Mongodb Map-Reduce 执行多重聚合

问题描述 投票:0回答:1

假设我有一个包含这种形式文档的集合:

{
    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,我知道,但我不能。

提前致谢!

mongodb mapreduce aggregate
1个回答
0
投票

这就是聚合的结果:

  1. 首先对
    id & name
    进行分组以获得总和
  2. 然后按总和降序排序
  3. 然后仅对
    id
    进行分组,该组将位于上一组中的
    $_id.id
    中,并获取 first 文档
    • 由于按降序排序,第一个文档将具有最高的总和。
  4. 然后根据需要在输出中投影字段
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"
    }
  }
])

蒙戈游乐场

© www.soinside.com 2019 - 2024. All rights reserved.