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查询 学生所在的班级, 结果如下: