gpt4 book ai didi

mongoDB:如何反转 $unwind

转载 作者:可可西里 更新时间:2023-11-01 09:07:07 25 4
gpt4 key购买 nike

考虑这组测试结果:

[{
_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

最佳答案

有一个特殊的技巧来处理这个问题,但首先如果你有 MongoDB 2.6 或更高版本,那么你实际上可以做你想做的事而不需要使用 $unwind。 .如果您正在处理大量文档,这对于性能来说非常方便。

这里的关键运算符是$map它处理数组和 $allElementsTrue将评估您的“结果”字段的运算符。这里使用“map”既可以测试内部的“tests”数组,也可以查看其中的“result”字段是否都满足真实条件。在外部数组的情况下,这个“结果”可以根据需要放入那些文档中,当然文档的完整评估遵循相同的规则:

db.test.aggregate([
{ "$project": {
"name": 1,
"result": {
"$allElementsTrue": {
"$map": {
"input": "$acts",
"as": "act",
"in": {
"$allElementsTrue": {
"$map": {
"input": "$$act.tests",
"as": "test",
"in": "$$test.result"
}
}
}
}
}
},
"acts": {
"$map": {
"input": "$acts",
"as": "act",
"in": {
"name": "$$act.name",
"result": {
"$allElementsTrue": {
"$map": {
"input": "$$act.tests",
"as": "test",
"in": "$$test.result"
}
}
},
"tests": "$$act.tests"
}
}
}
}}
])

在早期版本中执行此操作的方法需要您 $group分两步返回,以便在再次对这些“结果”字段进行测试时“重建”数组。这里的另一个区别也是使用 $min operator as false 将被视为比 true 更小的值,并计算出相同的“allElements”概念:

db.test.aggregate([
{ "$unwind": "$acts" },
{ "$unwind": "$acts.tests" },
{ "$group": {
"_id": {
"_id": "$_id",
"name": "$name",
"actName": "$acts.name"
},
"result": { "$min": "$acts.tests.result" },
"tests": {
"$push": {
"name": "$acts.tests.name",
"result": "$acts.tests.result"
}
}
}},
{ "$group": {
"_id": "$_id._id",
"name": { "$first": "$_id.name" },
"result": { "$min": "$result" },
"acts": {
"$push": {
"name": "$_id.actName",
"result": "$result",
"tests": "$tests"
}
}
}}
])

关于mongoDB:如何反转 $unwind,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25136536/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com