如何在相同的语句中使用填充和聚合?

这是我的约会collections

{ _id: ObjectId("518ee0bc9be1909012000002"), date: ISODate("2013-05-13T22:00:00Z"), patient:ObjectId("518ee0bc9be1909012000002") } { _id: ObjectId("518ee0bc9be1909012000002"), date: ISODate("2013-05-13T22:00:00Z"), patient:ObjectId("518ee0bc9be1909012000002") } { _id: ObjectId("518ee0bc9be1909012000002"), date: ISODate("2013-05-13T22:00:00Z"), patient:ObjectId("518ee0bc9be1909012000002") } 

我使用聚合来获得结果

 {date: ISODate("2013-05-13T22:00:00Z"), patients:[ObjectId("518ee0bc9be1909012000002"),ObjectId("518ee0bc9be1909012000002"),ObjectId("518ee0bc9be1909012000002")] } 

喜欢这个

 Appointments.aggregate([ {$group: {_id: '$date', patients: {$push: '$patient'}}}, {$project: {date: '$_id', patients: 1, _id: 0}} ], ...) 

如何填充耐心的文件,我尝试这个,但不工作… Appointments.find({}).populate("patient").aggregate ….

换句话说,我可以使用填充和聚合在相同的语句

请任何帮助

用最新版本的mongoose(mongoose> = 3.6),你可以但需要第二个查询,并使用不同的填充。 在您汇总之后,执行以下操作:

 Patients.populate(result, {path: "patient"}, callback); 

请参阅Mongoose API和Mongoose文档 。

你可以使用$ lookup来填充。

在一个不相关的例子中,我使用$ match来查询logging,使用$ lookup来填充外部模型作为这些logging的一个子属性:

  Invite.aggregate( { $match: {interview: req.params.interview}}, { $lookup: {from: 'users', localField: 'email', foreignField: 'email', as: 'user'} } ).exec( function (err, invites) { if (err) { next(err); } res.json(invites); } ); 

简短的回答:你不能。

长答案:在聚合框架中,返回的字段是由您创build的,您可以“重命名”文档属性。

这意味着,mongoose不能确定你的参考文件将在最终结果中可用。

在这种情况下你可以做的最好的事情是在查询返回之后填充你想要的字段。 是的,这将导致两个数据库调用,但这是MongoDB允许我们做的。

有点像这样:

 Appointments.aggregate([ ... ], function( e, result ) { if ( e ) return; // You would probably have to do some loop here, as probably 'result' is array Patients.findOneById( result.patient, function( e, patient ) { if ( e ) return; result.patient = patient; }); }); 

使用$ lookup执行join

收集订单包含以下文件:

 { "_id" : 1, "item" : "abc", "price" : 12, "quantity" : 2 } { "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1 } { "_id" : 3 } 

另一个集合库存包含以下文档:

 { "_id" : 1, "sku" : "abc", description: "product 1", "instock" : 120 } { "_id" : 2, "sku" : "def", description: "product 2", "instock" : 80 } { "_id" : 3, "sku" : "ijk", description: "product 3", "instock" : 60 } { "_id" : 4, "sku" : "jkl", description: "product 4", "instock" : 70 } { "_id" : 5, "sku": null, description: "Incomplete" } { "_id" : 6 } 

对订单集合的以下汇总操作将使用订单集合中的字段项目和清单集合中的sku字段将来自订单的文档与清单集合中的文档结合起来:

 db.orders.aggregate([ { $lookup: { from: "inventory", localField: "item", foreignField: "sku", as: "inventory_docs" } } ]) 

该操作返回以下文档:

 { "_id" : 1, "item" : "abc", "price" : 12, "quantity" : 2, "inventory_docs" : [ { "_id" : 1, "sku" : "abc", description: "product 1", "instock" : 120 } ] } { "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "inventory_docs" : [ { "_id" : 4, "sku" : "jkl", "description" : "product 4", "instock" : 70 } ] } { "_id" : 3, "inventory_docs" : [ { "_id" : 5, "sku" : null, "description" : "Incomplete" }, { "_id" : 6 } ] } 

参考$ lookup

在这里输入图像描述

 domain.Farm.aggregate({ $match: { "_id": mongoose.Types.ObjectId(farmId) } }, { $unwind: "$SelfAssessment" }, { $match: { "SelfAssessment.questionCategoryID": QuesCategoryId, "SelfAssessment.questionID": quesId } },function(err, docs) { var options = { path: 'SelfAssessment.actions', model: 'FarmAction' }; domain.Farm.populate(docs, options, function (err, projects) { callback(err,projects); }); }); 

结果我得到了行动模型填充

 { "error": false, "object": [ { "_id": "57750cf6197f0b5137d259a0", "createdAt": "2016-06-30T12:13:42.299Z", "updatedAt": "2016-06-30T12:13:42.299Z", "farmName": "abb", "userId": "57750ce2197f0b5137d2599e", "SelfAssessment": { "questionName": "Aquatic biodiversity", "questionID": "3kGTBsESPeYQoA8ae2Ocoy", "questionCategoryID": "5aBe7kuYWIEoyqWCWcAEe0", "question": "Waterways protected from nutrient runoff and stock access through fencing, buffer strips and off stream watering points", "questionImage": "http://images.contentful.com/vkfoa0gk73be/4pGLv16BziYYSe2ageCK04/6a04041ab3344ec18fb2ecaba3bb26d5/thumb1_home.png", "_id": "57750cf6197f0b5137d259a1", "actions": [ { "_id": "577512c6af3a87543932e675", "createdAt": "2016-06-30T12:38:30.314Z", "updatedAt": "2016-06-30T12:38:30.314Z", "__v": 0, "Evidence": [], "setReminder": "", "description": "sdsdsd", "priority": "High", "created": "2016-06-30T12:38:30.312Z", "actionTitle": "sdsd" } ], "answer": "Relevant" }, "locations": [] } ], "message": "", "extendedMessage": "", "timeStamp": 1467351827979 } 

你可以在一个查询中这样做:

 Appointments.aggregate([{ $group: { _id: '$date', patients: { $push: '$patient' } } }, { $project: { date: '$_id', patients: 1, _id: 0 } }, { $lookup: { from: "patients", localField: "patient", foreignField: "_id", as: "patient_doc" } } ]) 

基本上使用$查找引擎盖下。 在这种情况下不需要第二个查询。 有关更多详细信息,请查看MongoDB聚合查找