mongoose入门教程
以下是详细的 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/) 深入学习高级特性。
欢迎大家学习,交流
浙公网安备 33010602011771号