Skip to content
This repository has been archived by the owner on Oct 30, 2023. It is now read-only.

spawnfest/mungo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

59 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mungo

Package Version Hex Docs

mungo

mungo: a felted fabric made from the shredded fibre of repurposed woollen cloth


A mongodb driver for gleam

Installation

gleam add mungo

SpawnFest 2023

As should already be clear, this is an already existing package. As far as SpawnFest 2023 is concerned, the goal is to be able to perform all of the already supported commands against a mongodb replica set as a first step for supporting more general mongodb cluster topologies.

I also think it's appropriate to explain my mongodb cluster setup to help other people replicate my results. I'll use a mongodb replica set created using podman and the latest official mongodb docker image.

The first step is to create a podman network:

podman network create replset-network

Then we need to create at least three nodes(port mappings are only for accessing the nodes from the host):

podman run -d -p 1024:27017 --name dante  --net replset-network mongo:latest --replSet spawnfest-replset
podman run -d -p 2048:27017 --name vergil --net replset-network mongo:latest --replSet spawnfest-replset
podman run -d -p 4096:27017 --name lady   --net replset-network mongo:latest --replSet spawnfest-replset

Finally you can use mongosh to connect to any of the nodes, initialize the replica set and add the other nodes:

mongosh --port 1024
> rs.initiate()
> rs.add('vergil')
> rs.add('lady')

Replica Set with authentication

If you want to test with a replica set that has authentication enabled, create the the replica set like below:

cd replset
./init.sh

The nodes will have spawn as username and fest as password. Finally you can use mongosh to connect to any of the nodes, initialize the replica set and add the other nodes:

mongosh --port 2048
> use admin
> db.auth('spawn', 'fest')
> rs.initiate()
> rs.add('dante')
> rs.add('lady')

Usage

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(db) =
    mungo.start(
      "mongodb://spawn:fest@localhost:1024,localhost:2048,localhost:4096/mungo?authSource=admin",
    )

  let users =
    db
    |> mungo.collection("users")

  let _ =
    users
    |> mungo.insert_many([
      [
        #("username", bson.Str("jmorrow")),
        #("name", bson.Str("vincent freeman")),
        #("email", bson.Str("[email protected]")),
        #("age", bson.Int32(32)),
      ],
      [
        #("username", bson.Str("real-jerome")),
        #("name", bson.Str("jerome eugene morrow")),
        #("email", bson.Str("[email protected]")),
        #("age", bson.Int32(32)),
      ],
    ])

  let _ =
    users
    |> mungo.update_one(
      [#("username", bson.Str("real-jerome"))],
      [
        #(
          "$set",
          bson.Document([
            #("username", bson.Str("eugene")),
            #("email", bson.Str("[email protected] ")),
          ]),
        ),
      ],
      [Upsert],
    )

  let assert Ok(yahoo_cursor) =
    users
    |> mungo.find_many(
      [#("email", bson.Regex(#("yahoo", "")))],
      [Sort([#("username", bson.Int32(-1))])],
    )
  let _yahoo_users = mungo.to_list(yahoo_cursor)

  let assert Ok(underage_lindsey_cursor) =
    users
    |> aggregate([Let([#("minimum_age", bson.Int32(21))])])
    |> match([
      #(
        "$expr",
        bson.Document([
          #("$lt", bson.Array([bson.Str("$age"), bson.Str("$$minimum_age")])),
        ]),
      ),
    ])
    |> add_fields([
      #(
        "first_name",
        bson.Document([
          #(
            "$arrayElemAt",
            bson.Array([
              bson.Document([
                #("$split", bson.Array([bson.Str("$name"), bson.Str(" ")])),
              ]),
              bson.Int32(0),
            ]),
          ),
        ]),
      ),
    ])
    |> match([#("first_name", bson.Str("lindsey"))])
    |> pipelined_lookup(
      from: "profiles",
      define: [#("user", bson.Str("$username"))],
      pipeline: [
        [
          #(
            "$match",
            bson.Document([
              #(
                "$expr",
                bson.Document([
                  #(
                    "$eq",
                    bson.Array([bson.Str("$username"), bson.Str("$$user")]),
                  ),
                ]),
              ),
            ]),
          ),
        ],
      ],
      alias: "profile",
    )
    |> unwind("$profile", False)
    |> to_cursor

  let assert #(option.Some(_underage_lindsey), underage_lindsey_cursor) =
    underage_lindsey_cursor
    |> mungo.next

  let assert #(option.None, _) =
    underage_lindsey_cursor
    |> mungo.next
}

About

No description or website provided.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages