假设我有一个包含这种形式文档的集合:
{
id: id1,
name: foo,
value: 64
},
{
id: id1,
name: bar,
value: 37
},
{
id: id1,
name: bar,
value: 30
},
...
我想为每个 id 获取具有最大值总和的“名称”字段。例如,在上面的示例中,输出将是:
{
id: id1,
name: bar
}
从概念上讲,它非常简单。问题是,当涉及到在 MapReduce 中应用它时,我需要首先按名称字段分组并求和,然后按“id”分组并找到最大值。问题是,如果我将 id 字段作为键发出,那么我将对所有值求和,无论它们的名称如何;如果我将 id 和 name 字段作为键发出,那么我将正确执行总和,但在“finalize”函数中,我将无法使用其余的名称值来找出最大值,所以我将只剩下总和了。
到目前为止,我还想过发出一个空对象来跟踪每个名称的总和,但我很难使其幂等、关联和交换......
我知道这可以通过 MongoDB 查询轻松完成。事实上,我确实有。但这是一项任务,我们需要在 MapReduce 中完成所有工作,并在一次迭代中完成;所以请不要告诉我应该使用 $aggregate,我知道,但我不能。
提前致谢!
这就是聚合的结果:
id & name
进行分组以获得总和id
进行分组,该组将位于上一组中的 $_id.id
中,并获取 first 文档
db.collection.aggregate([
{
$group: {
_id: {
id: "$id",
name: "$name"
},
sum: { $sum: "$value" }
}
},
{ $sort: { sum: -1 } },
{
$group: {
_id: "$_id.id",
doc: { $first: "$$ROOT" }
}
},
{
$project: {
_id: 0,
id: "$_id",
name: "$doc._id.name",
// remove this next field if you don't want the sum
sum: "$doc.sum"
}
}
])