MongoDB:就地对嵌套数组的元素进行分组

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

想知道如何使用聚合管道按

procedures
就地对
type
数组进行分组。

所以转动这个:

[
    {
        "airport": "MSP",
        "country": "USA",
        "procedures": [
            {
                "name": "ABC1",
                "type": "DEP"
            },
            {
                "name": "JKL2",
                "type": "ARR"
            },
            {
                "name": "LMN3",
                "type": "DEP"
            },
            {
                "name": "PQR4",
                "type": "ARR"
            }
        ]
    },
    {
        "airport": "CMH",
        "country": "USA",
        "procedures": [
            {
                "name": "GHI4",
                "type": "ARR"
            },
            {
                "name": "RST3",
                "type": "ARR"
            },
            {
                "name": "TUV7",
                "type": "DEP"
            },
            {
                "name": "XYZ4",
                "type": "ARR"
            }
        ]
    }
]

进入这个:

[
    {
        "airport": "MSP",
        "country": "USA",
        "procedures": {
            "ARR": [
                {
                    "name": "JKL2",
                    "type": "ARR"
                },
                {
                    "name": "PQR4",
                    "type": "ARR"
                }
            ],
            "DEP": [
                {
                    "name": "ABC1",
                    "type": "DEP"
                },
                {
                    "name": "LMN3",
                    "type": "DEP"
                },
            ]
        }
    },
    {
        "airport": "CMH",
        "country": "USA",
        "procedures": {
            "ARR": [
                {
                    "name": "GHI4",
                    "type": "ARR"
                },
                {
                    "name": "RST3",
                    "type": "ARR"
                },

                {
                    "name": "XYZ4",
                    "type": "ARR"
                }
            ],
            "DEP": [
                {
                    "name": "TUV7",
                    "type": "DEP"
                }
            ]
        }
    }
]

我已经做到了

db.collection.aggregate([
  {
    "$unwind": "$procedures"
  },
  {
    "$group": {
      _id: "$procedures.type",
      procedures: {
        $push: "$procedures"
      }
    }
  }
])

但它丢失了

airport
结构并将数据混合在一起:

[
  {
    "_id": "DEP",
    "procedures": [
      {
        "name": "ABC1",
        "type": "DEP"
      },
      {
        "name": "LMN3",
        "type": "DEP"
      },
      {
        "name": "TUV7",
        "type": "DEP"
      }
    ]
  },
  {
    "_id": "ARR",
    "procedures": [
      {
        "name": "JKL2",
        "type": "ARR"
      },
      {
        "name": "PQR4",
        "type": "ARR"
      },
      {
        "name": "GHI4",
        "type": "ARR"
      },
      {
        "name": "RST3",
        "type": "ARR"
      },
      {
        "name": "XYZ4",
        "type": "ARR"
      }
    ]
  }
]
mongodb aggregation-framework
1个回答
0
投票
  1. 第二阶段:

    $group
    ,由
    airport
    和 procedure.type`.

  2. 第三阶段:

    $group
    by
    airport
    ,将具有
    k
    v
    字段的对象添加到
    procedures
    数组中。

  3. 最后阶段:

    $project
    ,通过
    procedures
    运算符将
    $arrayToObject
    数组转换为键值对来装饰输出文档。

db.collection.aggregate([
  {
    "$unwind": "$procedures"
  },
  {
    "$group": {
      _id: {
        type: "$procedures.type",
        airport: "$airport"
      },
      country: {
        $first: "$country"
      },
      procedures: {
        $push: "$procedures"
      }
    }
  },
  {
    "$group": {
      _id: "$_id.airport",
      country: {
        $first: "$country"
      },
      procedures: {
        $push: {
          k: "$_id.type",
          v: "$procedures"
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      airport: "$_id",
      country: "$country",
      procedures: {
        $arrayToObject: "$procedures"
      }
    }
  }
])

演示@Mongo Playground

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