Mongoose is a MongoDB object modeling library for Node.js. It provides a straightforward way to interact with MongoDB by using schemas and models
Schemas and Models
Example:
import mongoose ,{Schema} from "mongoose"
const userSchema= new Schema({
username:{
type:String,
required:true,
unique:true,
lowercase:true,
trim:true,
index:true
},
email:{
type:String,
required:true,
unique:true,
lowercase:true,
trim:true
}
},{timestamps:true})
Middleware (Hooks)
Example:
userSchema.pre('save', function(next) {
// Perform something before saving
console.log('Before saving...');
next();
});
userSchema.pre("save",async function(next){
if(!this.isModified("password")) return next();
this.password =await bcrypt.hash(this.password,10)
next()
})
Queries
Example:
User.find({ age: { $gte: 18 } })
Relationships Between Data
Example (One-to-many relationship):
const videoSchema= new Schema(
{
owner:{
type:Schema.Types.ObjectId,
ref:"User"
}
},{
timestamps:true
}
)
Plugins
import mongoose,{Schema} from "mongoose"
import aggregatePaginate from "mongoose-aggregate-paginate-v2"
const videoSchema= new Schema(
)
videoSchema.plugin(aggregatePaginate);
export const Video=mongoose.model("Video",videoSchema)
aggregatePaginate
WorksNormally, with MongoDB, when you use an aggregation pipeline, you might retrieve a large number of documents. However, fetching all of them at once can be inefficient or slow. Pagination helps break the results into smaller chunks, loading only a subset of the data at a time (e.g., 10 items per page).
With aggregatePaginate
, you can run an aggregation query and then paginate through the results without manually managing the skip/limit logic
**User Model**
import mongoose ,{Schema} from "mongoose"
import bcrypt from "bcrypt"
import jwt from "jsonwebtoken"
const userSchema= new Schema({
username:{
type:String,
required:true,
unique:true,
lowercase:true,
trim:true,
index:true
},
email:{
type:String,
required:true,
unique:true,
lowercase:true,
trim:true
},
fullName:{
type:String,
required:true,
trim:true,
index:true
},
avatar:{
type:String,///cloudinary url
required:true,
},
coverImage:{
type:String,///cloudinary url
},
watchHistory:{
type:Schema.Types.ObjectId,
ref:"video"
},
password:{
type:string,
required:[true,"Password is reuired"]
},
refreshToken:{
type:String
}
},{timestamps:true})
///////This line registers a middleware function to be executed before the "save"
///operation on a document of the specified schema (userSchema).
//async function(next) { ... }: This is the middleware function itself,
/// which takes a callback function next as its argument.
///The next function is used to proceed to the next middleware in the stack
///////If it hasn't been modified (i.e., it's not a new password or an updated password),
/// the function exits early by calling next() to proceed to the next middleware.
userSchema.pre("save",async function(next){
if(!this.isModified("password")) return next();
this.password =await bcrypt.hash(this.password,10)
next()
})
userSchema.methods.isPasswordCorrect= async function(password){
return await bcrypt.compare(password,this.password)
}
userSchema.methods.generateAccessToken=function(){
return jwt.sign({
_id:this._id,
email:this.email,
username:this.username,
fullName:this.fullName
}),
process.env.ACCESS_TOKEN_SECRET,
{
expiresIn:process.env.ACCESS_TOKEN_EXPIRY
}
}
userSchema.methods.generateRefreshToken=function(){
return jwt.sign({
_id:this._id,
email:this.email,
username:this.username,
fullName:this.fullName
}),
process.env.REFRESH_TOKEN_SECRET,
{
expiresIn:process.env.REFRESH_TOKEN_EXPIRY
}
}
export const User=mongoose.model("User",userSchema)