根据键值进行计数聚合,使键成为mongoDB中的值

发布于 2025-01-13 07:29:26 字数 1414 浏览 0 评论 0 原文

说明:我有几个文档,我想根据 typ 进行计数,并希望制作一个 namedate_key 列表。最后我们有一个文档,它计算typ。请查看预期输出。 备注

  1. typ value是一个变量。它只会统计变量值出现的次数。
  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"]

},
]

Explanation: I have several documents, I want to count base on typ and want to make a list of name and date_key. In the end we have one document, that count the typ. please see the expected output.
Remarks

  1. typ value is a variable.it will just count the occurrence of variable value.
  2. data key contain one element, for example just date. but we need the keys as value, keys can be multiple, at the moment there are 2 keys, it can me 3 or more. see the expected output keys are showing as a list ["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"
        }
      }
    ]
  }
]

Expected OutPut

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

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

},
]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月蹉跎了容颜 2025-01-20 07:29:26

鉴于 data 字段是一个仅包含一个元素的数组,您只需使用 $unwind, $first$arrayElemAt 运算符,但会推荐最后两个运算符中的任何一个以实现最佳聚合管道操作。

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

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

从那里您需要 $group 使用 $sum 并使用 date 键列表以及 name 列表://docs.mongodb.com/manual/reference/operator/aggregation/push/" rel="nofollow noreferrer">$push

最终管道使用 $reduce$concatArrays $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

Given that the data field is an array that contains only ONE element, you just need to flatten it either by using $unwind, $first or $arrayElemAt operators but would recommend any of the last two operators for an optimal aggregation pipeline operation.

Your aggregation pipeline should have essentially 4 stages: the initial stage is to transform ($addFields pipeline) the data key into an embedded document since its design as an array is redundant as it ONLY has one element, better flatten it so that it becomes an embedded document.

The next pipeline should be another transformation operation where you use $map and $objectToArray to create a list of the date keys.

From there you need to $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.

The final pipeline uses $reduce and $concatArrays with a $cond to filter out duplicates in the date_key list produced above.

Your overall pipeline should be as follows

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文