MongoDB中沒有join的特性,因此無法使用join進行表的連接和關聯查詢,在Mongoose中封裝了populate方法,在定義一個 Schema 的時候可以指定了其中的字段(屬性)是另一個Schema的引用,在查詢文檔時就可以使用 populate 方法通過引用 Schema 和 id 找到關聯的另一個文檔或文檔的指定字段值。下面是一個簡單的栗子:
【場景】: 通過學生ID找到學生所在的班級,對應集合: 學生students、 班級clazzs
1 var mongoose = require('mongoose') 2 var app = require('express')() 3 var mongoose = require('mongoose') 4 mongoose.connect('mongodb://localhost/test') 5 6 // 定義學生模式 7 var StudentSchema = new mongoose.Schema({ 8 name: String, 9 clazzID : { 10 type : mongoose.Schema.ObjectId, 11 ref : 'Clazz' // clazz的Model名 12 } 13 }) 14 // 連表查詢方法 15 StudentSchema.statics = { 16 findClazzNameByStudentId:function(studentId, callback){ 17 return this 18 .findOne({_id : studentId}).populate('clazzID') // 關聯查詢 19 .exec(callback) 20 } 21 } 22 23 // 定義班級模式 24 var ClazzSchema = new mongoose.Schema({ 25 clazzName: String 26 }); 27 28 // 模型 29 var Student = mongoose.model('Student',StudentSchema) 30 var Clazz = mongoose.model('Clazz',ClazzSchema) 31 32 // 新建班級文檔並保存 33 /*var clazz = new Clazz( 34 { 35 clazzName:'體育9班' 36 } 37 ); 38 clazz.save(function (argument){ 39 console.log('true'); 40 }); 41 */ 42 43 // 新建學生文檔並保存 44 /*var student = new Student({ 45 name : '馬冬梅', 46 clazzID : '56e1440f508c947b0f32c16b' //體育3班的_id 47 }) 48 student.save(function (err){ 49 console.log('true'); 50 })*/ 51 52 53 Student.findClazzNameByStudentId('56e1446c64a8f59c0f866df3', function (err, student){ 54 if(err) console.log(err); 55 console.log(student.name + " 在的班級: "+student.clazzID.clazzName); 56 /*通過studentID查詢到對應的學生對象,並通過關聯屬性clazzID獲取到對應classID的班級對象, 57 通過對象的clazzName屬性返回班級名稱*/ 58 }) 59 60 var logger = require('morgan'); 61 if('development' === app.get('env')){ 62 app.set('showStackError', true); // 輸出報錯信息 63 app.use(logger(':method :url :status')); // 輸出信息領域 64 app.locals.pretty = true; // 源代碼格式化 65 mongoose.set('debug', true); // 數據庫報錯信息 66 }
首先在數據庫中插入一下幾條班級的記錄:

然后新建學生對象:

通過clazzID的值可以知道 馬冬梅 的班級為 體育3班
運行代碼,通過studentID查詢 學生所在的班級, 結果如下:

