转载自 https://blog.csdn.net/elliott_yoho/article/details/53537147

在使用 mongoose 时,想通过一个外键与另一张表建立关联时,不知该如何简单快捷的实现,特地去查了一下,发现了 population 这个功能,在此简单记录下 mongoose 的 populate 使用。

环境
Node: v7.0.0
Bluebird: v3.4.6
Mongoose: v4.6.8
参考文档
ECMAScript 6 入门 —— Promise对象, 阮一峰
Mongoose 之 Population 使用, aikin
Mongoose API v4.7.2

使用方法
我觉得参考文档里的那篇文章 Mongoose 之 Population 使用, aikin 写的很详细了,这里为方便看,我把它复制过来了,所以,使用方法部分基本出自上述文章.

语法
Query.populate(path, [select], [model], [match], [options])
1
参数 Option
path
类型:String或Object。

String类型的时, 指定要填充的关联字段,要填充多个关联字段可以以空格分隔。
Object类型的时,就是把 populate 的参数封装到一个对象里。当然也可以是个数组。下面的例子中将会实现。
select
类型:Object或String,可选,指定填充 document 中的哪些字段。

Object类型的时,格式如: {name: 1, _id: 0},为0表示不填充,为1时表示填充。
String类型的时,格式如: “name -_id”,用空格分隔字段,在字段名前加上-表示不填充。详细语法介绍 query-select
尝试中发现 select 默认会填充 _id。

model
类型:Model,可选,指定关联字段的 model,如果没有指定就会使用Schema的ref。

match
类型:Object,可选,指定附加的查询条件。

options
类型:Object,可选,指定附加的其他查询选项,如排序以及条数限制等等。

基本使用
数据模型
创建三个Schema和Model。

var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://localhost/population');var Schema = mongoose.Schema;
var userSchema = new Schema({name: String,age: Number,posts: [{type: Schema.Types.ObjectId, ref: 'post'}],comments: [{type: Schema.Types.ObjectId, ref: 'comment'}]
});
var User = mongoose.model('user', userSchema);var postSchema = new Schema({title: String,content: String,author: {type: Schema.Types.ObjectId, ref: 'user'},comments: [{type: Schema.Types.ObjectId, ref: 'comment'}]
});
var Post = mongoose.model('post', postSchema);var commentSchema = new Schema({content: String,author: {type: Schema.Types.ObjectId, ref: 'user'}
})
var Comment = mongoose.model('comment', commentSchema);exports.User = User;
exports.Post = Post;
exports.Comment = Comment;
注: ref 对应的应该是在connection中注册过的model。var User = mongoose.model('user', userSchema);
...
author: {type: Schema.Types.ObjectId, ref: 'user'}

// 这里的 ref: ‘user’ 是第一行的 mongoose.model(‘user’, userSchema) 第一个参数。
插入数据

var User = require('./model').User;
var Post = require('./model').Post;
var Comment = require('./model').Comment;var tom = new User({name: 'Tom', age: 19});
var test = new Post({title: 'test', content: 'wakaka'});
var walala = new Comment({content: 'walala'});tom.save().then(function(user) {test.author = user;walala.author = user;return Promise.all([test.save(), walala.save(), user]);
}).spread(function(post, comment, user) {user.posts.push(post);user.comments.push(comment);post.comments.push(comment);return Promise.all([user.save(), post.save()]);
}).spread(function() {console.log('success');
}).catch(function(reason) {console.log(reason);
});
mongodb 查询数据
> db.users.find().pretty()
{"_id" : ObjectId("584a030733604a156a4f65ff"),"name" : "Tom","age" : 19,"comments" : [ObjectId("584a030733604a156a4f6601")],"posts" : [ObjectId("584a030733604a156a4f6600")],"__v" : 1
}
> db.posts.find().pretty()
{"_id" : ObjectId("584a030733604a156a4f6600"),"author" : ObjectId("584a030733604a156a4f65ff"),"title" : "test","content" : "wakaka","comments" : [ObjectId("584a030733604a156a4f6601")],"__v" : 1
}
> db.comments.find().pretty()
{"_id" : ObjectId("584a030733604a156a4f6601"),"author" : ObjectId("584a030733604a156a4f65ff"),"content" : "walala","__v" : 0
}

populate
填充单个字段
假如,填充 Comment 中的 author。

代码
这里通过传入 Object 类型参数调用 populate。

Comment.findOne({'content': 'walala'}).populate({path:'author', select: 'name'})
.exec().then(function(user) {console.log(user);
}).catch(function(reason) {console.log(reason);
});

结果
{ _id: 584a030733604a156a4f6601,
author: { _id: 584a030733604a156a4f65ff, name: ‘Tom’ },
content: ‘walala’,
__v: 0 }
填充多个字段
假如,我们要填充 Post 中的 author 和 comments,且填充 author 的 name 和 age,还有 comments 的 content; 不填充 author 和 comments 的 _id。

代码
以下两种写法效果是一样的。

// 若是用字符串填写,select 同时作用于两个字段,即 author 和 comments 都会填充 name age content,若该字段没有这些数据,则不填充。
Post.findOne({'title': 'test'}).populate('author comments', 'name age content -_id').exec()
.then(function(post) {console.log(post);
}).catch(function(reason) {console.log(reason);
});// 数组形式可以单独对某一字段用 select 选择要填充的数据。
Post.findOne({'title': 'test'}).populate([{path: 'author', select: 'name age -_id'}, {path: 'comments', select: 'content -_id'}]).exec()
.then(function(post) {console.log(post);
}).catch(function(reason) {console.log(reason);
});

结果

{ _id: 584a030733604a156a4f6600,author: { name: 'Tom', age: 19 },title: 'test',content: 'wakaka',__v: 1,comments: [ { content: 'walala' } ] }

[NodeJS] Mongoose Populate 基本使用相关推荐

  1. 使用Mongoose populate实现多表关联存储与查询,内附完整代码

    文章目录 使用Mongoose populate实现多表关联与查询 一. 数据模型创建 1. 创建一个PersonSchema 2. 创建一个StorySchema 3. 使用Schema创建对应的m ...

  2. nodejs mongoose建模实践

    2019独角兽企业重金招聘Python工程师标准>>> 一直以来mongoose学习都是比较麻烦的,mongoose-cli试图简化学习和测试mongoose部分,并通过app开发流 ...

  3. mongoose populate 返回 指定 字段

    1.mongoose中一个数据模型Product(商品)关联另外一个数据模型Brand(品牌)需要使用ref,关联查询使用populate Product模型 new mongoose.Schema( ...

  4. Mongoose populate方法

    最近好忙啊,好久没有来写博客了- 干巴蝶! 还是那句话,写一遍真的比看一遍要好很多! populate方法提供外键填充的功能.由于Mongoose是极具JavaScript特点的程序库,提供了极其简单 ...

  5. mongoose populate 填充

    学习笔记 内容待商榷 欢迎提出宝贵意见 populate方法提供外键填充的功能 1.创建作者集合 const User = new mongoose.model('User', new mongoos ...

  6. Mongoose Populate

    本文已整理到 Github,地址

  7. Mongoose 中使用 populate 实现关联查询

    一.Mongoose populate 官方文档 https://mongoosejs.com/docs/populate.html 二.Mongoose populate 关联查询 1.定义 ref ...

  8. Eggjs笔记:详解Mongoose的聚合管道以及populate实现关联查询

    基于mongodb的聚合管道 此处忽略之前mongodb在eggjs中需要配置的步骤,前文已有说明,现在开始在controller中调用(应该封装到service中的,仅作为示例) const res ...

  9. 太急了点吧?贴吧PWA20天就出炉了

    "老司机开车 从不需要理由 喜欢我 就来点我吧" 易杭贴吧--新鲜出炉的中文社区 http://tieba.freeedit.cn 1. 前述 最近一直在写一个发贴子的应用,前不久 ...

最新文章

  1. 如何创建和维护你自己的man手册
  2. js控制Iframe 和 iframe与主页的交互,传值 (转载)
  3. ChartDirector资料小结
  4. C# 将List中的数据导入csv文件中
  5. Android onSaveInstanceState、onRestoreInstanceState保存数据
  6. PLSQL导出触发器代码
  7. rxjs switchMap的实现原理
  8. 前端学习(3269):js中this在类中的表现
  9. setuptools find_packages
  10. Android中使用HttpURLConnection实现GET POST JSON数据与下载图片
  11. 基于java的教师教学评价管理系统
  12. texture_laws 纹理滤波用于缺陷检测
  13. 阿里巴巴招募AI鉴黄体验官,日薪1000,小姐姐优先,快看看你是否符合
  14. org.apache.ibatis.binding.BindingException: Type interface com.java.mapper.UserMapper is not known t
  15. 高斯投影正反算C语言程序代码,高斯投影正反算c代码
  16. 解决方法:CC2640R2F从7x7改成5x5封装,主机连接失败
  17. HTML CSS基本知识点总结
  18. 关于数据存储引擎结构,没有比这篇更详细的
  19. [数据挖掘笔记] 聚类算法KMeans
  20. 一篇文章搞懂Typescript

热门文章

  1. 【HigherHRNet】 HigherHRNet 详解之 HigherHRNet的热图回归代码
  2. ppt python 图表_利用python分析weibo数据做成图表放入PPT中
  3. 计算机毕业设计之java+ssm校园外卖配送系统
  4. 清明不远游 国内赏春地推荐
  5. MCU裸系统下快速平方根实现
  6. excel切片器_如何快速做出酷炫的Excel动态图表?
  7. c语言程序设计精髓 第13周练兵题
  8. 音频信号的基波和谐波介绍
  9. 排名第一的word模板引擎,到底有多神仙
  10. @mysql数据库面试手册