是否可以创建一个aggerate,对嵌套的对象数组进行分组和计数,而无需展开它。
EG,拿这样的东西:
"things": [
{
"something": "else",
"stuff": "I don't want",
"a_thing": [
{
"thing": "a record",
"cat": "type A"
},
{
"thing": "an other record",
"cat": "type A"
},
{
"thing": "yet other record",
"cat": "type B"
},
{
"thing": "more records",
"cat": "type A"
},
{
"thing": "last record",
"cat": "type C"
}
]
}
]
结果是这样的:
"things": [{
{ "Grand_Total": 5 },
[{
"type A":
{ "sub_total": 3 },
[{
{ "thing": "a record" },
{ "thing": "an other record" },
{ "thing": "more records" }
}],
"type B":
{ "sub_total": 1 },
[{
{ "thing": "yet other record" }
}],
"type C":
{ "sub_total": 1 },
[{
{ "thing": "last record" }
}]
}]
}]
我一直在使用$project和$filter来减少一定条件下的记录,但我不确定如果没有放松阶段,分组和计数是否可行。
谢谢。
一个选项是:
- 创建一个键数组
- 收集每个密钥的
a_thing
项 - 格式化每个键的数据以匹配
$arrayToObject
- 使用
$arrayToObject
格式化答案
db.collection.aggregate([
{$set: {keys: {$setUnion: ["$a_thing.cat"]}}},
{$project: {
res: {$map: {
input: "$keys",
as: "key",
in: {
k: "$$key",
v: {$reduce: {
input: "$a_thing",
initialValue: [],
in: {$concatArrays: [
"$$value",
{$cond: [
{$eq: ["$$this.cat", "$$key"]},
[{thing: "$$this.thing"}],
[]
]}
]}
}}
}
}}
}},
{$project: {
res: {$map: {
input: "$res",
in: {k: "$$this.k", v: {sub_total: {$size: "$$this.v"}, values: "$$this.v"}}
}}
}},
{$project: {res: {"$arrayToObject": "$res"}}}
])
看看它是如何在操场上工作的例子