我在 Mongodb中有以下数据. { "_id" : ObjectId("54a0d4c5bffabd6a179834eb"), "is_afternoon_scheduled" : true, "employee_id" : ObjectId("546f0a06c7555ae310ae925a") } 我想使用populate with aggregate,并希望在同一个响应中获取
{ "_id" : ObjectId("54a0d4c5bffabd6a179834eb"), "is_afternoon_scheduled" : true, "employee_id" : ObjectId("546f0a06c7555ae310ae925a") }
我想使用populate with aggregate,并希望在同一个响应中获取员工完整信息,我需要帮助.我的代码是:
var mongoose = require("mongoose"); var empid = mongoose.Types.ObjectId("54a0d4c5bffabd6a179834eb"); Availability.aggregate() .match( { employee_id : empid} ) .group({_id : "$employee_id",count: { $sum: 1 }}) .exec(function (err, response) { if (err) console.log(err); res.json({"message": "success", "data": response, "status_code": "200"}); } );
我得到的回应是
{"message":"success","data":{"_id":"54a0d4c5bffabd6a179834eb","count":1},"status_code":"200"}
我的预期回应是:
{"message":"success","data":[{"_id":"54aa34fb09dc5a54232e44b0","count":1, "employee":{fname:abc,lname:abcl}}],"status_code":"200"}您可以从聚合操作调用结果对象上的模型形式
.populate()
.但问题是你需要一个模型来表示聚合返回的“Result”对象才能这样做.
有几个步骤,最好用完整的清单解释:
var async = require('async'), mongoose = require('mongoose'), Schema = mongoose.Schema; var employeeSchema = new Schema({ "fname": String, "lname": String }) var availSchema = new Schema({ "is_afternoon_scheduled": Boolean, "employee_id": { "type": Schema.Types.ObjectId, "ref": "Employee" } }); var resultSchema = new Schema({ "_id": { "type": Schema.Types.ObjectId, "ref": "Employee" }, "count": Number }); var Employee = mongoose.model( "Employee", employeeSchema ); var Availability = mongoose.model( "Availability", availSchema ); var Result = mongoose.model( "Result", resultSchema, null ); mongoose.connect('mongodb://localhost/aggtest'); async.series( [ function(callback) { async.each([Employee,Availability],function(model,callback) { model.remove({},function(err,count) { console.log( count ); callback(err); }); },callback); }, function(callback) { async.waterfall( [ function(callback) { var employee = new Employee({ "fname": "abc", "lname": "xyz" }); employee.save(function(err,employee) { console.log(employee), callback(err,employee); }); }, function(employee,callback) { var avail = new Availability({ "is_afternoon_scheduled": true, "employee_id": employee }); avail.save(function(err,avail) { console.log(avail); callback(err); }); } ], callback ); }, function(callback) { Availability.aggregate( [ { "$group": { "_id": "$employee_id", "count": { "$sum": 1 } }} ], function(err,results) { results = results.map(function(result) { return new Result( result ); }); Employee.populate(results,{ "path": "_id" },function(err,results) { console.log(results); callback(err); }); } ); } ], function(err,result) { if (err) throw err; mongoose.disconnect(); } );
这是完整的例子,但仔细研究聚合结果中发生的事情的主要观点是:
function(err,results) { results = results.map(function(result) { return new Result( result ); }); Employee.populate(results,{ "path": "_id" },function(err,results) { console.log(results); callback(err); }); }
首先要注意的是.aggregate()返回的结果不是mongoose文档,因为它们在.find()查询中.这是因为聚合管道通常会根据原始模式的结果更改结果中的文档.由于它只是一个原始对象,因此每个元素都会重新转换为前面定义的Result模型类型的mongoose文档.
现在为了使用来自Employee的数据.populate(),在文档对象形式的结果数组中调用此方法的模型形式以及要填充的字段的“path”参数.
最终结果填充是来自与其相关的Employee模型的数据.
[ { _id: { _id: 54ab2e3328f21063640cf446, fname: 'abc', lname: 'xyz', __v: 0 }, count: 1 } ]
与您使用find进行处理的方式不同,但由于结果的返回方式,有必要“重新投射”并以这种方式手动调用.