MongoDB aggregate/find 将数组合并为单独的命名元素

MongoDB aggregate/find consolidate array into seperate named elements

我有一个包含文档数组的文档,我需要将这些文档合并为 1 个平面文档,并根据数组记录编号命名。

例如

{
'Name': 'Barry'
'Cars': [{
           'Model': 'Clio'
           'Reg':'WY99 XFT'
         }
         {
           'Model': 'Punto'
           'Reg': 'XX01 SDF'
         }]
}

{
'Name': 'Barry'
'Reg1': 'WY99 XFT'
'Reg2': 'XX01 SDF'
}

这甚至可以使用 Mongoshell 和聚合函数吗? 我尝试了 $unwind/$group 的变体,但我似乎无法获得元素编号。 JSON 可以有 N 辆汽车。

您可以尝试通过迭代集合的 find() cursor using the forEach() method where you convert the Cars array into an object that you can add to the flattened object. The conversion can be made possible through the use of JavaScript native methods like Object.getOwnPropertyNames() and Array.prototype.reduce() 来创建一个新对象。下面的 mongo shell 操作演示了这个概念:

var flattened = [];

db.collection.find().forEach(function(doc) {
    var newRegObject = Object.getOwnPropertyNames(doc.Cars).reduce(function(o, v, i) {
        if (i < doc.Cars.length) o["Reg" + i] = doc.Cars[i].Reg;
        return o;
    }, {});
    newRegObject["Name"] = doc.Name;
    flattened.push(newRegObject);
})


printjson(flattened);

你基本上可以使用 $map:

db.collection.aggregate([
    { "$project": {
        "Name": 1,
        "Regs": { 
            "$map": {
                "input": "$Cars",
                "as": "car",
                "in": "$$car.Reg"
             }
        }
    }}
])

这将产生:

{
    "Name": "Barry",
    "Regs": [
        "WY99 XFT",
        "XX01 SDF"
    ]
}

您 "can" 使用聚合框架运算符做的事情。

但是无法按照您的建议在输出中将 "arbitrary names" 赋给 "keys"。

所以我建议坚持做可能的事情,或者在代码中做你想做的事情。

  1. db.so.aggregate([{"$project":{"_id":0,"Name":1,"Reg1":"$Cars.Reg"}}]) will Produce { "Name" : "Barry", "Reg1" : [ "WY99 XFT", "XX01 SDF" ] }

  2. db.so.aggregate([{"$project":{"_id":0,"Name":1,"Reg1":"$Cars.Reg"}},{"$unwind" :"$Reg1"}]) Will Produce { "Name" : "Barry", "Reg1" : "WY99 XFT" } { "Name" : "Barry", "Reg1" : "XX01 SDF" }