使用Aggregation Framework将MongoDB 3.4中的数组元素连接起来

hot*_*ips 5 mongodb aggregation-framework

是)我有的 :

{ "_id" : ObjectId("577dc9d61a0b7e0a40499f90"), "equ" : 123456, "key" : "p" }
{ "_id" : ObjectId("577c789b1a0b7e0a403f1b52"), "equ" : 123456, "key" : "r" }
{ "_id" : ObjectId("577b27481a0b7e0a4033965a"), "equ" : 123456, "key" : "r" }
{ "_id" : ObjectId("5779d6111a0b7e0a40282dc7"), "equ" : 123456, "key" : "o" }
Run Code Online (Sandbox Code Playgroud)

我想要的是 :

{ "_id" : ObjectId("5779d6111a0b7e0a40282dc7"), "equ" : 123456, "keys" : "prro" }
Run Code Online (Sandbox Code Playgroud)

我尝试了什么:

db.table.aggregate([{"$group":{"_id":0, "keys":{"$push":"$key"}}}]) 返回一个数组而不是一个字符串:

{"_id":0, "keys":["p","r","r","o"]}
Run Code Online (Sandbox Code Playgroud)

你有什么主意吗?

Ali*_*ani 10

TL; DR

使用此聚合管道:

db.col.aggregate([
    {$group: {_id: "$equ", last: {$last: "$_id"}, keys: {$push: "$key"}}},
    {
        $project: {
            equ: "$_id",
            _id: "$last",
            keys: {
                $reduce: {
                    input: "$keys",
                    initialValue: "",
                    in: {$concat: ["$$value", "$$this"]}
                }
            }
        }
    }
])
Run Code Online (Sandbox Code Playgroud)

更多细节

首先,你应该基础上的文件equ值也保持按键的排列与沿_id中的最后一个组成员:

var groupByEqu = {
    $group: {
        _id: "$equ",
        last: {$last: "$_id"},
        keys: {$push: "$key"}
    }
}
Run Code Online (Sandbox Code Playgroud)

仅应用此管道操作将导致:

{ 
    "_id" : 123456, 
    "last" : ObjectId("5779d6111a0b7e0a40282dc7"), 
    "keys" : [ "p", "r", "r", "o" ] 
}
Run Code Online (Sandbox Code Playgroud)

您应该使用Projection将前面的文档转换为您想要的文档.前两个转换是微不足道的.要加入数组元素,您可以使用new $reduce运算符:

var project = {
    $project: {
        equ: "$_id",
        _id: "$last",
        keys: {
            $reduce: {
                input: "$keys",
                initialValue: "",
                in: {$concat: ["$$value", "$$this"]}
            }
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)

应用这两个管道操作将为您提供所需的结果:

db.col.aggregate([groupByEqu, project])
Run Code Online (Sandbox Code Playgroud)

这是:

{ 
    "equ" : 123456, 
    "_id" : ObjectId("5779d6111a0b7e0a40282dc7"), 
    "keys" : "prro"
}
Run Code Online (Sandbox Code Playgroud)