根据键值计算聚合并使键成为 mongoDB 中的值

count aggregation base on key value and make keys become values in mongoDB

说明:我有几份文件,我想根据typ统计,并想列出namedate_key。最后我们有 一个文档 ,即 typ。请查看预期输出。 备注

  1. typ value is a variable.it 将只计算变量值的出现次数。
  2. data 键包含一个元素,例如只有日期。但是我们需要键作为值,键可以是多个,目前有2个键,我可以有3个或更多。看到预期的输出键显示为列表 ["el1", "el2]
[
  {
    "typ": "ABC",
    "data": [
      {
        "name": "XYZ",
        "in_data": {
          "date": {
            "el2": "2015-01-10",
            "el1": "2014-01-10"
          },
          "version" : "0.22",
          "model" : "2015"

        }
      }
    ]
  },
  {
    "typ": "ABC",
    "data": [
      {
        "name": "LMNO",
        "in_data": {
          "date": {
            "el2": "2015-01-10",
            "el1": "2014-01-10"
          },
          "version" : "0.22",
          "model" : "2014"
        }
      }
    ]
  },
{
    "typ": "EDC",
    "data": [
      {
        "name": "QWERTY",
        "in_data": {
          "date": {
            "el3": "2015-01-10",
            "el4": "2014-01-10"
          },
          "version" : "0.52",
          "model" : "2010"
        }
      }
    ]
  }
]

预期输出

[
{
    "typ_count" : 2,
    "name" : ["XYZ", "LLMNO"],
    "date_key" : ["el1", "el2"]

},
{
    "typ_count" : 1,
    "name" : ["QWERTY"],
    "date_key" : ["el3", "el4"]

},
]

鉴于 data 字段是一个仅包含一个元素的数组,您只需使用 $unwind, $first or $arrayElemAt 运算符将其展平,但建议使用最后两个运算符中的任何一个以获得最佳效果聚合管道操作。

您的聚合管道基本上应该有 4 个阶段:初始阶段是将 data 键转换($addFields 管道)到嵌入式文档中,因为它作为数组的设计是多余的,因为它 只有有一个元素,最好把它压平,这样它就变成了嵌入文档。

下一个管道应该是另一个转换操作,您可以在其中使用 $map and $objectToArray 创建 date 键的列表。

从那里你需要$group the documents to aggregate the typ_count using $sum and create another list of the date keys along with the name list using $push

最终管道使用 $reduce and $concatArrays with a $cond 过滤掉上面生成的 date_key 列表中的重复项。

你的整体流水线应该如下

db.collection.aggregate([
    { $addFields: {
        data: { $arrayElemAt: ['$data', 0] } // OR data: { $first: '$data' }
    } },
    { $addFields: {
        name: '$data.name',
        date_key: {
            $map: {
                input: { $objectToArray: '$data.in_data.date' },
                in: '$$this.k'
            }
        }
    } },
    { $group: {
        _id: '$typ',
        typ_count: { $sum: 1 },
        name: { $push: '$name' },
        date_key: { $push: '$date_key' }
    } },
    { $project: {
       _id: 0,
        typ_count: 1,
        name: 1,
        date_key: {
            $reduce: {
                input: '$date_key',
                initialValue: [],
                in: { 
                    $concatArrays: [ 
                        '$$value', 
                        {
                            $cond: [
                                { $in: ["$$this", ["$$value"]] },
                                [], 
                                "$$this"
                            ]
                        } 
                    ]  
                }                
            }
        }
    } }
])

Mongo Playground