这是我的预约系列:
{ _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
....
换句话说,我可以在同一个语句中使用populate和aggregate
任何帮助,请
答案 0 :(得分:63)
使用最新版本的mongoose(mongoose> = 3.6),可以,但它需要第二个查询,并使用不同的填充。聚合后,请执行以下操作:
Patients.populate(result, {path: "patient"}, callback);
点击Mongoose API和Mongoose docs了解详情。
答案 1 :(得分:30)
您可以使用与填充类似的$ lookup。
在一个不相关的例子中,我使用$ 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);
}
);
答案 2 :(得分:9)
简答: 你不能。
答案很长: 在聚合框架中,返回的字段由您构建,您可以“重命名”文档属性。
这意味着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;
});
});
答案 3 :(得分:9)
使用$ lookup执行加入
收集订单包含以下文件:
{ "_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 }
订单集合的以下聚合操作使用orders集合中的字段项和库存集合中的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 }
]
}
答案 4 :(得分:6)
您可以在一个查询中执行此操作:
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"
}
}
])
populate基本上使用引擎盖下的$ lookup。 在这种情况下,不需要第二个查询。 有关详情,请查看MongoDB aggregation lookup
答案 5 :(得分:2)
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 }
答案 6 :(得分:2)
您必须分两次而不是一次声明。
在 异步等待 方案中,确保等待直到填充。
const appointments = await Appointments.aggregate([...]);
await Patients.populate(appointments, {path: "patient"});
return appointments;
或(如果您想限制)
await Patients.populate(appointments, {path: "patient", select: {_id: 1, fullname: 1}});
答案 7 :(得分:0)
我改用了查找,而且效果很好。请参阅下面截取的代码。
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);
});