Mongoose的核心特性
Mongoose是一个优秀的Node.js对象模型工具,专为MongoDB设计。它提供了强大的数据建模、验证、查询构建和中间件支持,简化了与MongoDB的交互过程。
数据建模与模式定义
Mongoose的核心是Schema(模式),它定义了文档的结构、字段类型和验证规则。通过Schema可以精确控制数据的形状和行为。例如:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const userSchema = new Schema({
username: {
type: String,
required: true,
unique: true,
minlength: 3,
maxlength: 20
},
email: {
type: String,
required: true,
match: /.+\@.+\..+/
},
age: {
type: Number,
min: 18,
max: 120
},
createdAt: {
type: Date,
default: Date.now
},
isActive: Boolean,
hobbies: [String]
});
Schema支持多种数据类型:
- String, Number, Boolean, Date
- Buffer (二进制数据)
- Mixed (任意类型)
- ObjectId (引用其他文档)
- Array (包含特定类型的数组)
模型与文档操作
将Schema编译为Model后,就可以进行CRUD操作了:
const User = mongoose.model('User', userSchema);
// 创建文档
const newUser = new User({
username: 'devuser',
email: 'dev@example.com',
age: 25
});
// 保存文档
newUser.save()
.then(doc => console.log(doc))
.catch(err => console.error(err));
// 查询文档
User.findOne({ username: 'devuser' })
.then(user => console.log(user))
.catch(err => console.error(err));
Model提供了丰富的查询方法:
find()
: 查询多个文档findOne()
: 查询单个文档findById()
: 通过ID查询countDocuments()
: 计数updateOne()/updateMany()
: 更新文档deleteOne()/deleteMany()
: 删除文档
高级查询功能
Mongoose的查询构建器支持链式调用和丰富的操作符:
// 链式查询
User.find()
.where('age').gte(18).lte(30)
.where('isActive').equals(true)
.sort('-createdAt')
.limit(10)
.select('username email')
.exec()
.then(users => console.log(users));
支持的操作符包括:
- 比较操作符:
$gt
,$gte
,$lt
,$lte
,$ne
- 逻辑操作符:
$and
,$or
,$not
,$nor
- 数组操作符:
$in
,$nin
,$all
- 元素操作符:
$exists
,$type
数据验证
Mongoose提供了强大的内置验证器:
const productSchema = new Schema({
name: { type: String, required: true },
price: {
type: Number,
required: true,
validate: {
validator: function(v) {
return v > 0;
},
message: props => `${props.value}不是有效的价格`
}
},
category: {
type: String,
enum: ['electronics', 'clothing', 'food']
}
});
验证类型包括:
- 必填验证:
required
- 字符串验证:
minlength
,maxlength
,match
(正则) - 数字验证:
min
,max
- 枚举验证:
enum
- 自定义验证:
validate
中间件(钩子函数)
Mongoose支持在特定操作前后执行中间件:
userSchema.pre('save', function(next) {
if (this.isModified('password')) {
this.password = hashPassword(this.password);
}
next();
});
userSchema.post('save', function(doc, next) {
sendWelcomeEmail(doc.email);
next();
});
支持的钩子类型:
- 文档中间件:
validate
,save
,remove
- 查询中间件:
count
,find
,findOne
,update
,delete
- 聚合中间件:
aggregate
- 模型中间件:
insertMany
虚拟属性
虚拟属性不会存入数据库,但可以像普通属性一样访问:
userSchema.virtual('fullName').get(function() {
return `${this.firstName} ${this.lastName}`;
});
userSchema.virtual('fullName').set(function(name) {
const [firstName, lastName] = name.split(' ');
this.firstName = firstName;
this.lastName = lastName;
});
数据填充(Population)
Mongoose可以自动填充文档引用:
const storySchema = new Schema({
author: { type: Schema.Types.ObjectId, ref: 'User' },
title: String
});
Story.findOne({ title: 'Mongoose Guide' })
.populate('author')
.exec()
.then(story => console.log(story.author.username));
填充选项包括:
- 选择填充字段:
populate('field', 'name email')
- 多级填充:
populate({ path: 'field', populate: { path: 'nested' } })
- 条件填充:
populate({ path: 'field', match: { age: { $gt: 18 } } })
插件系统
Mongoose支持通过插件扩展功能:
function timestampPlugin(schema) {
schema.add({
createdAt: Date,
updatedAt: Date
});
schema.pre('save', function(next) {
const now = new Date();
this.updatedAt = now;
if (!this.createdAt) {
this.createdAt = now;
}
next();
});
}
userSchema.plugin(timestampPlugin);
常用插件:
- mongoose-autopopulate: 自动填充引用
- mongoose-paginate: 分页支持
- mongoose-unique-validator: 唯一性验证
- mongoose-timestamp: 自动时间戳
事务支持
Mongoose支持MongoDB的事务操作:
const session = await mongoose.startSession();
session.startTransaction();
try {
const user = await User.create([{ username: 'txuser' }], { session });
await Account.create([{ userId: user[0]._id, balance: 100 }], { session });
await session.commitTransaction();
} catch (error) {
await session.abortTransaction();
throw error;
} finally {
session.endSession();
}
性能优化
Mongoose提供了多种性能优化手段:
- 查询优化:
// 只选择需要的字段
User.find().select('username email');
// 使用lean()返回普通JS对象
User.find().lean();
- 批量操作:
// 批量插入
User.insertMany([user1, user2, user3]);
// 批量更新
User.updateMany({ isActive: false }, { $set: { status: 'inactive' } });
- 索引支持:
userSchema.index({ username: 1 }, { unique: true });
userSchema.index({ email: 1, status: 1 });
聚合框架集成
Mongoose完全支持MongoDB的聚合框架:
Order.aggregate([
{ $match: { status: 'completed' } },
{ $group: {
_id: '$customer',
total: { $sum: '$amount' },
count: { $sum: 1 }
}},
{ $sort: { total: -1 } },
{ $limit: 10 }
]);
多数据库连接
Mongoose支持同时连接多个数据库:
const conn1 = mongoose.createConnection('mongodb://localhost/db1');
const conn2 = mongoose.createConnection('mongodb://localhost/db2');
const Model1 = conn1.model('Model', schema);
const Model2 = conn2.model('Model', schema);
类型转换与自定义类型
Mongoose支持自定义类型和类型转换:
function toLower(v) {
return v.toLowerCase();
}
const emailSchema = new Schema({
email: {
type: String,
set: toLower
}
});
// 自定义类型
class Money extends mongoose.SchemaType {
constructor(key, options) {
super(key, options, 'Money');
}
cast(val) {
return parseFloat(val).toFixed(2);
}
}
mongoose.Schema.Types.Money = Money;
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
下一篇:Mongoose的应用场景