node.js-如何在同一条语句中使用填充和聚合?

这是我的约会集合:

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

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

任何帮助请

Nour Sammour asked 2020-07-20T05:07:28Z
7个解决方案
70 votes

使用最新版本的猫鼬(mongoose> = 3.6),您可以但需要第二次查询,并使用不同的填充方式。 汇总后,请执行以下操作:

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

有关更多信息,请访问Mongoose API和Mongoose文档。

ruffrey answered 2020-07-20T05:07:47Z
36 votes

您可以使用类似于填充的$ 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);
    }
  );
Lotus answered 2020-07-20T05:08:12Z
11 votes

您可以在一个查询中执行以下操作:

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

填充基本上在后台使用$ lookup。在这种情况下,无需第二次查询。有关更多详细信息,请检查MongoDB聚合查找

Mohammed Abo-zaid answered 2020-07-20T05:08:37Z
10 votes

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

对订单集合的以下聚合操作使用订单集合中的字段项和库存集合中的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

Libu Mathew answered 2020-07-20T05:09:18Z
9 votes

简短答案:你不能

长答案:在Aggregation Framework中,返回的字段由您构建,并且您可以“重命名”文档属性。

这意味着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;
  });
});
gustavohenke answered 2020-07-20T05:09:56Z
2 votes

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 }
Himanshu sharma answered 2020-07-20T05:10:16Z
0 votes

您必须分两次完成,而不是一次声明。

在异步等待方案中,请确保等待直到填充。

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

或(如果您想限制)

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

Vidura Adikari answered 2020-07-20T05:10:45Z
translate from https://stackoverflow.com:/questions/16680015/how-to-use-populate-and-aggregate-in-same-statement