设为首页 收藏本站
查看: 1191|回复: 0

[经验分享] mongodb中的populate方法【转载】

[复制链接]

尚未签到

发表于 2017-12-15 16:06:39 | 显示全部楼层 |阅读模式
  Mongoose 是 MongoDB 的 ODM(Object Document Mapper)。

  
什么是ODM? 其实和ORM(Object>  
MongoDB 是文档型数据库(Document Database),不是关系型数据库(Relational Database)。而Mongoose可以将 MongonDB 数据库存储的文档(documents)转化为 javascript 对象,然后可以直接进行数据的增删改查。
  因为MongoDB是文档型数据库,所以它没有关系型数据库[joins](http://zh.wikipedia.org/wiki/%E8%BF%9E%E6%8E%A5_(SQL)(数据库的两张表通过"外键",建立连接关系。) 特性。也就是在建立数据的关联时会比较麻烦。为了解决这个问题,Mongoose封装了一个Population功能。使用Population可以实现在一个 document 中填充其他 collection(s) 的 document(s)。
  在定义Schema的时候,如果设置某个 field 关联另一个Schema,那么在获取 document 的时候就可以使用 Population 功能通过关联Schema的 field 找到关联的另一个 document,并且用被关联 document 的内容替换掉原来关联字段(field)的内容。
  接下来分享下:Query#populate Model#populate Document#populate的用法
  先建立三个Schema和Model:
    var mongoose = require('mongoose');  
var Schema   = mongoose.Schema;
  

  
var UserSchema = new Schema({
  name  : { type: String, unique: true },
  posts : [{ type: Schema.Types.ObjectId, ref: 'Post' }]
  
});
  
var User = mongoose.model('User', UserSchema);
  

  
var PostSchema = new Schema({
  poster   : { type: Schema.Types.ObjectId, ref: 'User' },
  comments : [{ type: Schema.Types.ObjectId, ref: 'Comment' }],
  title    : String,
  content  : String
  
});
  
var Post = mongoose.model('Post', PostSchema);
  

  
var CommentSchema = new Schema({
  post      : { type: Schema.Types.ObjectId, ref: "Post" },
  commenter : { type: Schema.Types.ObjectId, ref: 'User' },
  content   : String
  
});
  
var Comment = mongoose.model('Comment', CommentSchema);
  在上述的例子中,创建了三个 Models:User,Post,Comment。
  
User 的属性 posts,对应是一个 ObjectId 的数组。ref表示关联Post(注意: 被关联的model的 type 必须是ObjectId, Number, String, 和 Buffer 才有效)。
  
Post的属性 poster 和 comments 分别关联User和Comment。
  
Comment的属性 post 和 commenter 分别关联Post和User。
  
三个 Models 的关系:一个 user--has many-->post。一个 post--has one-->user,has many-->comment。一个 comment--has one-->post 和 user。

创建一些数据到数据库:
  // 连接数据库
  
mongoose.connect('mongodb://localhost/population-test', function (err){
  
if (err) throw err;
  
createData();
  
});
  function createData() {
  

var userIds    = [new ObjectId, new ObjectId, new ObjectId];  
var postIds    = [new ObjectId, new ObjectId, new ObjectId];
  
var commentIds = [new ObjectId, new ObjectId, new ObjectId];
  

  
var users    = [];
  
var posts    = [];
  
var comments = [];
  

  
users.push({
  _id   : userIds[0],
  name  : 'aikin',
  posts : [postIds[0]]
  
});
  
users.push({
  _id   : userIds[1],
  name  : 'luna',
  posts : [postIds[1]]
  
});
  
users.push({
  _id   : userIds[2],
  name  : 'luajin',
  posts : [postIds[2]]
  
});
  

  
posts.push({
  _id      : postIds[0],
  title    : 'post-by-aikin',
  poster   : userIds[0],
  comments : [commentIds[0]]
  
});
  
posts.push({
  _id      : postIds[1],
  title    : 'post-by-luna',
  poster   : userIds[1],
  comments : [commentIds[1]]
  
});
  
posts.push({
  _id      : postIds[2],
  title    : 'post-by-luajin',
  poster   : userIds[2],
  comments : [commentIds[2]]
  
});
  

  
comments.push({
  _id       : commentIds[0],
  content   : 'comment-by-luna',
  commenter : userIds[1],
  post      : postIds[0]
  
});
  
comments.push({
  _id       : commentIds[1],
  content   : 'comment-by-luajin',
  commenter : userIds[2],
  post      : postIds[1]
  
});
  
comments.push({
  _id       : commentIds[2],
  content   : 'comment-by-aikin',
  commenter : userIds[1],
  post      : postIds[2]
  
});
  

  
User.create(users, function(err, docs) {
  Post.create(posts, function(err, docs) {
  Comment.create(comments, function(err, docs) {
  });
  });
  
});
  

  }

数据的准备就绪后,接下来就是探索populate方法:


  • Query#populate
  什么Query? Query(查询),可以快速和简单的从MongooDB查找出相应的 document(s)。 Mongoose 封装了很多查询的方法,使得对数据库的操作变得简单啦。这里分享一下populate方法用法。
  语法:
  
Query.populate(path, [select], [model], [match], [options])
  
参数:
  
path
  
  类型:String或Object。
  
  String类型的时, 指定要填充的关联字段,要填充多个关联字段可以以空格分隔。
  
  Object类型的时,就是把 populate 的参数封装到一个对象里。当然也可以是个数组。下面的例子中将会实现。
  
select
  
  类型:Object或String,可选,指定填充 document 中的哪些字段。
  
  Object类型的时,格式如:{name: 1, _id: 0},为0表示不填充,为1时表示填充。
  
  String类型的时,格式如:"name -_id",用空格分隔字段,在字段名前加上-表示不填充。详细语法介绍query-select
  
model
  
  类型:Model,可选,指定关联字段的 model,如果没有指定就会使用Schema的ref。
  
match
  
  类型:Object,可选,指定附加的查询条件。
  
options
  
  类型:Object,可选,指定附加的其他查询选项,如排序以及条数限制等等。
  
填充User的posts字段:
  
全选复制放进笔记User.findOne({name: 'aikin'})
  
.exec(function(err, doc) {
  

    var opts = [{  path   : 'posts',
  select : 'title'
  }];
  

  doc.populate(opts, function(err, populatedDoc) {
  console.log(populatedDoc.posts[0].title);  // post-by-aikin
  });
  
});
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-424409-1-1.html 上篇帖子: mongoDB在java上面的应用 下篇帖子: MongoDB学习第七篇
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表