第7章-使用ORM类库Mongoose提升你的Node.js数据-7.6.使用population建立关系和连接

虽然,在NoSQL类的数据库,例如MongoDB中是不存储关系数据的,但是我们可以在应用层进行存储。
Mongoose提供了这一特性,名为population。
他允许我们使用不同的集合来填充文档的特定部分。
假设我们有posts和users两个集合
我们可以在user的原型中引用posts:

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;
var userSchema = Schema({
    _id: Number,
    name: String,
    posts: [{type: Schema.Types.ObjectId, ref: 'Post'}]
});

var postSchema = Schema({
    _creator: {type: Number, ref: 'User'},
    title: String,
    text: String
});

var Post = mongoose.model('Post', postSchema);
var User = mongoose.model('User', userSchema);
User.findOne({nema: /lijian/i})
    .populate('posts')
    .exec(function(err, user){
        if(err) return handleError(err);
        console.log('The user has % post(s)', user.posts.length);
})

注:ObjectId、Number、String和Buffer都是可以直接引用的合法数据类型

在上面的查询中,我们使用了正则表达式(RegExp)
虽然Mongoose并不包含这一特性,但实际上,原生的驱动以及其他封装库,就连mongo控制台都是支持正则表达式的。
语法与标准的JavaScript/Node.js正则表达式是一样的。
用这种方法,我们完成了对Post和User的联合查询。

当然也可以只返回复杂结果的一部分,例如,我们可以限制posts只取前10个:

.populate({
    path: 'posts',
    options: {limit:10, sort:'title'}
})

有时候,只返回文档的特定部分比返回整个文档更实用。
可以使用以下查询语句实现:

.populate({
    path: 'posts',
    select: 'title',
    options: {limit: 10, sort: 'title'}
})

此外,Mongoose可以使用查询语句对复杂的返回结果进行过滤!
如:我们可以对text(其中一个查询匹配的属性)使用正则表达式匹配出“node.js”:

.populate({
    path: 'posts',
    select: '_id title text',
    match: {text: /node\.js/i},
    options: {limit:10, sort:'_id'}
})

这里,可以按照需求定制查询,带上需要选择的字段(选择字段名字为_id、title、text)即可。
最好的做法是只查询所需的部分,因为这可以避免潜在的安全信息泄露以及减少服务器负担。

populate 方法也能作用于文档的复合查询中,比如,我们可以用find方法代替findOne方法:

User.find({}, {limit:10, sort:{_id:-1}})
    .populate('posts')
    .exec(function(err, user){
        if(err) return handleError(err);
        console.log('The user has % post(s)', user.posts.length);
})

小贴士:对于自定义排序,我们可以使用形如name:-1或者name:1这样的参数,并将他传递给sort字段即可。
同之前提到的一样,这是一个MongoDB的标准接口,不适用于Mongoose

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值