将数组转换为新字段,将键作为这个数组的值,将值作为这些项目的频率(聚合框架)。

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

我有这个问题,但我不能解决。我必须转换数组 s 的新字段,称为 shares. 这个新字段里面有新的键和新的值。假设我有这些文件。

{
  'name': 'igor',
  's': ['a', 'a', 'a', 'b', 'b']
},
{
  'name': 'jones',
  's': ['c', 'b']
}

预期输出:

{
  'name': 'igor',
  'shares': {
     'a': 3
     'b': 2
  }
},
{
  'name': 'jones',
  'shares': {
     'c': 1
     'b': 1
  }
}
arrays mongodb aggregation-framework
1个回答
2
投票

你可以试试下面的聚合查询。

db.collection.aggregate([
    /** unwind `s` array */
    {
      $unwind: "$s"
    },
    /** group on unique pairs of `_id + s` & retain name field, count sum of matching docs */
    {
      $group: { _id: { k: "$s", _id: "$_id" }, name: { $first: "$name" }, v: { $sum: 1 } }
    },
    /** group on unique pairs of just `_id` & retain name field, push docs into shares array `[{k :..., v:...}]` */
    {
      $group: { _id: "$_id._id", name: { $first: "$name" }, shares: { $push: { k: "$_id.k", v: "$v" } } }
    },
    /** Re-create shares field from array to object */
    {
      $addFields: { shares: { $arrayToObject: "$shares" } }
    }
  ])

测试: mongoplayground


0
投票

在一个数组中添加异构元素(在你的例子中。'a': 3, 'b': 2)到一个数组中,我将 shares'的类型改为类似。

{
    key: "$_id.shares",
    count: "$count"
}

你需要按顺序执行以下操作

  1. 解开数组 s.
  2. 按综合_ids分组 names.
  3. 再次按_id分组 _id.name 和推送类型的对象 keycountshares 数组。

你可以尝试下面的查询。

db.collection.aggregate([
  {
    $unwind: "$s"
  },
  {
    $group: {
      _id: {
        name: "$name",
        shares: "$s"
      },
      count: {
        $sum: 1
      }
    }
  },
  {
    $group: {
      _id: "$_id.name",
      shares: {
        $push: {
          key: "$_id.shares",
          count: "$count"
        }
      }
    }
  }
])

输出

[
  {
    "_id": "jones",
    "shares": [
      {
        "count": 1,
        "key": "c"
      },
      {
        "count": 1,
        "key": "b"
      }
    ]
  },
  {
    "_id": "igor",
    "shares": [
      {
        "count": 3,
        "key": "a"
      },
      {
        "count": 2,
        "key": "b"
      }
    ]
  }
]

梦之城娱乐平台链接

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