iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Node.js Driver

MongoDB Node driver: connection options, CRUD, aggregation, transactions, and the production patterns.

MongoDB — Node driver

EXAMPLE
// Install: npm install mongodb
import { MongoClient, ObjectId } from 'mongodb';

// ===== Connect =====
const client = new MongoClient(process.env.MONGO_URI, {
  maxPoolSize: 50,
  minPoolSize: 5,
  serverSelectionTimeoutMS: 5000,
  retryWrites: true,
  retryReads: true,
  appName: 'shop',
});
await client.connect();
const db = client.db('shop');
const users = db.collection('users');

// ===== Insert =====
const result = await users.insertOne({ email: 'a@x.io', name: 'Alex' });
console.log(result.insertedId);

await users.insertMany([{ email: 'b@x.io' }, { email: 'c@x.io' }]);

// ===== Find =====
const u = await users.findOne({ _id: new ObjectId(id) });

const cursor = users.find({ active: true })
  .sort({ created_at: -1 })
  .skip(0)
  .limit(20)
  .project({ password: 0 });

const list = await cursor.toArray();

// Cursor iteration (large results):
for await (const doc of users.find({ active: true })) {
  // process one doc at a time
}

// ===== Update =====
await users.updateOne(
  { _id: new ObjectId(id) },
  { $set: { name: 'Sam' }, $inc: { logins: 1 } },
  { upsert: true }
);

const result2 = await users.updateMany(
  { country: 'AU' },
  { $set: { region: 'APAC' } }
);
console.log(result2.modifiedCount);

// ===== Delete =====
await users.deleteOne({ _id: new ObjectId(id) });
await users.deleteMany({ created_at: { $lt: cutoff } });

// ===== Aggregation =====
const stats = await db.collection('orders').aggregate([
  { $match: { status: 'paid' } },
  { $group: { _id: '$customer_id', total: { $sum: '$amount' } } },
  { $sort: { total: -1 } },
  { $limit: 10 },
]).toArray();

// ===== Indexes =====
await users.createIndex({ email: 1 }, { unique: true });
await users.createIndexes([
  { key: { country: 1, region: 1 } },
  { key: { created_at: -1 } },
]);

const indexes = await users.indexes();

// ===== Transactions =====
const session = client.startSession();
try {
  await session.withTransaction(async () => {
    await accounts.updateOne({ _id: from }, { $inc: { balance: -50 } }, { session });
    await accounts.updateOne({ _id: to },   { $inc: { balance:  50 } }, { session });
  });
} finally {
  await session.endSession();
}

// ===== Bulk operations =====
const bulk = users.initializeUnorderedBulkOp();
for (const u of inserts) bulk.insert(u);
for (const u of updates) bulk.find({ _id: u._id }).update({ $set: u });
await bulk.execute();

// ===== Lifecycle =====
process.on('SIGTERM', async () => {
  await client.close();
  process.exit(0);
});

// ===== Patterns =====
// - One client per process; reuse across requests
// - Use cursors for large result sets; do not toArray() millions of docs
// - Set appName for ops + slow query attribution
// - Bulk ops for write-heavy workflows
// - Replica set + transactions only when needed

// ===== Pitfalls =====
// - Connecting per request (slow + connection leak)
// - Missing indexes -> COLLSCAN
// - Forgetting projection -> shipping every field including secrets
// - Transactions on standalone server -> error (replica set required)

Why it matters

The official Node driver is fast + minimal. Connect once, reuse, project explicitly, paginate via cursor, index for queries, bulk for writes, transactions only when needed. Add appName + retry settings for production observability.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
import { MongoClient } from 'mongodb';
const client = new MongoClient(uri);
await client.connect();
const db = client.db('shop');
Try it Yourself »

Discussion

Loading…