考虑一下这组测试结果:
[{
_id: ObjectId(...),
name: "Test1",
acts: [
{
name: "act1",
tests: [
{name: "test1", result: true},
{name: "test2", result: true}]
}]
},
{
_id: ObjectId(...),
name: "Test2",
acts: [
{
name: "act1",
tests: [
{name: "test1", result: true},
{name: "test2", result: false}]
},
{
name: "act2",
tests: [
{name: "test3", result: true}]
}]
}]
我正在尝试使用聚合来创建一个计算字段,其中包含所有测试结果的总和,我想要这样的东西:
[{
_id: ObjectId(...),
name: "Test1",
result: true, //new aggregated value
acts: [
{
name: "act1",
result: true, //new aggregated value
tests: [
{name: "test1", result: true},
{name: "test2", result: true}]
}]
},
{
_id: ObjectId(...),
name: "Test2",
result: false, //new aggregated value
acts: [
{
name: "act1",
result: false, //new aggregated value
tests: [
{name: "test1", result: true},
{name: "test2", result: false}]
},
{
name: "act2",
result: true, //new aggregated value
tests: [
{name: "test3", result: true}]
}]
}]
我尝试过使用aggregate和$ unwind,$ project和$ group:
aggregate([
{$unwind: "$acts"},
{$unwind: "$acts.tests"},
{$project: {name: 1, acts: 1, failed: {$cond: {if: {$eq: ["$acts.tests.test", "true" ]}, then: 0, else: 1}}}},
{$group: {_id: "$_id", failedCount: {$sum: "$failed"}, acts: {$push: "$acts.tests"}}}
])
但我不能让它反转$ unwind操作,我只得到结果数据结构与原始数据结构不同 . 是否可以使结果看起来与原始集合完全相同但具有新的聚合值?
/ gemigspam
1 回答
如何处理这个问题有一个特殊的技巧,但首先如果你有MongoDB 2.6或更高版本,那么你可以实际做你想做的事情而不用$unwind . 如果您要处理大量文档,这对于性能非常方便 .
这里的关键操作符是$map,它处理数组到位,$allElementsTrue运算符将评估你的"result"字段 . 这里使用"map"允许测试内部"tests"数组,以查看其中"result"字段的所有字符都满足真实条件 . 在外部数组的情况下,可以根据需要将"result"放入这些文档中,当然,对文档的完整评估遵循相同的规则:
在早期版本中执行此操作的方法要求您在两个步骤中返回$group,以便在再次对这些"result"字段进行测试时_1192461_数组 . 这里的另一个区别也是使用$min运算符,因为
false
将被视为比true
更小的值并且计算为相同的"allElements"概念: