mongodb 分组聚合_MongoDB按键值对进行聚合/分组
我的數(shù)據(jù)看起來像這樣:
{
"_id" : "9aa072e4-b706-47e6-9607-1a39e904a05a",
"customerId" : "2164289-4",
"channelStatuses" : {
"FOO" : {
"status" : "done"
},
"BAR" : {
"status" : "error"
}
},
"channel" : "BAR",
}
我的聚合/組看起來像這樣:
{
"_id" : {
"customerId" : "$customerId",
"channel" : "$channel",
"status" : "$channelStatuses[$channel].status"
},
"count" : {
"$sum" : 1
}
}
所以基本上通過示例數(shù)據(jù),該組應(yīng)該給我一個(gè)分組的組:
{"customerId": "2164289-4", "channel": "BAR", "status": "error"}
但是我不能在聚合/組中使用[] -indexing.我該怎么做呢?
最佳答案 使用.aggregate()無法獲得當(dāng)前結(jié)構(gòu)所需的結(jié)果.您“可以”更改結(jié)構(gòu)以使用數(shù)組而不是命名鍵,操作實(shí)際上非常簡(jiǎn)單.
所以有一個(gè)文件,如:
{
"_id" : "9aa072e4-b706-47e6-9607-1a39e904a05a",
"customerId" : "2164289-4",
"channelStatuses" : [
{
"channel": "FOO",
"status" : "done"
},
{
"channel": "BAR",
"status" : "error"
}
],
"channel" : "BAR",
}
{ "$group": {
"_id": {
"customerId" : "$customerId",
"channel" : "$channel",
"status": {
"$arrayElemAt": [
{ "$map": {
"input": { "$filter": {
"input": "$chanelStatuses",
"as": "el",
"cond": { "$eq": [ "$$el.channel", "$channel" ] }
}},
"as": "el",
"in": "$$el.status"
}},
0
]
}
},
"count": { "$sum": 1 }
}}
較早版本的MongoDB將需要$unwind來訪問匹配的數(shù)組元素.
在MongoDB 2.6中,您仍然可以在展開之前“預(yù)過濾”數(shù)組:
[
{ "$project": {
"customerId": 1,
"channel": 1,
"status": {
"$setDifference": [
{ "$map": {
"input": "$channelStatuses",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.channel", "$channel" ] },
"$$el.status",
false
]
}
}},
[false]
]
}
}},
{ "$unwind": "$status" },
{ "$group": {
"_id": {
"customerId": "$customerId",
"channel": "$channel",
"status": "$status"
},
"count": { "$sum": 1 }
}}
]
之前的任何事情你都會(huì)在$unwind之后“過濾”:
[
{ "$unwind": "$channelStatuses" },
{ "$project": {
"customerId": 1,
"channel": 1,
"status": "$channelStatuses.status",
"same": { "$eq": [ "$channelStatuses.status", "$channel" ] }
}},
{ "$match": { "same": true } },
{ "$group": {
"_id": "$_id",
"customerId": { "$first": "$customerId" },
"channel": { "$first": "$channel" },
"status": { "$first": "$status" }
}},
{ "$group": {
"_id": {
"customerId": "$customerId",
"channel": "$channel",
"status": "$status"
},
"count": { "$sum": 1 }
}}
]
在比MongoDB 2.6更小的版本中,您還需要$project兩個(gè)字段之間的相等性測(cè)試結(jié)果,然后在單獨(dú)的階段中對(duì)結(jié)果進(jìn)行$匹配.您可能還會(huì)注意到“兩個(gè)”$group階段,因?yàn)榈谝粋€(gè)階段會(huì)在過濾器之后通過$first累加器刪除任何可能的“通道”值的重復(fù)項(xiàng).以下$group與上一個(gè)列表中的完全相同.
但是如果你不能改變結(jié)構(gòu)并且需要“靈活”匹配你不能提供每個(gè)名字的鍵,那么你必須使用mapReduce:
db.collection.mapReduce(
function() {
emit({
"customerId": this.customerId,
"channel": this.channel,
"status": this.channelStatuses[this.channel].status
},1);
},
function(key,values) {
return Array.sum(values);
},
{ "out": { "inline": 1 } }
)
你當(dāng)然可以使用那種表示法
總結(jié)
以上是生活随笔為你收集整理的mongodb 分组聚合_MongoDB按键值对进行聚合/分组的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: k8s 多租户_k8s使用rbac实现多
- 下一篇: 电销机器人价格_供应商电话销售机器人服务