汇总嵌入式文档数组

时间:2018-12-19 21:34:08

标签: mongodb aggregation-framework

我有一个包含多个文档的mongodb集合。每个文档都有一个包含多个子文档的数组(我猜是嵌入式文档还是?)。这些子文档均采用以下格式:

{
    "name": string,
    "count": integer
}

现在我想汇总这些子文档以查找

  1. 排名靠前的X计数及其名称。
  2. 与1相同。但是名称必须在排序和限制前匹配一个正则表达式。

我已经为1.尝试过以下操作-它确实返回了我的前X个,但没有排序,所以我不得不再次订购它们,这似乎效率不高。

[{
    $match: {
        _id: id
}
}, {
    $unwind: {
        path: "$array"
    }
}, {
    $sort: {
        'count': -1
    }
}, {
    $limit: x
}]

由于我是mongodb的新手,所以这对我来说很混乱。很高兴获得任何帮助。预先感谢。

1 个答案:

答案 0 :(得分:1)

排序必须包含数组名称,以避免以后再进行其他排序。

给出以下文档以供使用:

    {
      students: [{
        count: 4,
        name: "Ann"
      }, {
        count: 7,
        name: "Brad"
      }, {
        count: 6,
        name: "Beth"
      }, {
        count: 8,
        name: "Catherine"
      }]
    }

作为示例,以下聚合查询将匹配包含字母“ h”和“ e”的任何名称。这需要在“ $ unwind”步骤之后发生,以便仅保留您需要的内容。

    db.tests.aggregate([
      {$match: {
        _id: ObjectId("5c1b191b251d9663f4e3ce65")
      }},
      {$unwind: {
        path: "$students"
      }},
      {$match: {
        "students.name": /[he]/
      }},
      {$sort: {
        "students.count": -1
      }},
      {$limit: 2}
    ])

这是给定上述输入的输出:

    { "_id" : ObjectId("5c1b191b251d9663f4e3ce65"), "students" : { "count" : 8, "name" : "Catherine" } }
    { "_id" : ObjectId("5c1b191b251d9663f4e3ce65"), "students" : { "count" : 6, "name" : "Beth" } }

两个名称都包含字母“ h”和“ e”,并且输出从高到低排序。

将限制设置为1时,输出限制为:

    { "_id" : ObjectId("5c1b191b251d9663f4e3ce65"), "students" : { "count" : 8, "name" : "Catherine" } }

在这种情况下,匹配名称后只保留最高的计数。

===================== 编辑额外的问题:

是的,可以更改第一个$ match以对特定大学进行过滤。

      {$match: {
        university: "University X"
      }},

这将给出一个或多个匹配的文档(如果您每年有一个文档),其余的汇总步骤仍然有效。

接下来的比赛将在给定的学年中检索给定大学的学生,以备不时之需。

      {$match: {
        university: "University X",
        academic_year: "2018-2019"
      }},

那应该缩小范围以获取正确的文档。