记录 mongose 使用过程中遇到的应用场景
1.mongoose 预定义模式修饰符
对增加的数据进行预格式化。
- lowercase
- uppercase
- trim 去掉左右两边的空格 ## 2.mongoose 自定义修饰符 setter 和 getter 通过 set 在添加数据的时候对数据进行格式化,或者在实例获取数据的时候对数据进行格式化。
1
2
3
4
5
6var TestSchema = mongoose.Schema({
name:{
type:String,
trim:true //定义 mongoose 修饰符,去掉空格
}
})get 同理,但不建议使用 get 。1
2
3
4
5
6
7
8
9
10
11
12
13
14var TestSchema = mongoose.Schema({
url:{
type:String,
set(params){ //定义 mongoose 修饰符,去掉空格
if(!params){
return ''
}else{
if(params.indexOf('http://')!=0&¶ms.indexOf('https://')!=0){
return 'http://' + params;
}
}
}
}
})
3.mongoose 数据校验
简单的有required 也可以自定义 更多
4.索引
设置索引的目的是为了优化查询的速度。 1. 基础索引 可以在定义 Schema
的时候指定创建索引 1
2
3
4
5
6
7
8
9
10var TestSchema = mongoose.Schema({
name:{
type:String,
unique:true //唯一索引
},
sex: {
type:String
index:true //普通索引
}
})1
db.factories.ensureIndex( { addr : 1 } );
5.扩展 mongoose 的静态方法和实例方法
在定义Schema的时候扩展数据库操作方法。 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 // 静态方法
TestSchema.statics.findBySex = function(sex,cb){
//通过 find 方法获取 sex 的数据
this.find({"sex":sex},function(err,data){
cb(err,data)
})
}
// 静态方法调用,model直接调用
var Test = mongoose.model('Test',TestSchema);
test.findBySex('female')
// 实例方法
var animalSchema = new Schema({ name: String, type: String });
animalSchema.methods.findSimilarTypes = function(cb) {
return this.model('Animal').find({ type: this.type }, cb);
};
// 实例方法调用,
var Animal = mongoose.model('Animal', animalSchema);
var dog = new Animal({ type: 'dog' });
// 必须先初始化一个实例
dog.findSimilarTypes(function(err, dogs) {
console.log(dogs); // woof
});
6.ObjectId()
_id: new mongoose.Types.ObjectId()
7.对文档中数组属性添加记录
相关方法: | 方法名 | 描述 | | ---- | --- | | \(pull | 从数组field内删除一个等于value的值 | |
pullAll | 用法同\)pull一样,可以一次删除数组内的多个值。 | |
$push | 把value追加到field里 | | \(pushAll |
用法同\)push一样,只是$pushAll一次可以追加多个值到一个数组字段内。
| | $addToSet | 加一个值到数组内,而且只有当这个值不在数组内才增加。 | |
\(pop | 删除数组内的一个值 |
常用的有\)addToSet和\(push使用如下:
1
2TestModel.updateOne({'_id':_id},{$addToSet:{fass:'wys'}})
TestModel.updateOne({'_id':_id},{$push:{fass:'wys'}})
8.Populaton 填充
将一个文档中的一部分字段,填充到另一个文档一个字段中 或者填充到另一个文档的多个字段中
以下代码定义了两个Schema ,注意 Story 的author 字段类型为 ref
指向的Person 文档 的_id . 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15var personSchema = db.Schema({
_id: db.Schema.Types.ObjectId,
name: String,
age: Number,
stories: [{ type: db.Schema.Types.ObjectId, ref: 'Story' }]
});
var storySchema = db.Schema({
author: { type: db.Schema.Types.ObjectId, ref: 'Person' },
title: String,
fans: [{ type: db.Schema.Types.ObjectId, ref: 'Person' }]
});
var Story = db.model('Story', storySchema);
var Person = db.model('Person', personSchema);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19var author = new Person({
_id: new mongoose.Types.ObjectId(),
name: 'Ian Fleming',
age: 50
});
author.save(function (err) {
if (err) return handleError(err);
var story1 = new Story({
title: 'Casino Royale',
author: author._id // assign the _id from the person
});
story1.save(function (err) {
if (err) return handleError(err);
// 保存成功
});
});1
2
3
4
5
6
7Story.
findOne({ title: 'Casino Royale' }).
populate('author').
exec(function (err, story) {
if (err) return handleError(err);
console.log(story);
});1
2
3
4
5
6
7
8
9
10{ fans: [],
_id: 5dc3881b53c06d363aa816bb,
title: 'Casino Royale',
author:
{ stories: [],
_id: 5dc3881b53c06d363aa816ba,
name: 'Ian Fleming',
age: 50,
__v: 0 },
__v: 0 }1
2
3
4
5
6
7Story.
findOne({ title: /casino royale/i }).
populate('author', ['name','age']). // 设置只填充 name、age 字段
exec(function (err, story) {
if (err) return handleError(err);
console.log(story);
});1
2
3
4
5
6
7
8{ fans:
[ 3dc3881b53c06d363aa816bb,
5dc3903d6b4365368f3c4074,
5dc3903d6b4365368f3c4074 ],
_id: 5dc3881b53c06d363aa816bb,
title: 'Casino Royale',
author: { _id: 5dc3881b53c06d363aa816ba, name: 'Ian Fleming', age: 50 },
__v: 0 }1
2
3
4
5Story.
find(...).
populate('fans').
populate('author').
exec();1
2
3
4
5
6
7// 第二个 `populate()` 覆盖了第一个,因为它们都填充 fans
Story.
find().
populate({ path: 'fans', select: 'name' }).
populate({ path: 'fans', select: 'email' });
// 以上代码等同于:
Story.find().populate({ path: 'fans', select: 'email' });1
2
3
4
5
6
7
8
9
10Story.
find(...).
populate({
path: 'fans',
match: { age: { $gte: 20 }}, // age >= 21
// 指定需要 name,age 字段而不要_id字段
select: 'name age -_id',
options: { limit: 5 } // 限制数量5条
}).
exec();1
2
3
4
5{ fans: [ { name: 'zhu', age: 20 }, { name: 'zhu', age: 20 } ],
_id: 5dc3881b53c06d363aa816bb,
title: 'Casino Royale',
author: 5dc3881b53c06d363aa816ba,
__v: 0 }
9.mongoose 中使用聚合管道连表查询
1 | TestModel.aggregate([ |