0

想象我有一个这样的集合:

{
  "_id": "10280",
  "city": "NEW YORK",
  "state": "NY",
  "departments": [
             {"departmentType":"01",
              "departmentHead":"Peter"},
             {"departmentType":"02",
              "departmentHead":"John"}
  ]
},
{
  "_id": "10281",
  "city": "LOS ANGELES",
  "state": "CA",
  "departments": [
             {"departmentType":"02",
              "departmentHead":"Joan"},
             {"departmentType":"03",
              "departmentHead":"Mary"}
  ]
},
{
  "_id": "10284",
  "city": "MIAMI",
  "state": "FL",
  "department": [
  "departments": [
             {"departmentType":"01",
              "departmentHead":"George"},
             {"departmentType":"02",
              "departmentHead":"Harry"}
  ]
}

我想获得每个部门类型的计数,例如:

[{"departmentType":"01", "dCount":2},
 {"departmentType":"02", "dCount":3},
 {"departmentType":"03", "dCount":1}
]

为此,我已经尝试了几乎所有方法,但是我在网上找到的所有示例都比较简单,其中 group by 是在文档根级别的字段上完成的。相反,我在这里尝试按部门类型进行分组,这似乎破坏了我迄今为止发现的所有内容。

关于如何使用 Mongoose 的聚合实现或 mapreduce 来做到这一点的任何想法?

理想情况下,我想排除所有 count <= 1 的部门类型,并按部门类型对结果进行排序。

谢谢大家!

4

1 回答 1

0

您需要 $unwind 部门数组,该数组将为数组中的每个条目创建一个文档,以便您可以在管道中聚合它们。

不幸的是,您不能预先过滤 departmentTypes <= 1,因为 $size 只会采用精确值,但您可以将其从结果中过滤掉。这不是很好,但它有效。此示例仅预过滤具有 EXACTLY 2 个部门的记录,但仅用于演示,您可能希望删除第一个 $match,因为我们稍后会过滤掉 <=1 和第二个 $match 的结果;

db.runCommand({
    aggregate: "so",
    pipeline: [
        {   // filter out only records with 2 departments
            $match: {
                departments: { $size: 2 }
            }
        },
        // unwind - create a doc for each department in the array
        { $unwind: "$departments" },
        {   // aggregate sum of departments by type
            $group: {
                _id: "$departments.departmentType",
                count: { $sum: 1 },
            }
        },
        {   // filter out departments with <=1
            $match: {
                count: { $gt: 1 },
            }
        },
        {   // rename fields as per example
            $project: {
                _id: 0,
                departmentType: "$_id",
                dCount: "$count",
            }
        }
    ]
});

请注意,我还假设您之前的 json 示例有错字,并且“部门”实际上并不存在。假设所有文档都具有与前两个相同的架构,则此代码将起作用。

如果您不关心获得的实际字段名称,请随意删除第一个 $match 和最后一个 $project。

于 2012-10-05T21:22:03.717 回答