吴贺华 发表于 2017-12-15 16:06:39

mongodb中的populate方法【转载】

  Mongoose 是 MongoDB 的 ODM(Object Document Mapper)。

  
什么是ODM? 其实和ORM(Object>  
MongoDB 是文档型数据库(Document Database),不是关系型数据库(Relational Database)。而Mongoose可以将 MongonDB 数据库存储的文档(documents)转化为 javascript 对象,然后可以直接进行数据的增删改查。
  因为MongoDB是文档型数据库,所以它没有关系型数据库(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    = ;  
var postIds    = ;
  
var commentIds = ;
  

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

  
users.push({
  _id   : userIds,
  name: 'aikin',
  posts : ]
  
});
  
users.push({
  _id   : userIds,
  name: 'luna',
  posts : ]
  
});
  
users.push({
  _id   : userIds,
  name: 'luajin',
  posts : ]
  
});
  

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

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

  
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, , , , )
  
参数:
  
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.title);// post-by-aikin
  });
  
});
  
页: [1]
查看完整版本: mongodb中的populate方法【转载】