Table of Contents
- Introduction
- What is CRUD?
- Setting Up the Project
- Connecting to MongoDB
- Create Operation (
insertOne
,insertMany
) - Read Operation (
findOne
,find
) - Update Operation (
updateOne
,updateMany
) - Delete Operation (
deleteOne
,deleteMany
) - Error Handling & Validation
- Organizing Code Structure
- Best Practices
- Conclusion
1. Introduction
MongoDB and Node.js are often paired together in modern web development due to their asynchronous capabilities and JSON-friendly nature. In this module, we’ll explore how to implement CRUD operations (Create, Read, Update, Delete) using the official MongoDB Node.js driver, not an ODM like Mongoose, giving you full control and transparency.
2. What is CRUD?
CRUD is an acronym for the four basic types of database operations:
- Create – Add new data
- Read – Retrieve data
- Update – Modify existing data
- Delete – Remove data
Each of these maps directly to methods provided by the MongoDB Node.js driver.
3. Setting Up the Project
Initialize Project
bashCopyEditmkdir mongodb-crud-node
cd mongodb-crud-node
npm init -y
npm install mongodb dotenv
Setup .env
File
envCopyEditMONGO_URI=mongodb://127.0.0.1:27017
DB_NAME=crud_demo
Folder Structure
bashCopyEdit.
├── .env
├── db.js
├── crud.js
└── index.js
4. Connecting to MongoDB
db.js
jsCopyEditconst { MongoClient } = require('mongodb');
require('dotenv').config();
const client = new MongoClient(process.env.MONGO_URI);
let db;
async function connectDB() {
if (!db) {
await client.connect();
db = client.db(process.env.DB_NAME);
console.log('Connected to MongoDB');
}
return db;
}
module.exports = connectDB;
5. Create Operation
insertOne
jsCopyEditconst db = await connectDB();
const users = db.collection('users');
await users.insertOne({
name: 'John Doe',
email: '[email protected]',
age: 30
});
insertMany
jsCopyEditawait users.insertMany([
{ name: 'Jane Doe', age: 25 },
{ name: 'Alice', age: 22 }
]);
6. Read Operation
findOne
jsCopyEditconst user = await users.findOne({ name: 'John Doe' });
console.log(user);
find + toArray
jsCopyEditconst userList = await users.find({ age: { $gt: 20 } }).toArray();
console.log(userList);
Add filters, projection, and sorting:
jsCopyEditconst usersSorted = await users.find({}, { projection: { name: 1, _id: 0 } }).sort({ age: -1 }).toArray();
7. Update Operation
updateOne
jsCopyEditawait users.updateOne(
{ name: 'John Doe' },
{ $set: { age: 31 } }
);
updateMany
jsCopyEditawait users.updateMany(
{ age: { $lt: 30 } },
{ $inc: { age: 1 } }
);
8. Delete Operation
deleteOne
jsCopyEditawait users.deleteOne({ name: 'John Doe' });
deleteMany
jsCopyEditawait users.deleteMany({ age: { $gt: 25 } });
9. Error Handling & Validation
Wrap each database interaction in try-catch
to gracefully handle errors:
jsCopyEdittry {
const user = await users.insertOne({ name: 'Test' });
} catch (err) {
console.error('MongoDB Error:', err.message);
}
Use validation logic before making DB calls:
jsCopyEditif (!email.includes('@')) throw new Error('Invalid email address');
You can also enforce schema validation using MongoDB 4.0+ features on the collection level.
10. Organizing Code Structure
To make your CRUD application production-ready:
Structure like:
bashCopyEdit/db
└── connect.js
/controllers
└── userController.js
/routes
└── userRoutes.js
index.js
Move each CRUD function to its own module in /controllers
for clean separation.
11. Best Practices
- Always close the connection in shutdown hooks.
- Avoid hardcoded values – use environment variables.
- Sanitize and validate user input.
- Use appropriate indexes for frequent queries.
- Prefer
insertMany
,updateMany
, etc., for batch operations. - Keep the logic reusable by abstracting functions into services.
- Use proper logging (e.g., Winston, Pino) in production.
- Set a default limit on
find()
queries to avoid memory overload.
12. Conclusion
Implementing CRUD with the official MongoDB Node.js driver gives you low-level control over your database interactions. While tools like Mongoose abstract a lot, using the native driver teaches you how MongoDB works under the hood — a crucial skill for optimization, performance tuning, and working in microservices environments.