在嵌套结构(集合)上具有条件的Mongo查询

时间:2018-10-02 11:48:56

标签: python database mongodb

我有一个nested fields这样的收藏集:

student: {
name: banana,
meetings: [
{grade: AW, key1, group: A, time: ISODate("2018-09-25T14:08:00.729+0000")},
{grade: AW, key2, group: A, time: ISODate("2018-09-24T14:08:00.729+0000")},
{grade: BC, key2, group: B, time: ISODate("2018-09-25T14:08:00.729+0000")},
{grade: BC, key3, group: B, time: ISODate("2018-09-24T14:08:00.729+0000")},
{grade: BD, key4, group: D, time: ISODate("2018-09-25T14:08:00.729+0000")}
  ]
}

如果meeting在[']中,则想为每个name领取,latest grade及其 group 信息。 A”,“ B”,“ C”]。 例如,我想要得到的这个收藏集:

student: {
name: banana,
meetings: [
{grade: AW, key1, group: A, time: ISODate("2018-09-25T14:08:00.729+0000")},
{grade: BC, key2, group: B, time: ISODate("2018-09-25T14:08:00.729+0000")}
  ]
}

似乎使用unwind和$group是潜在的解决方案。但是,该集合非常huge,这使得$group甚至不可能。谁能给我一些提示吗?谢谢。

2 个答案:

答案 0 :(得分:0)

由于这来自huge collection,因此group方法将触发memory问题。因此,我尝试使用以下查询,并在post processing中使用一些python来获取结果。如果您有更好的建议,请告诉我。谢谢:)

db.getCollection("***").aggregate([
{$unwind: {path: '$meetings'}},
{$match: 
  {
    'time':{$gte: new ISODate("2018-10-01T00:00:00Z")} , 
    'group': {$in: ['A','B']} ,
    'meetings.time':{$gte: new ISODate("2018-10-01T00:00:00Z")}
  }
},
{$addFields: {
    "_id": "$_id",
    "grade": "$meetings.grade",
    "time": "$meetings.time"
}},
{$project: { "_id": 1, "grade": 1}}
]);

答案 1 :(得分:0)

您可以在$filter中使用$project

db.getCollection('students').aggregate([
{ 
  $project : 
  {
     'student.name' : 1,
    'student.meetings' : {
      $filter: {
        input: "$student.meetings",
        as: "item",
        cond: { $in: [ "$$item.group", ["A","B"] ]}
      }
    }
  } 
  }])

注意:已在MongoDb GUI Robo3T

中进行了测试