MongoDB:如何在聚合阶段分组时计算数组中的不同值

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

我有一个聚合管道,我试图在其中查找数组属性中的唯一值以及每个文档数组中每个值的实例数。

我到达了文档如下所示的阶段:

{
    _id: ObjectId("5d8cac657d2d1e0145268fb4"),
    values: [
        "5d8a2c3d4768d9660d3ba383",
        "5d8a1d4f4768d951cb6c8989"
    ]
},
{
    _id: ObjectId("5d8caf4039321e7b14061a46"),
    values: [
        "5d8a2c3d4768d9660d3ba383",
        "5d8c835a39321e7b15792353"
    ]
}

从这里我希望得到如下结果:

{
    values: {
        "5d8a2c3d4768d9660d3ba383": 2,
        "5d8a1d4f4768d951cb6c8989": 1,
        "5d8c835a39321e7b15792353" : 1
    }  
}

or 

{
    values: [
        { "id": "5d8a2c3d4768d9660d3ba383", "count" : 2 },
        { "id": "5d8a1d4f4768d951cb6c8989", "count" : 1 },
        { "id": "5d8c835a39321e7b15792353", "count" : 1 }
    ]
}

我不太关心结果的格式,只要我有唯一的值和它们的计数,我就可以使用它 - 无论最高效的方法是什么都可以。我可以通过使用带有 $push 和 $reduce 的 $group 阶段来获取唯一值,但我无法以这种方式获取计数 - 有人可以指出我正确的方向吗?

mongodb aggregation-framework
1个回答
0
投票

如果您想要第一个选项,您可以尝试以下查询:

  • 首先
    $unwind
    数组
    values
    能够单独获取每个元素。
  • 然后
    $group
    获取每个元素的计数。
  • 再次重新分组,但使用
    _id
    作为
    null
    将所有值放入一个数组中。这里的每个元素都是一个具有
    k
    v
    属性的对象。这将在下一阶段使用。
  • 最后一个阶段是
    $project
    ,不输出
    _id
    值(位于
    null
    中)并使用$arrayToObject。在上一阶段使用
    k
    v
    创建了一个数组,其中的对象可有效转换为所需的对象。
db.collection.aggregate([
  {
    "$unwind": "$values"
  },
  {
    "$group": {
      "_id": "$values",
      "count": {
        "$sum": 1
      }
    }
  },
  {
    "$group": {
      "_id": null,
      "values": {
        "$push": {
          "k": "$_id",
          "v": "$count"
        }
      }
    }
  },
  {
    "$project": {
      "_id": 0,
      "values": {
        "$arrayToObject": "$values"
      }
    }
  }
])

示例这里

对于第二个选项,您可以尝试以下查询:

  • 步骤与之前相同。
  • 这里的重新分组是使用
    $$ROOT
    来获取整个对象。由于这里不需要任何其他内容,您可以按原样设置对象。
  • 最后阶段只是
    $project
    ,不输出
    _id
    值。
db.collection.aggregate([
  {
    "$unwind": "$values"
  },
  {
    "$group": {
      "_id": "$values",
      "count": {
        "$sum": 1
      }
    }
  },
  {
    "$group": {
      "_id": null,
      "values": {
        "$push": "$$ROOT"
      }
    }
  },
  {
    "$project": {
      "_id": 0
    }
  }
])

示例这里

编辑:我没有注意到第二个例子有

id
而不是
_id
。如果相关,您可以使用 this query 代替,这是相同的,但不是使用
$$ROOT
来设置整个对象,而是创建
id/count
对象。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.