使用聚合框架对MongoDB进行组计数

假设我的MongoDB模式如下所示:

{car_id: "...", owner_id: "..."} 

这是一个多对多的关系。 例如,数据可能如下所示:

 +-----+----------+--------+ | _id | owner_id | car_id | +-----+----------+--------+ | 1 | 1 | 1 | | 2 | 1 | 2 | | 3 | 1 | 3 | | 4 | 2 | 1 | | 5 | 2 | 2 | | 6 | 3 | 4 | | 7 | 3 | 5 | | 8 | 3 | 6 | | 9 | 3 | 7 | | 10 | 1 | 1 | <-- not unique +-----+----------+--------+ 

我想得到每个车主拥有的汽车数量。 在SQL中,这可能看起来像:

 SELECT owner_id, COUNT(*) AS cars_owned FROM (SELECT owner_id FROM car_owners GROUP BY owner_id, car_id) AS t GROUP BY owner_id; 

在这种情况下,结果如下所示:

 +----------+------------+ | owner_id | cars_owned | +----------+------------+ | 1 | 3 | | 2 | 2 | | 3 | 4 | +----------+------------+ 

如何使用聚合框架使用MongoDB来完成同样的事情?

为了适应潜在的重复,你需要使用两个$group操作:

 db.test.aggregate([ { $group: { _id: { owner_id: '$owner_id', car_id: '$car_id' } }}, { $group: { _id: '$_id.owner_id', cars_owned: { $sum: 1 } }}, { $project: { _id: 0, owner_id: '$_id', cars_owned: 1 }}] , function(err, result){ console.log(result); } ); 

给出一个格式为:

 [ { cars_owned: 2, owner_id: 10 }, { cars_owned: 1, owner_id: 11 } ] 

$group通过命令与SQL Group类似。 在下面的例子中,我们将根据创build年份来累计公司。 并计算每个公司的平均雇员人数。

 db.companies.aggregate([{ $group: { _id: { founded_year: "$founded_year" }, average_number_of_employees: { $avg: "$number_of_employees" } } }, { $sort: { average_number_of_employees: -1 } } ]) 

$平均运算符MongoDB

这个聚合pipe道有两个阶段

  1. $group
  2. $sort

现在, $group阶段的基础是我们指定为文档部分的_id字段。 这是$group操作符本身对arrogation框架语法的非常严格的解释。 _id是我们如何定义,如何控制,如何调整小组阶段用来组织它所看到的文档。

下面的查询find使用$sum操作符的公司人员与公司的关系:

 db.companies.aggregate([{ $match: { "relationships.person": { $ne: null } } }, { $project: { relationships: 1, _id: 0 } }, { $unwind: "$relationships" }, { $group: { _id: "$relationships.person", count: { $sum: 1 } } }, { $sort: { count: -1 } }]) 

$ sum在MongoDB中