Mongoose 使用之 Population

何爲 Population

用過 MongoDB 的人應該都知道它是沒有關係型數據庫裏的 join 特性的,這意味着當咱們使用 MongoDB 讀取某個 document 及其關聯的 document 的字段的時候,變得尤其麻煩。數據庫

基於此,Mongoose 封裝了一個 population 的功能,當你在定義 Schema 的時候指定了某個 field 是引用了另外一個 Schema ,那麼你在獲取 document 的時候就可使用 populate 方法讓 Mongoose 幫你經過引用 Schema 和 id 找到關聯的另外一個 document,而且用該 document 的內容替換掉原來引用字段的內容,使引用的 ducoment 使用起來就像是內嵌的 document 同樣方便。數組

定義帶有引用字段的 Schema

首先,若是要使用這個功能,必須給你的「外鍵字段」定義 Mongoose 的「外鍵約束」(這裏借用關係型數據庫的術語,只是爲了幫助理解)。假設咱們有一個用戶的 Schema ,其中有一個字段是followings,保存用戶關注了的其餘用戶,相似微博。Mongoose 的 Schema 定義以下:mongoose

var mongoose = require('mongoose')
  , Schema = mongoose.Schema
  
var UserSchema = Schema({
  name    : String,
  followings : [{ type: Schema.Types.ObjectId, ref: 'User' }]
});
    
var User = mongoose.model('User', UserSchema);

保存引用字段

而後咱們建立兩個 User 實例,而且先將其中之一保存進數據庫(爲了產生 _id ):函數

var lily = new User({name: 'lily'})
   ,lucy = new User({name: 'lucy'});
lily.save(cb);

lily 保存成功後,咱們再在回調函數 cb 中保存 lucy ,不過這個時候假設 lucy 關注了 lily:ui

function cb(err) {
    if(err) throw err;
    lucy.followings.push(lily._id);// line 1
    lucy.save(cb1);
}

這樣就保存完成了。不過好像咱們沒用引用字段以前也是這麼保存的吧?有沒有更直接一點的?有,你其實能夠將 line 1 的語句改爲如下形式, Mongoose 也會自動幫你作內部解析的:code

lucy.followings.push(lily);

這樣看起來代碼就更接近天然語言了,有點ORM的味道。對象

查詢 document

固然,上面的例子可能對開發者來講沒有什麼太大的用處,那麼就來看看 population 在獲取 document 的時候能給咱們帶來什麼好處吧。排序

假設咱們如今要找到 lucy 的信息以及她所關注的用戶,咱們能夠這樣:開發

User.findOne({name: 'lucy'}).exec(cb2);

可是這樣拿出來的 lucy 的 followings 是一組存儲了 ObjectId 的數組,還得去一個個查找對應的用戶,多麻煩啊。因此這個時候用 population 就簡單多了,直接指定你想要 populate 哪一個引用字段:get

User.findOne({name: 'lucy'}).populate('followings').exec(cb2);

這樣的話,在回調函數 cb2 中你獲得的就是一個存儲了若干個 User 對象的數組了。

populate 方法

populate 方法能夠用在 document 上、 model 上或者是 query 對象上,這意味着你幾乎能夠在任何地方調用這個方法以填充你的引用字段。

固然,populate 方法在不一樣對象上參數不大同樣,可是都接收一個option的參數,你能夠用這些參數指定:

  • path: 以空格分隔的引用字段的名稱
  • select: 填充引用 document 中的哪些字段
  • match: 可選,指定附加的查詢條件
  • model: 可選,指定引用的 model
  • options: 可選,指定附加的其餘查詢選項,如排序以及條數限制等等

引用字段的類型

目前,Mongoose 只支持如下幾種引用字段的類型:

  • ObjectId
  • Number
  • String
  • Buffer

並且天然而然,引用 document 的主鍵類型必須和引用字段類型相對應。在生產環境中,推薦主鍵類型和引用類型都使用 ObjectId ,一是由於 ObjectId 不包含業務含義,二是 ObjectId 不大可能重複,三是由於 Mongoose 默認生成的主鍵類型就是 ObjectId ,能夠減小不少配置的操做。

更多信息請關注這裏

相關文章
相關標籤/搜索