我是MongoDB聚合的新手。
我的数据库具有以下结构:
{
"_id": "AAABBBCCCDDDD",
"report":{
"google": [{
"report_id": "XXX",
"detail": [{
"available": true,
"status_code": 200,
"return_code": "ok",
}, {
"available": true,
"status_code": 300,
"return_code": "ok",
}, {
"available": true,
"status_code": 400,
"return_code": "ok",
}]
}, {
"report_id": "YYY",
"detail": [{
"available": false,
"status_code": 200,
"return_code": "ok",
}, {
"available": true,
"status_code": 200,
"return_code": "ng",
}, {
"available": true,
"status_code": 200,
"return_code": "ok",
}]
}]
}
}
我想要压扁这样的文件:
{
"AAABBBCCCDDDD": [{
"report_id": "XXX",
"detail": [{
"available": true,
"status_code": 200,
"return_code": "ok",
}, {
"available": true,
"status_code": 300,
"return_code": "ok",
}, {
"available": true,
"status_code": 400,
"return_code": "ok",
}]
}, {
"report_id": "YYY",
"detail": [{
"available": false,
"status_code": 200,
"return_code": "ok",
}, {
"available": true,
"status_code": 200,
"return_code": "ng",
}, {
"available": true,
"status_code": 200,
"return_code": "ok",
}]
}]
}
然后计算匹配的available is true
和return_code is "ok"
的数量,返回这样的结构:
{
"AAABBBCCCDDDD": [{
"report_id": "XXX",
"available_count": 3,
},
{
"report_id": "YYY",
"available_count": 1,
}]
}
有没有这样做?
答案 0 :(得分:1)
使用现代MongoDB 3.4,您可以使用$replaceRoot
和$arrayToObject
执行此操作:
db.collection.aggregate([
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$concatArrays": [
[
{
"k": "$_id",
"v": {
"$map": {
"input": "$report.google",
"as": "el",
"in": {
"report_id": "$$el.report_id",
"available_count": {
"$size": {
"$filter": {
"input": "$$el.detail",
"as": "d",
"cond": {
"$and": [
"$$d.available",
{ "$eq": [ "$$d.return_code", "ok" ] }
]
}
}
}
}
}
}
}
}
]
]
}
}
}}
])
但是你可以在任何带有少量客户端代码的版本中执行此操作:
db.collection.find().forEach(doc => {
doc[doc._id] = doc.report.google.map(el => {
el.available_count = el.detail.filter(d => d.available && d.return_code === "ok").length;
delete el.detail;
return el;
});
delete doc._id;
delete doc.report;
printjson(doc);
})
两者产生相同的东西:
{
"AAABBBCCCDDDD" : [
{
"report_id" : "XXX",
"available_count" : 3
},
{
"report_id" : "YYY",
"available_count" : 1
}
]
}
所以你根本不需要聚合,因为它只是真正重塑文档。
{
"_id": "AAABBBCCCDDDD",
"report":{
"google": [{
"report_id": "XXX",
"detail": [{
"available": true,
"status_code": 200,
"return_code": "ok",
}, {
"available": true,
"status_code": 300,
"return_code": "ok",
}, {
"available": true,
"status_code": 400,
"return_code": "ok",
}]
}, {
"report_id": "YYY",
"detail": [{
"available": false,
"status_code": 200,
"return_code": "ok",
}, {
"available": true,
"status_code": 200,
"return_code": "ng",
}, {
"available": true,
"status_code": 200,
"return_code": "ok",
}]
}]
}
}