mongodb中的populate方法【轉載】

Mongoose 是 MongoDB 的 ODM(Object Document Mapper)。
什麼是ODM? 其實和ORM(Object Relational Mapper)是同類型的工具。都是將數據庫的數據轉化爲代碼對象的庫,使用轉化後的對象能夠直接對數據庫的數據進行CRUD(增刪改查)。
MongoDB 是文檔型數據庫(Document Database),不是關係型數據庫(Relational Database)。而Mongoose能夠將 MongonDB 數據庫存儲的文檔(documents)轉化爲 javascript 對象,而後能夠直接進行數據的增刪改查。javascript

由於MongoDB是文檔型數據庫,因此它沒有關係型數據庫[joins](http://zh.wikipedia.org/wiki/%E8%BF%9E%E6%8E%A5_(SQL)(數據庫的兩張表經過"外鍵",創建鏈接關係。) 特性。也就是在創建數據的關聯時會比較麻煩。爲了解決這個問題,Mongoose封裝了一個Population功能。使用Population能夠實如今一個 document 中填充其餘 collection(s) 的 document(s)。java

在定義Schema的時候,若是設置某個 field 關聯另外一個Schema,那麼在獲取 document 的時候就能夠使用 Population 功能經過關聯Schema的 field 找到關聯的另外一個 document,而且用被關聯 document 的內容替換掉原來關聯字段(field)的內容。mongodb

接下來分享下: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。app

建立一些數據到數據庫:

// 鏈接數據庫
mongoose.connect('mongodb://localhost/population-test', function (err){
if (err) throw err;
createData();
});mongoose

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) {
        });
    });
});

}post

數據的準備就緒後,接下來就是探索populate方法:
  1. Query#populate

什麼Query? Query(查詢),能夠快速和簡單的從MongooDB查找出相應的 document(s)。 Mongoose 封裝了不少查詢的方法,使得對數據庫的操做變得簡單啦。這裏分享一下populate方法用法。ui

語法:
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
    });
});
相關文章
相關標籤/搜索