以下是详细的 Mongoose 入门教程,包含代码示例和关键概念说明:
1. 环境准备
安装依赖
npm install mongoose
启动 MongoDB 服务
本地安装或使用 MongoDB Atlas 云服务
2. 基本连接
const mongoose = require('mongoose');// 基础连接
mongoose.connect('mongodb://localhost:27017/mydb').then(() => console.log('Connected to MongoDB')).catch(err => console.error('Connection failed:', err));// 带配置的连接
mongoose.connect('mongodb://localhost:27017/mydb', {useNewUrlParser: true,useUnifiedTopology: true,serverSelectionTimeoutMS: 5000
});
3. Schema 定义
基本字段类型
const userSchema = new mongoose.Schema({username: {type: String,required: true,minlength: 3,maxlength: 20},age: {type: Number,min: 18,max: 100},createdAt: {type: Date,default: Date.now},hobbies: [String], // 字符串数组address: {street: String,city: String}
});
自定义验证
const productSchema = new mongoose.Schema({price: {type: Number,validate: {validator: function(v) {return v >= this.costPrice; // 售价必须大于成本价},message: props => `售价 ${props.value} 不能低于成本价`}},costPrice: Number
});
4. 创建模型
const User = mongoose.model('User', userSchema);
const Product = mongoose.model('Product', productSchema);
5. CRUD 操作
创建文档
const newUser = new User({username: 'john_doe',age: 25,hobbies: ['reading', 'coding']
});// 保存方式1
const savedUser = await newUser.save();// 保存方式2
await User.create({username: 'jane_smith',age: 30
});
查询文档
// 基础查询
const users = await User.find({ age: { $gt: 20 } });// 链式查询
const user = await User.findOne({ username: 'john_doe' }).select('username age').sort('-age').limit(5);
更新文档
// 直接更新
await User.updateOne({ username: 'john_doe' },{ $set: { age: 26 } }
);// 先查询后保存
const user = await User.findById('...');
user.age = 26;
await user.save();
删除文档
await User.deleteOne({ _id: '...' });
await User.findByIdAndDelete('...');
6. 中间件(Hooks)
pre 保存钩子
userSchema.pre('save', function(next) {if (this.isNew) {this.createdAt = Date.now();}next();
});
post 查询钩子
userSchema.post('find', function(docs) {console.log(`查询到 ${docs.length} 个用户`);
});
7. 关联查询
定义关联模型
const postSchema = new mongoose.Schema({title: String,author: {type: mongoose.Schema.Types.ObjectId,ref: 'User'}
});
const Post = mongoose.model('Post', postSchema);
填充查询
const posts = await Post.find().populate('author', 'username').exec();
8. 聚合查询
const result = await User.aggregate([{ $match: { age: { $gt: 20 } } },{ $group: { _id: "$city",averageAge: { $avg: "$age" }}}
]);
9. 错误处理
try {await User.create({ age: 17 }); // 触发最小年龄验证
} catch (err) {if (err instanceof mongoose.Error.ValidationError) {console.log('验证错误:', err.message);}
}
10. 最佳实践
- 连接管理
// 连接状态监控
mongoose.connection.on('connected', () => console.log('MongoDB connected'));
mongoose.connection.on('error', (err) => console.error('MongoDB error', err));
mongoose.connection.on('disconnected', () => console.log('MongoDB disconnected'));
- 全局插件
// 为所有 Schema 添加时间戳
mongoose.plugin((schema) => {schema.add({ createdAt: { type: Date, default: Date.now },updatedAt: { type: Date, default: Date.now }});schema.pre('save', function(next) {this.updatedAt = Date.now();next();});
});
11. 调试模式
// 查看所有执行的查询
mongoose.set('debug', true);
12. 性能优化
索引创建
userSchema.index({ username: 1 }, { unique: true });
userSchema.index({ age: 1, city: 1 });
查询优化
// 仅返回需要字段
await User.find().select('username');// 限制结果数量
await User.find().limit(100);
13. 完整示例
const mongoose = require('mongoose');// 1. 连接数据库
mongoose.connect('mongodb://localhost:27017/mydb');// 2. 定义 Schema
const bookSchema = new mongoose.Schema({title: { type: String, required: true },author: String,price: Number,published: Boolean
});// 3. 创建模型
const Book = mongoose.model('Book', bookSchema);// 4. 业务操作
async function main() {// 创建const book = await Book.create({title: 'Node.js实战',author: '张三',price: 59.9,published: true});// 查询const foundBook = await Book.findById(book._id);// 更新await Book.updateOne({ _id: book._id },{ $set: { price: 69.9 } });// 删除await Book.deleteOne({ _id: book._id });
}main().catch(err => console.error(err));
常见问题解答
- 连接池配置
mongoose.connect(uri, {poolSize: 10, // 最大连接数socketTimeoutMS: 45000
});
- 时区处理
const date = new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai'
});
- 批量操作
await User.insertMany([{ username: 'user1', age: 25 },{ username: 'user2', age: 30 }
]);
通过这个教程,你可以掌握 Mongoose 的核心用法。建议配合官方文档 (https://mongoosejs.com/) 深入学习高级特性。