[英]Multiple $unwind and $group in mongo query
mongodb 查询有点挣扎。 我的 mongo 数据库具有以下结构:
name: String
test: String
competences: [{name: String, code: String, value: Float}]
subcompetences: [{name: String, code: String, value: Float}]
我的查询如下所示:
async function getAggregatedDataForCompetences(filter, category) {
return await getCollection('competences').aggregate([
{$match: { $or: filter }},
{$unwind: "$competences" },
{$group: {
_id: "$_id",
code: { $first: "$competences.code" },
name: { $first: "$competences.name"},
avgValue: { $avg: "$competences.value" },
subcompetences: { $first: "$subcompetences"},
}
},
{$unwind: "$subcompetences" },
{$group: {
_id: "$subcompetences.code",
code: { $first: "$subcompetences.code" },
name: { $first: "$subcompetences.name"},
avgValue: { $avg: "$subcompetences.value" },
}}
]).toArray();
}
我想要做的是展开所有元素的第一个(能力)数组,将它们分组并计算每个项目的平均值。 对以下对象的子能力数组重复相同的过程。 结果,我只得到最后一个子能力数组的平均值。 你知道我怎样才能达到以下结果:
{
competences: [{name: String, code: String, avgValue: Float}],
subcompetences: [{name: String, code: String, avgValue: Float}]
}
$facet
救援——“多组”运算符。 给定这样的输入:
var r =
[
{
"_id" : 0,
"name": "N1",
"competences": [
{name: "AAA", code: "A", value: 1.1},
{name: "BBB", code: "B", value: 2.2},
{name: "CCC", code: "C", value: 3.3}
],
"subcompetences": [
{name: "DDD", code: "D", value: 4.4},
{name: "EEE", code: "E", value: 5.5},
{name: "FFF", code: "F", value: 6.6}
]
}
,{
"_id" : 1, "name": "N2",
"competences": [
{name: "AAA", code: "A", value: 9.9},
{name: "BBB", code: "B", value: 8.8},
{name: "KKK", code: "K", value: 11.11}
],
"subcompetences": [
{name: "FFF", code: "F", value: 4.9},
{name: "GGG", code: "G", value: 6.7}
]
}
];
然后$facet
将允许您“并行”进行两组。 实际上,您可以同时执行两个或更多完整的管道(有一些限制):
db.foo.aggregate([
{$facet: {
"avg_competences": [
{$unwind: "$competences"}
,{$group: {_id: "$competences.code",
name: {$first: "$competences.name"},
count: {$sum: 1},
avgval: {$avg: "$competences.value"},
}}
]
,"avg_subcompetences": [
{$unwind: "$subcompetences"}
,{$group: {_id: "$subcompetences.code",
name: {$first: "$subcompetences.name"},
count: {$sum: 1},
avgval: {$avg: "$subcompetences.value"},
}}
]
}
}
// The output of the stage above will be a *single* doc with two fields,
// avg_competence and avg_subcompetences. Let's add more fields to this doc!
,{$addFields: {N: {$reduce: {
input: {$concatArrays: ["$avg_competences","$avg_subcompetences"]},
initialValue: 0,
in:{$sum: [ "$$value", "$$this.count"]}
}}
}}
]);
产生:
{
"avg_competences" : [
{
"_id" : "K",
"name" : "KKK",
"count" : 1,
"avgval" : 11.11
},
{
"_id" : "C",
"name" : "CCC",
"count" : 1,
"avgval" : 3.3
},
{
"_id" : "B",
"name" : "BBB",
"count" : 2,
"avgval" : 5.5
},
{
"_id" : "A",
"name" : "AAA",
"count" : 2,
"avgval" : 5.5
}
],
"avg_subcompetences" : [
{
"_id" : "G",
"name" : "GGG",
"count" : 1,
"avgval" : 6.7
},
{
"_id" : "F",
"name" : "FFF",
"count" : 2,
"avgval" : 5.75
},
{
"_id" : "E",
"name" : "EEE",
"count" : 1,
"avgval" : 5.5
},
{
"_id" : "D",
"name" : "DDD",
"count" : 1,
"avgval" : 4.4
}
],
"N" : 11
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.