MongoDB 使用聚合进行数组转换

MongoDB array transformation using aggregation

如何使用 MongoDB 聚合管道展开多个数组并将它们合并为一个数组。

输入:

    "_id" : ObjectId("5d8605c9a9410a0e3ca50f12"),
    "fourWheeler" : {
        "cars" : [
            {
                "make": "Honda",
                "model": "Accord",
                "year": 2010
            },
            {
                "make": "Toyota",
                "model": "Camry",
                "year": 2012
            }
        ]
    },
    "twoWheeler" : {
        "motorBikes" : [
            {
                "make": "Suzuki",
                "model": "Hayabusa",
                "year": 2018
            },
            {
                "make": "Yamaha",
                "model": "FZ1",
                "year": 2005
            }
        ]
    }
}

我想把上面的改成下面的: *最好按年份排序。如您所见,新键 vehicles 已分配给组合数组,现有键已移至相应的数组元素。

{
    "_id" : ObjectId("5d8605c9a9410a0e3ca50f12"),
    "vehicles" : [
            {
                "make": "Honda",
                "model": "Accord",
                "year": 2010,
                "category": "fourWheeler"
            },
            {
                "make": "Toyota",
                "model": "Camry",
                "year": 2012,
                "category": "fourWheeler"
            },
            {
                "make": "Suzuki",
                "model": "Hayabusa",
                "year": 2018,
                "category": "twoWheeler"
            },
            {
                "make": "Yamaha",
                "model": "FZ1",
                "year": 2005,
                "category": "twoWheeler"
            }            
    ]
}

尝试聚合管道为:

注意:$unwind,$sort,$group 流水线阶段如果不想按年排序可以忽略

dbname.aggregate([
  {
    $project: {
      vehicles: {
        $concatArrays: [
          {
            $map: {
              input: "$fourWheeler.cars",
              as: "item",
              in: {
                "make": "$$item.make",
                "model": "$$item.model",
                "year": "$$item.year",
                "category": "fourWheeler"
              }
            }
          },
          {
            $map: {
              input: "$twoWheeler.motorBikes",
              as: "item",
              in: {
                "make": "$$item.make",
                "model": "$$item.model",
                "year": "$$item.year",
                "category": "twoWheeler"
              }
            }
          }
        ]
      }
    }
  },
  {
    $unwind: "$vehicles"
  },
  {
    $sort: {
      "vehicles.year": -1
    }
  },
  {
    $group: {
      _id: "$_id",
      vehicles: {
        $push: "$vehicles"
      }
    }
  }
])

将给出输出:

[
  {
    "_id": ObjectId("5d8605c9a9410a0e3ca50f12"),
    "vehicles": [
      {
        "category": "twoWheeler",
        "make": "Suzuki",
        "model": "Hayabusa",
        "year": 2018
      },
      {
        "category": "fourWheeler",
        "make": "Toyota",
        "model": "Camry",
        "year": 2012
      },
      {
        "category": "fourWheeler",
        "make": "Honda",
        "model": "Accord",
        "year": 2010
      },
      {
        "category": "twoWheeler",
        "make": "Yamaha",
        "model": "FZ1",
        "year": 2005
      }
    ]
  }
]

以下查询可以获得预期的输出:

db.collection.aggregate([
    {
        $addFields:{
            "fourWheeler.cars.category":"fourWheeler",
            "twoWheeler.motorBikes.category":"twoWheeler"   
        }
    },
    {
        $project:{
            "vehicles":{
                $concatArrays:["$fourWheeler.cars","$twoWheeler.motorBikes"]
            }
        }
    }
]).pretty()

数据集:

{
    "_id" : ObjectId("5d8605c9a9410a0e3ca50f12"),
    "fourWheeler" : {
        "cars" : [
            {
                "make" : "Honda",
                "model" : "Accord",
                "year" : 2010
            },
            {
                "make" : "Toyota",
                "model" : "Camry",
                "year" : 2012
            }
        ]
    },
    "twoWheeler" : {
        "motorBikes" : [
            {
                "make" : "Suzuki",
                "model" : "Hayabusa",
                "year" : 2018
            },
            {
                "make" : "Yamaha",
                "model" : "FZ1",
                "year" : 2005
            }
        ]
    }
}

输出:

{
    "_id" : ObjectId("5d8605c9a9410a0e3ca50f12"),
    "vehicles" : [
        {
            "make" : "Honda",
            "model" : "Accord",
            "year" : 2010,
            "category" : "fourWheeler"
        },
        {
            "make" : "Toyota",
            "model" : "Camry",
            "year" : 2012,
            "category" : "fourWheeler"
        },
        {
            "make" : "Suzuki",
            "model" : "Hayabusa",
            "year" : 2018,
            "category" : "twoWheeler"
        },
        {
            "make" : "Yamaha",
            "model" : "FZ1",
            "year" : 2005,
            "category" : "twoWheeler"
        }
    ]
}