MongoDB and Node.js Integration Guide
MongoDB and Node.js Integration Guide
1. SQL vs NoSQL
2. MongoDB Essentials
3. Connecting [Link] to MongoDB
4. Full CRUD Operations
5. Edge Cases & Best Practices
1. SQL vs NoSQL
Tables vs Documents
┌─────────────┬──────────┬─────────┐
│ user_id │ name │ email │
├─────────────┼──────────┼─────────┤
│ 1 │ John │ j@[Link] │
│ 2 │ Jane │ j@[Link] │
└─────────────┴──────────┴─────────┘
{
"_id": "507f1f77bcf86cd799439011",
"name": "John",
"email": "j@[Link]",
"age": 30,
"address": {
"city": "Kathmandu",
"country": "Nepal"
}
}
Real-world examples:
Industry Examples
2. MongoDB Essentials
Core Concepts
Database
Collection
Document
Basic Operations
// Drop a collection
[Link]()
CREATE (Insert)
READ (Find)
// Find all documents
[Link]()
// Limit results
[Link]().limit(5)
// Sort results
[Link]().sort({ age: 1 }) // ascending
[Link]().sort({ age: -1 }) // descending
// Count documents
[Link]({ isActive: true })
UPDATE
// Update one document
[Link](
{ name: "John Doe" }, // filter
{ $set: { age: 31 } } // update operation
)
// Update operators
[Link](
{ name: "John Doe" },
{
$set: { age: 31 }, // set field
$inc: { loginCount: 1 }, // increment
$push: { tags: "premium" }, // add to array
$unset: { oldField: "" } // remove field
}
)
DELETE
// Logical Operators
[Link]({ $and: [{ age: { $gt: 25 } }, { isActive: true }] })
[Link]({ $or: [{ age: { $gt: 30 } }, { isActive: false }] })
[Link]({ $not: { age: { $gt: 25 } } })
// Array Operators
[Link]({ tags: "premium" }) // array contains
[Link]({ tags: { $all: ["premium", "vip"] } }) // contains all
[Link]({ tags: { $size: 3 } }) // array size
Installation
# Or with yarn
yarn add mongoose
What is Mongoose?
Mongoose is an ODM (Object Document Mapper) for MongoDB and [Link]. It provides:
Schema definition
Data validation
Middleware hooks
Easy query building
Type casting
Create src/config/[Link] :
[Link] = connectDB;
Update [Link] :
const app = require('./src/app');
const connectDB = require('./src/config/database');
Schema = Blueprint for documents (defines structure) Model = Constructor function that creates documents
Create src/models/[Link] :
const mongoose = require('mongoose');
// Define Schema
const userSchema = new [Link]({
name: {
type: String,
required: [true, 'Name is required'], // Custom error message
trim: true, // Remove whitespace
minlength: [2, 'Name must be at least 2 characters'],
maxlength: [50, 'Name cannot exceed 50 characters']
},
email: {
type: String,
required: [true, 'Email is required'],
unique: true, // Ensures email is unique
lowercase: true, // Convert to lowercase
match: [/^\S+@\S+\.\S+$/, 'Please provide a valid email'] // Email validation
},
age: {
type: Number,
min: [0, 'Age cannot be negative'],
max: [120, 'Age cannot exceed 120']
},
isActive: {
type: Boolean,
default: true // Default value
},
role: {
type: String,
enum: ['user', 'admin', 'moderator'], // Only these values allowed
default: 'user'
},
tags: [String], // Array of strings
address: {
city: String,
country: String
},
createdAt: {
type: Date,
default: [Link] // Automatically set when document is created
},
updatedAt: {
type: Date,
default: [Link]
}
}, {
timestamps: true // Automatically adds createdAt and updatedAt
});
// Create Model
const User = [Link]('User', userSchema);
[Link] = User;
Schema Types:
Install dotenv:
Update [Link] :
Project Structure
randomizer/
├── src/
│ ├── config/
│ │ └── [Link] (Database connection)
│ ├── models/
│ │ └── [Link] (User schema/model)
│ ├── controllers/
│ │ └── [Link] (Business logic)
│ ├── routes/
│ │ └── [Link] (API routes)
│ ├── middleware/
│ │ └── [Link] (Error handling)
│ └── [Link] (Express app setup)
├── [Link] (Start server)
└── [Link]
File: src/models/[Link]
[Link] = User;
File: src/routes/[Link]
// Define routes
[Link]('/', createUser); // Create user
[Link]('/', getUsers); // Get all users
[Link]('/:id', getUserById); // Get one user
[Link]('/:id', updateUser); // Update user
[Link]('/:id/renew', renewUser); // Renew validity
[Link]('/:id', deleteUser); // Delete user
[Link] = router;
File: src/controllers/[Link]
How to test:
POST [Link]
Content-Type: application/json
{
"unique_id": "USER001",
"name": "John Doe",
"email": "john@[Link]",
"contact": "1234567890",
"membership_fee": 1000,
"validity": 12
}
What happens:
// Send response
[Link](200).json({
success: true,
count: [Link],
data: users
});
} catch (error) {
next(error);
}
};
How to test:
GET [Link]
What happens:
// Find user by ID
const user = await [Link](id).select('-__v');
// Send response
[Link](200).json({
success: true,
data: user
});
} catch (error) {
next(error);
}
};
How to test:
GET [Link]
What happens:
// Validate ID format
if () {
return [Link](400).json({
success: false,
message: 'Invalid user ID format'
});
}
// Send response
[Link](200).json({
success: true,
message: 'User updated successfully',
data: user
});
} catch (error) {
// Handle duplicate email
if ([Link] === 11000) {
return [Link](409).json({
success: false,
message: 'Email already exists'
});
}
next(error);
}
};
How to test:
PUT [Link]
Content-Type: application/json
{
"name": "John Updated",
"email": "[Link]@[Link]",
"contact": "9876543210"
}
What happens:
1. Validates the ID
2. Builds an update object from provided fields
3. Updates the user in the database
4. Returns the updated user
5. Handles errors (duplicate email, validation)
// Validate ID format
if () {
return [Link](400).json({
success: false,
message: 'Invalid user ID format'
});
}
// Increment validity by 1
// $inc is MongoDB operator to increment a number
const user = await [Link](
id,
{ $inc: { validity: 1 } }, // Add 1 to validity
{ new: true, runValidators: true }
).select('-__v');
// Send response
[Link](200).json({
success: true,
message: 'Validity renewed successfully',
data: user
});
} catch (error) {
next(error);
}
};
How to test:
PUT [Link]
What happens:
1. Validates the ID
2. Increments validity by 1
3. Returns the updated user
// Validate ID format
if () {
return [Link](400).json({
success: false,
message: 'Invalid user ID format'
});
}
// Send response
[Link](200).json({
success: true,
message: 'User deleted successfully',
data: user
});
} catch (error) {
next(error);
}
};
How to test:
DELETE [Link]
What happens:
1. Validates the ID
2. Deletes the user from the database
3. Returns the deleted user data
4. Returns 404 if the user doesn't exist
[Link](201).json({
success: true,
message: 'User created successfully',
data: user
});
} catch (error) {
if ([Link] === 11000) {
const field = [Link]([Link])[0];
return [Link](409).json({
success: false,
message: `${field} already exists`
});
}
if ([Link] === 'ValidationError') {
const errors = [Link]([Link]).map(err => [Link]);
return [Link](400).json({
success: false,
message: [Link](', ')
});
}
next(error);
}
};
if () {
return [Link](400).json({
success: false,
message: 'Invalid user ID format'
});
}
const user = await [Link](id).select('-__v');
if (!user) {
return [Link](404).json({
success: false,
message: 'User not found'
});
}
[Link](200).json({
success: true,
data: user
});
} catch (error) {
next(error);
}
};
if () {
return [Link](400).json({
success: false,
message: 'Invalid user ID format'
});
}
if ([Link](updateData).length === 0) {
return [Link](400).json({
success: false,
message: 'Please provide name, email, or contact to update'
});
}
if (!user) {
return [Link](404).json({
success: false,
message: 'User not found'
});
}
[Link](200).json({
success: true,
message: 'User updated successfully',
data: user
});
} catch (error) {
if ([Link] === 11000) {
return [Link](409).json({
success: false,
message: 'Email already exists'
});
}
if ([Link] === 'ValidationError') {
const errors = [Link]([Link]).map(err => [Link]);
return [Link](400).json({
success: false,
message: [Link](', ')
});
}
next(error);
}
};
if () {
return [Link](400).json({
success: false,
message: 'Invalid user ID format'
});
}
if (!user) {
return [Link](404).json({
success: false,
message: 'User not found'
});
}
[Link](200).json({
success: true,
message: 'Validity renewed successfully',
data: user
});
} catch (error) {
next(error);
}
};
if () {
return [Link](400).json({
success: false,
message: 'Invalid user ID format'
});
}
if (!user) {
return [Link](404).json({
success: false,
success: false,
message: 'User not found'
});
}
[Link](200).json({
success: true,
message: 'User deleted successfully',
data: user
});
} catch (error) {
next(error);
}
};
File: src/[Link]
// Root endpoint
[Link]('/', (req, res) => {
[Link]({
message: 'Welcome to Randomizer API',
endpoints: {
'POST /api/users': 'Create a new user',
'GET /api/users': 'Get all users',
'GET /api/users/:id': 'Get user by ID',
'PUT /api/users/:id': 'Update user (name, email, contact)',
'PUT /api/users/:id/renew': 'Renew user validity (increment by 1)',
'DELETE /api/users/:id': 'Delete user'
}
});
});
// User routes
[Link]('/api/users', userRoutes);
[Link] = app;
Step 6: Create Error Handler
File: src/middleware/[Link]
// Validation error
if ([Link] === 'ValidationError') {
return [Link](400).json({
success: false,
message: 'Validation error',
error: [Link]
});
}
// Duplicate entry
if ([Link] === 11000) {
return [Link](409).json({
success: false,
message: 'Duplicate entry - this value already exists'
});
}
// Invalid ID
if ([Link] === 'CastError') {
return [Link](400).json({
success: false,
message: 'Invalid ID format'
});
}
// Default error
[Link](500).json({
success: false,
message: 'Something went wrong!',
error: [Link]
});
};
[Link] = errorHandler;
File: [Link]
1. Create a user:
curl [Link]
curl [Link]
4. Update user:
curl -X PUT [Link] \
-H "Content-Type: application/json" \
-d '{
"name": "John Updated",
"email": "[Link]@[Link]"
}'
5. Renew validity:
6. Delete user:
Summary
Key points: