![mungo](https://raw.githubusercontent.com/massivefermion/mungo/main/banner.png)
[![Package Version](https://img.shields.io/hexpm/v/mungo)](https://hex.pm/packages/mungo)
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/mungo/)
# mungo (formerly gleam_mongo)
> mungo: a felted fabric made from the shredded fibre of repurposed woollen cloth
---
A mongodb driver for gleam
## <img width=32 src=https://raw.githubusercontent.com/massivefermion/mungo/main/icon.png> Quick start
```sh
gleam shell # Run an Erlang shell
```
## <img width=32 src=https://raw.githubusercontent.com/massivefermion/mungo/main/icon.png> Installation
```sh
gleam add mungo
```
## <img width=32 src=https://raw.githubusercontent.com/massivefermion/mungo/main/icon.png> Roadmap
- [x] support basic mongodb commands
- [x] support aggregation
- [x] support connection strings
- [x] support authentication
- [x] support mongodb cursors
- [ ] support connection pooling
- The plan is to use [puddle](https://github.com/massivefermion/puddle), but there are still unresolved issues with that package!
- [ ] support bulk operations
- [ ] support clusters
- [ ] support tls
- [ ] support transactions
- [ ] support change streams
- [ ] support other mongodb commands
## <img width=32 src=https://raw.githubusercontent.com/massivefermion/mungo/main/icon.png> Usage
```gleam
import gleam/option
import mungo
import mungo/crud.{Sort, Upsert}
import mungo/aggregation.{
Let, add_fields, aggregate, match, pipelined_lookup, to_cursor, unwind,
}
import bison/bson
pub fn main() {
let assert Ok(client) =
mungo.start(
"mongodb://app-dev:passwd@localhost/app-db?authSource=admin",
512,
)
let users =
client
|> mungo.collection("users")
let _ =
users
|> mungo.insert_many(
[
[
#("username", bson.String("jmorrow")),
#("name", bson.String("vincent freeman")),
#("email", bson.String("jmorrow@gattaca.eu")),
#("age", bson.Int32(32)),
],
[
#("username", bson.String("real-jerome")),
#("name", bson.String("jerome eugene morrow")),
#("email", bson.String("real-jerome@running.at")),
#("age", bson.Int32(32)),
],
],
128,
)
let _ =
users
|> mungo.update_one(
[#("username", bson.String("real-jerome"))],
[
#(
"$set",
bson.Document([
#("username", bson.String("eugene")),
#("email", bson.String("eugene@running.at ")),
]),
),
],
[Upsert],
128,
)
let assert Ok(yahoo_cursor) =
users
|> mungo.find_many(
[#("email", bson.Regex(#("yahoo", "")))],
[Sort([#("username", bson.Int32(-1))])],
128,
)
let _yahoo_users = mungo.to_list(yahoo_cursor, 128)
let assert Ok(underage_lindsey_cursor) =
users
|> aggregate([Let([#("minimum_age", bson.Int32(21))])], 128)
|> match([
#(
"$expr",
bson.Document([
#(
"$lt",
bson.Array([bson.String("$age"), bson.String("$$minimum_age")]),
),
]),
),
])
|> add_fields([
#(
"first_name",
bson.Document([
#(
"$arrayElemAt",
bson.Array([
bson.Document([
#(
"$split",
bson.Array([bson.String("$name"), bson.String(" ")]),
),
]),
bson.Int32(0),
]),
),
]),
),
])
|> match([#("first_name", bson.String("lindsey"))])
|> pipelined_lookup(
from: "profiles",
define: [#("user", bson.String("$username"))],
pipeline: [
[
#(
"$match",
bson.Document([
#(
"$expr",
bson.Document([
#(
"$eq",
bson.Array([bson.String("$username"), bson.String("$$user")]),
),
]),
),
]),
),
],
],
alias: "profile",
)
|> unwind("$profile", False)
|> to_cursor
let assert #(option.Some(_underage_lindsey), underage_lindsey_cursor) =
underage_lindsey_cursor
|> mungo.next(128)
let assert #(option.None, _) =
underage_lindsey_cursor
|> mungo.next(128)
}
```