4. MongoDB and mongoose

MongoDB – The Database
MongoDB is a NoSql Database that stores data in the form of documents and in these documents the data is written in KEY - Value pairs .
Unlike SQL databases (tables, rows, columns), MongoDB uses:
Database → container of collections
Collection → container of documents (like a table)
Document → actual data stored as JSON-like objects
{ "_id": "64ef9fabc123", // unique key "name": "Ayush", "age": 22, "skills": ["Node.js", "React", "MongoDB"] }
Mongoose - ODM(Object data modelling)
Mongoose is a Node.js library that provides a schema-based solution for MongoDB.
Think of it as a bridge between your Node.js code and MongoDB.
Mongoose WorkFlow
Connect To MongoDB
const mongoose = require('mongoose'); require('dotenv').config(); const dbConnect = ()=>{ mongoose.connect(process.env.DATABASE_URL) .then(()=>{console.log("DB CONNECTION SUCESSFULL")}) .catch((err)=>{ console.log("Failed to connect DB") console.log(err); process.exit(1); }) } module.exports = dbConnect;
Define Schema
const userSchema = new mongoose.Schema({ name: { type: String, required: true }, age: Number, skills: [String], createdAt: { type: Date, default: Date.now } });
Create Model
const User = mongoose.model('User', userSchema);// "Users" will be the collection in DB
CRUD operations
Create(POST Data)
// Assuming Schema + Model already defined const User = mongoose.model("User", userSchema); // ---------------- CREATE ---------------- // Save a new user const newUser = await User.create({ name:"Ayush", age:5, skills:["java","Py"] }) // Saves into DB also use save method
Read(GET Data)
// ---------------- READ ---------------- // 1. find() const allUsers = await User.find({}); // ✅ Returns an array of all the documents(USers) // Use when you expect multiple documents const getUsersWhoseAgeisFive = await User.find({age:5}) // if we use findOne here then it give first matching document const getSelectedFields = await User.find().select('name email -_id') // it give all documenst having only name and email and not include _id const getLimitedUser = await User.find().limit(5).skip(1) // this give only 5 Users exxcept first user -> used for pagination const sortedUser = await User.find().sort({age:1}) // return/find user in acseding order of thier age . if you pass -1 then you get the user in decending order // 2. findOne() const oneUser = await User.findOne({ name: "Ayush" }); // ✅ Returns the first matching document (or null if none) // Use when you need just ONE document // 3. findById() const userById = await User.findById(newUser._id); //newUser._id // ✅ Finds a document by _id directly // Faster than findOne({ _id: ... }) // 4. findByIdAndUpdate() const updatedUser = await User.findByIdAndUpdate( newUser._id, { $set: { age: 23 } }, { new: true } // return the updated document instead of old one ); // ✅ Finds document by _id and updates it in one step // 5. findByIdAndDelete() await User.findByIdAndDelete(newUser._id); // ✅ Deletes document directly using _id // 6. findByIdAndRemove() await User.findByIdAndRemove("64ef9fabc123"); // ❌ Deprecated (use findByIdAndDelete instead)
Update
// ---------------- UPDATE ---------------- // 7. updateOne() await User.updateOne({ name: "Ayush" }, { $set: { age: 25 } }); // ✅ Updates the FIRST matching document // 8. updateMany() await User.updateMany({ age: { $lt: 18 } }, { $set: { isMinor: true } }); // ✅ Updates ALL matching documents // 9. replaceOne() await User.replaceOne({ name: "Ayush" }, { name: "Raj", age: 30 }); // ✅ Replaces entire document (removes old fields not mentioned)
Delete
// 10. deleteOne() await User.deleteOne({ name: "Ayush" }); // ✅ Deletes the first matching document // 11. deleteMany() await User.deleteMany({ age: { $gt: 60 } }); // ✅ Deletes all matching documents
Other queries
// ---------------- EXTRA QUERY HELPERS ---------------- // 12. countDocuments() const count = await User.countDocuments({ age: { $gte: 18 } }); // ✅ Count matching documents (faster than .find().length) // 13. distinct() const uniqueSkills = await User.distinct("skills"); // ✅ Returns unique values for a given field // 14. exists() const exists = await User.exists({ name: "Ayush" }); // ✅ Returns _id if document exists, null if not // 15. sort() const sorted = await User.find().sort({ age: -1 }); // ✅ Sort results (1 = asc, -1 = desc) // 16. limit() const limited = await User.find().limit(5); // ✅ Limit number of documents returned // 17. skip() const skipped = await User.find().skip(5).limit(5); // ✅ Pagination (skip first 5, then get next 5) // 18. select() const selectedFields = await User.find().select("name age"); // ✅ Return only specific fields (projection) // 19. aggregate() const aggregation = await User.aggregate([ { $match: { age: { $gte: 18 } } }, { $group: { _id: null, avgAge: { $avg: "$age" } } } ]); // ✅ Powerful data aggregation pipeline // 20. populate() // Example: if a post has author ref const posts = await Post.find().populate("author"); // ✅ Fetches related document (like JOIN in SQL) })();
Advance mongoose features
Middleware/Hooks → run before/after operations (
pre
,post
).Virtuals → computed fields not stored in DB.
Population → like SQL joins (
ref
another model).Indexes → schema-level indexing for performance.
Transactions → multi-document atomic operations.
const postSchema = new mongoose.Schema({ title: String, author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' } }); const Post = mongoose.model('Post', postSchema); const post = await Post.find().populate('author');
Subscribe to my newsletter
Read articles from Ayush Rajput directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
