gpt4 book ai didi

mongodb - 在 MongoDB 聚合中合并数组字段

转载 作者:IT老高 更新时间:2023-10-28 13:10:25 24 4
gpt4 key购买 nike

在使用 MongoDB 聚合框架时是否可以合并数组字段?这是我要解决的一个摘要问题:

用于聚合的示例输入文档:

{
"Category" : 1,
"Messages" : ["Msg1", "Msg2"],
"Value" : 1
},
{
"Category" : 1,
"Messages" : [],
"Value" : 10
},
{
"Category" : 1,
"Messages" : ["Msg1", "Msg3"],
"Value" : 100
},
{
"Category" : 2,
"Messages" : ["Msg4"],
"Value" : 1000
},
{
"Category" : 2,
"Messages" : ["Msg5"],
"Value" : 10000
},
{
"Category" : 3,
"Messages" : [],
"Value" : 100000
}

我们希望在总结“值(value)”并合并“消息”时按“类别”分组。我试过这个聚合管道:

{group : {
_id : "$Category",
Value : { $sum : "$Value"},
Messages : {$push : "$Messages"}
}
},
{$unwind : "$Messages"},
{$unwind : "$Messages"},
{$group : {
_id : "$_id",
Value : {$first : "$Value"},
Messages : {$addToSet : "$Messages"}
}
}

结果是:

"result" : [{
"_id" : 1,
"Value" : 111,
"Messages" : ["Msg3", "Msg2", "Msg1"]
},
{
"_id" : 2,
"Value" : 11000,
"Messages" : ["Msg5", "Msg4"]
}
]

但是,这完全错过了类别 3,因为“类别”为 3 的文档没有任何“消息”,并且它们在第二次展开时被丢弃。我们希望结果还包括以下内容:

{
"_id" : 3,
"Value" : 100000,
"Messages" : []
}

聚合框架有没有一种巧妙的方法来实现这一点?

最佳答案

如果 Messages 保证是一个数组,则可以使用以下技巧:

> db.messages.find()
{ "Category" : 1, "Messages" : [ "Msg1", "Msg2" ], "Value" : 1 }
{ "Category" : 1, "Messages" : [ ], "Value" : 10 }
{ "Category" : 1, "Messages" : [ "Msg1", "Msg3" ], "Value" : 100 }
{ "Category" : 2, "Messages" : [ "Msg4" ], "Value" : 1000 }
{ "Category" : 2, "Messages" : [ "Msg5" ], "Value" : 10000 }
{ "Category" : 3, "Messages" : [ ], "Value" : 100000 }

> var group1 = {
"$group": {
"_id": "$Category",
"Value": {
"$sum": "$Value"
},
"Messages": {
"$push": "$Messages"
}
}
};

> var project1 = {
"$project": {
"Value": 1,
"Messages": {
"$cond": [
{
"$eq": [
"$Messages",
[ [ ] ]
]
},
[ [ null ] ],
"$Messages"
]
}
}
};

> db.messages.aggregate( group1, project1 )
{ "_id" : 3, "Value" : 100000, "Messages" : [ [ null ] ] }
{ "_id" : 2, "Value" : 11000, "Messages" : [ [ "Msg4" ], [ "Msg5" ] ] }
{ "_id" : 1, "Value" : 111, "Messages" : [ [ "Msg1", "Msg2" ], [ ], [ "Msg1", "Msg3" ] ] }

现在展开两次并重新组合以获得单个 Messages 数组。

> var unwind = {"$unwind":"$Messages"};

> var group2 = {
$group: {
"_id": "$_id",
"Value": {
"$first": "$Value"
},
"Messages": {
"$addToSet": "$Messages"
}
}
};

> var project2 = {
"$project": {
"Category": "$_id",
"_id": 0,
"Value": 1,
"Messages": {
"$cond": [
{
"$eq": [
"$Messages",
[ null ]
]
},
[ ],
"$Messages"
]
}
}
};

> db.messages.aggregate(group1, project1, unwind, unwind, group2 ,project2 )
{ "Value" : 111, "Messages" : [ "Msg3", "Msg2", "Msg1" ], "Category" : 1 }
{ "Value" : 11000, "Messages" : [ "Msg5", "Msg4" ], "Category" : 2 }
{ "Value" : 100000, "Messages" : [ ], "Category" : 3 }

关于mongodb - 在 MongoDB 聚合中合并数组字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19266590/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com