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

这是我的预约收藏:

{ _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... 。

换句话说,我是否可以在同一个语句中使用填充和聚合

需要帮忙吗

124475 次浏览

简短的回答: 你不能。

长话短说: 在聚合框架中,返回的字段由您生成,您可以“重命名”文档属性。

这意味着 Mongoose 无法识别您引用的文档在最终结果中是否可用。

在这种情况下,最好的办法是在查询返回后填充所需的字段。是的,这将导致两个 DB 调用,但 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;
});
});

对于最新版本的猫鼬(monose > = 3.6) ,您需要 可以,但是它需要第二个查询,并且使用的填充方式不同。在你的聚合之后,这样做:

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

更多请看 猫鼬 API猫鼬医生

编辑: 看起来在最新的 Mongoose API 中有一种新的方法可以实现这一点(参见上面的答案: https://stackoverflow.com/a/23142503/293492)

老答案在下面

可以使用类似于填充。

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

  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);
}
);

使用 $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 }
]
}

参考 $查找

enter image description here

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"
}
}
])

Popular 基本上在引擎盖下使用 $lookup。 在这种情况下,不需要第二个查询。 有关详细信息,请查看 < a href = “ https://docs.MongoDB.com/Manual/reference/Operating/lookup/”rel = “ noReferrer”> MongoDB 聚合查找

你必须用两句话,而不是一句话。

异步等待场景中,确保 等待直到填充。

const appointments = await Appointments.aggregate([...]);


await Patients.populate(appointments, {path: "patient"});


return appointments;

或(如果你想限制)

await Patients.populate(appointments, {path: "patient",  select:  {_id: 1, fullname: 1}});

我使用了查找代替,它工作得很好。

Post.aggregate([
{
$group: {
// Each `_id` must be unique, so if there are multiple
// posts with the same category, MongoDB will increment `count`.
_id: '$category',
count: { $sum: 1 }
}
},
//from: is collection name in MongoDB, localField are primary and foreign keys in Model.
{$lookup: {from: 'categories', localField: '_id', foreignField:'_id', as: 'category'}}
]).then(categoryCount => {
console.log(categoryCount);
let json = [];
categoryCount.forEach(cat => {
console.log(json);
});

我看到有很多答案,我是蒙哥布的新人,我也想分享我的答案。 我使用聚合函数和查找来填充患者。 为了便于阅读,我更改了集合和字段的名称。

希望能有帮助。

DB:

db={
"appointmentCol": [
{
_id: ObjectId("518ee0bc9be1909012000001"),
date: ISODate("2013-05-13T22:00:00Z"),
patientId: ObjectId("518ee0bc9be1909012000001")
},
{
_id: ObjectId("518ee0bc9be1909012000002"),
date: ISODate("2013-05-13T22:00:00Z"),
patientId: ObjectId("518ee0bc9be1909012000002")
},
{
_id: ObjectId("518ee0bc9be1909012000003"),
date: ISODate("2013-05-13T22:00:00Z"),
patientId: ObjectId("518ee0bc9be1909012000003")
}
],
"patientCol": [
{
"_id": ObjectId("518ee0bc9be1909012000001"),
"name": "P1"
},
{
"_id": ObjectId("518ee0bc9be1909012000002"),
"name": "P2"
},
{
"_id": ObjectId("518ee0bc9be1909012000003"),
"name": "P3"
},
    

]
}

使用查找的聚合查询:

db.appointmentCol.aggregate([
{
"$lookup": {
"from": "patientCol",
"localField": "patientId",
"foreignField": "_id",
"as": "patient"
}
}
])

产出:

[
{
"_id": ObjectId("518ee0bc9be1909012000001"),
"date": ISODate("2013-05-13T22:00:00Z"),
"patient": [
{
"_id": ObjectId("518ee0bc9be1909012000001"),
"name": "P1"
}
],
"patientId": ObjectId("518ee0bc9be1909012000001")
},
{
"_id": ObjectId("518ee0bc9be1909012000002"),
"date": ISODate("2013-05-13T22:00:00Z"),
"patient": [
{
"_id": ObjectId("518ee0bc9be1909012000002"),
"name": "P2"
}
],
"patientId": ObjectId("518ee0bc9be1909012000002")
},
{
"_id": ObjectId("518ee0bc9be1909012000003"),
"date": ISODate("2013-05-13T22:00:00Z"),
"patient": [
{
"_id": ObjectId("518ee0bc9be1909012000003"),
"name": "P3"
}
],
"patientId": ObjectId("518ee0bc9be1909012000003")
}
]

游乐场: Mongoplayground.net