MongoDB driver examples
Recipes for common tasks against the Nimbus MongoDB endpoint, using stock MongoDB drivers. Each section is independent — jump to the task you need. If you haven’t connected a driver yet, start with the tutorial.
All examples assume a Nimbus server with the MongoDB endpoint enabled on
127.0.0.1:27017 and SCRAM-SHA-256 credentials app-user / app-secret,
as set up in the tutorial.
Build a connection string
Section titled “Build a connection string”The shape Nimbus expects:
mongodb://<username>:<password>@<host>:<port>/<database>?directConnection=true- Credentials are your server’s configured SCRAM-SHA-256 username and password, URL-encoded if they contain special characters.
- The database name selects the Nimbus tenant.
If you omit it, you land in the tenant
default. directConnection=trueis required — Nimbus is a single endpoint, and without it the driver attempts replica-set discovery and times out.
If your project uses the Nimbus CLI, the @nimbus/mongodb helper package
builds the string for you. Provision it into your project:
nimbus packages provision mongodbThen:
import { mongoUri } from "@nimbus/mongodb";
const uri = mongoUri({ username: "app-user", password: "app-secret", database: "myapp",});// mongodb://app-user:app-secret@127.0.0.1:27017/myapp?directConnection=truemongoUri() defaults to 127.0.0.1, port 27017, and database default,
URL-encodes the credentials, and always appends directConnection=true.
Basic CRUD
Section titled “Basic CRUD”import { MongoClient } from "mongodb";
const client = new MongoClient( "mongodb://app-user:app-secret@127.0.0.1:27017/myapp?directConnection=true",);await client.connect();const tasks = client.db("myapp").collection("tasks");
// Createawait tasks.insertOne({ title: "Write docs", done: false, priority: 2 });await tasks.insertMany([ { title: "Review PR", done: false, priority: 1 }, { title: "Ship release", done: true, priority: 3 },]);
// Read — implicit equality and comparison operatorsconst open = await tasks.find({ done: false }).toArray();const urgent = await tasks.find({ priority: { $lte: 2 } }).toArray();
// Updateawait tasks.updateOne({ title: "Write docs" }, { $set: { done: true } });await tasks.updateMany({ done: true }, { $inc: { priority: -1 } });
// Deleteawait tasks.deleteOne({ title: "Ship release" });
await client.close();Filters support implicit equality plus $eq, $ne, $gt, $gte, $lt,
and $lte. Other filter operators ($in, $or, $regex, $exists, …)
are rejected with a BadValue error — see
supported operations for the full surface.
Upserts and findAndModify
Section titled “Upserts and findAndModify”// Insert-or-update keyed on a fieldawait tasks.updateOne( { title: "Triage inbox" }, { $set: { done: false }, $setOnInsert: { priority: 5 } }, { upsert: true },);
// Atomically claim a task and get the updated document backconst claimed = await tasks.findOneAndUpdate( { done: false }, { $set: { owner: "ada" } }, { returnDocument: "after" },);Count and distinct
Section titled “Count and distinct”const openCount = await tasks.countDocuments({ done: false });const owners = await tasks.distinct("owner");Aggregate
Section titled “Aggregate”The pipeline stages $match, $sort, $limit, $skip, $project,
$addFields, $count, $group, and $unwind are supported:
const byOwner = await tasks .aggregate([ { $match: { done: false } }, { $group: { _id: "$owner", open: { $sum: 1 } } }, { $sort: { open: -1 } }, ]) .toArray();Unsupported stages are rejected with an error naming the stage, so a pipeline never silently degrades.
Use transactions
Section titled “Use transactions”Multi-document transactions work through standard driver sessions. Writes
inside the transaction are isolated until commit; if a concurrent write
conflicts, the commit fails with a WriteConflict error and your
application decides whether to retry:
const session = client.startSession();try { await session.withTransaction(async () => { const db = client.db("myapp"); await db.collection("accounts").updateOne( { name: "checking" }, { $inc: { balance: -100 } }, { session }, ); await db.collection("accounts").updateOne( { name: "savings" }, { $inc: { balance: 100 } }, { session }, ); });} finally { await session.endSession();}A transaction stays within one database — one Nimbus tenant. Start separate transactions for separate tenants.
Connect from Python
Section titled “Connect from Python”The same connection string works with pymongo:
from pymongo import MongoClient
client = MongoClient( "mongodb://app-user:app-secret@127.0.0.1:27017/myapp?directConnection=true")tasks = client["myapp"]["tasks"]
tasks.insert_one({"title": "Write docs", "done": False})for doc in tasks.find({"done": False}): print(doc)Connect from Go
Section titled “Connect from Go”With the official Go driver:
package main
import ( "context" "fmt"
"go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options")
func main() { uri := "mongodb://app-user:app-secret@127.0.0.1:27017/myapp?directConnection=true" client, err := mongo.Connect(options.Client().ApplyURI(uri)) if err != nil { panic(err) } defer client.Disconnect(context.Background())
tasks := client.Database("myapp").Collection("tasks") if _, err := tasks.InsertOne(context.Background(), bson.M{"title": "Write docs", "done": false}); err != nil { panic(err) }
cur, err := tasks.Find(context.Background(), bson.M{"done": false}) if err != nil { panic(err) } var results []bson.M if err := cur.All(context.Background(), &results); err != nil { panic(err) } fmt.Println(results)}Work with multiple tenants
Section titled “Work with multiple tenants”Each database name is its own isolated Nimbus tenant. One client can address several:
const acme = client.db("acme").collection("orders");const globex = client.db("globex").collection("orders");
await acme.insertOne({ sku: "A-1" });// Invisible to globex — different tenant, different storage namespace.const none = await globex.find({ sku: "A-1" }).toArray(); // []Tenants are created automatically on first access. Database names must be
valid tenant IDs: ASCII letters, digits, _, and -, up to 128 characters.
Change streams are not supported
Section titled “Change streams are not supported”collection.watch() fails: the server rejects $changeStream pipelines
with a CommandNotSupported error rather than emulating a partial feature.
Poll with find where you need to observe changes through the MongoDB
endpoint.
Related pages
Section titled “Related pages”- Supported operations — the exact command, filter, update, and aggregation surface.
- Supported drivers — driver and tool compatibility.
- Tenant isolation — how database names map to tenants.