MongoDB is the most widely used NoSQL database in the Node.js ecosystem, storing flexible, JSON-like documents. This lesson covers connecting and querying MongoDB using the official mongodb driver.
Connecting to MongoDB
MongoDB stores data as "documents", JSON-like objects, grouped into "collections" (roughly analogous to tables in SQL). The official mongodb npm package provides a MongoClient for connecting and a query API that closely mirrors MongoDB's native query language.
Unlike SQL, MongoDB documents in the same collection don't need identical fields, which makes it a natural fit for rapidly evolving or naturally nested data, at the cost of the database itself enforcing less structure than a relational schema would.
import { MongoClient } from 'mongodb';
const client = new MongoClient(process.env.MONGODB_URI);
await client.connect();
const db = client.db('shop');
const products = db.collection('products');
const result = await products.insertOne({ name: 'Keyboard', price: 49.99 });
console.log('Inserted with id:', result.insertedId);
client.db(name) selects a database, and .collection(name) selects a collection within it, both are lightweight handles, not new connections.
insertOne()/insertMany() add new documents to a collection.
find() returns a cursor, call .toArray() to materialize it into an array of documents.
updateOne() requires an update operator like $set, you can't just pass the new fields directly.
Filters use plain objects matching field values, e.g. { name: 'Keyboard' }.
MongoDB Driver Cheatsheet
The operations you'll use in almost every MongoDB-backed Node.js app.
Task
Code
Insert one
collection.insertOne(doc)
Find all
collection.find({}).toArray()
Find with filter
collection.find({ price: { $gt: 20 } }).toArray()
Find one
collection.findOne({ _id: id })
Update fields
collection.updateOne(filter, { $set: fields })
Delete one
collection.deleteOne(filter)
Working With ObjectId
MongoDB automatically assigns each document a unique _id field of type ObjectId, not a plain string. When accepting an ID from a URL parameter (a string), you must convert it to an ObjectId before using it in a filter, or the query will silently match nothing.
Wrap the ObjectId conversion in a try/catch, an invalid ID format throws an error rather than simply returning no match.
Querying With MongoDB Operators
MongoDB's query language uses special $-prefixed operators for comparisons and logic beyond simple equality, letting you express ranges, inclusion checks, and combined conditions directly in a filter object.
Passing a raw string ID from a URL parameter directly into a filter instead of converting it to an ObjectId.
Calling updateOne() with plain fields instead of wrapping them in $set, which replaces the entire document unexpectedly.
Forgetting .toArray() after find(), and trying to use the cursor as if it were already an array.
Not closing or reusing the MongoClient connection properly, opening a new one per request.
Key Takeaways
MongoDB stores flexible, JSON-like documents grouped into collections.
The mongodb driver's API (insertOne, find, updateOne, deleteOne) closely mirrors MongoDB's native query language.
_id fields are ObjectId instances and must be explicitly converted from string IDs.
Update operations require operators like $set, plain field objects won't work as expected.
Pro Tip
Create a single shared MongoClient instance when your app starts and reuse it for the life of the process, the driver manages its own internal connection pool, so you don't need (or want) to create a new client per request.
You now know the official MongoDB driver. Next, learn Mongoose, the most popular ODM for adding schemas and validation on top of MongoDB.