I have the following style Collection:
我有以下风格的集合:
{
"_id" : "5548d5ebb8157a53e9ceb9a4",
"layers" : [
{ "_id" : "5548c97eb8157a53e9ceb9a0", "name" : "layer1"},
{ "_id" : "5548c97eb8157a53e9ceb9a1", "name" : "layer2"}
]
}
{
"_id" : "5548d5ebb8157a778899b9a5",
"layers" : [
{ "_id" : "5548c97eb8157a53e9ceb9a2", "name" : "layer1"},
{ "_id" : "5548c97eb8157a53e9ceb9a3", "name" : "layer2"}
]
}
...
I now want to query for layers with certain _id
. What I want is only an array of matching layer objects. Here is what I tried:
我现在想要查询具有特定_id的图层。我想要的只是一个匹配的图层对象数组。这是我尝试过的:
db.graphs.aggregate([
{ $match: { "layers._id": { $in: ["5548c97eb8157a53e9ceb9a1"] } } },
{ $redact : { $cond:
{ if:
{ $or : [
{ $eq: ["$_id","5548c97eb8157a53e9ceb9a1"] },
{ $not : "$_id" }]
},
then: "$$DESCEND",
else: "$$PRUNE"
}
} }]);
Doesn't work - I get an empty result. Any hints?
不起作用 - 我得到一个空的结果。任何提示?
1 个解决方案
#1
Ok I found the solution, short version:
好的我找到了解决方案,简短版本:
db.test.aggregate([
{ $match: { "layers._id": { $in: ["5548c97eb8157a53e9ceb9a1"] } } },
{ $redact : { $cond:
{ if:
{ $or : [
{ $eq: ["$_id","5548c97eb8157a53e9ceb9a1"] },
{ $or : "$layers" }]
},
then: "$$DESCEND",
else: "$$PRUNE"
}
} }]);
Explanation: first understand that the $redact
operator walks the matched documents level wise downwards, like a tree / graph. The problem here was that the top level document already contains an _id
field. Therefore the { $not: "_id" }
expression evaluates to false. On the same, top level, so does the { $eq: ["$_id","5548c97eb8157a53e9ceb9a1"] }
expression since that id would only be found on the nested, next level. As a result the top level evaluates to false and "$$PRUNE" is done instead of "$$DESCEND".
说明:首先要了解$ redact操作符向下向下移动匹配的文档,如树/图。这里的问题是*文档已经包含一个_id字段。因此,{$ not:“_ id”}表达式的计算结果为false。在同一顶层,{$ eq:[“$ _id”,“5548c97eb8157a53e9ceb9a1”]}表达式也是如此,因为该id只能在嵌套的下一级找到。结果,*评估为false并且“$$ PRUNE”完成而不是“$$ DESCEND”。
The provided solution makes the top level pass by letting the test be true if the checked level has a layers
property - which the top level, and only the top level, does have.
如果检查的级别具有图层属性(*,只有*级别)具有图层属性,则提供的解决方案会使测试成为正确。
#1
Ok I found the solution, short version:
好的我找到了解决方案,简短版本:
db.test.aggregate([
{ $match: { "layers._id": { $in: ["5548c97eb8157a53e9ceb9a1"] } } },
{ $redact : { $cond:
{ if:
{ $or : [
{ $eq: ["$_id","5548c97eb8157a53e9ceb9a1"] },
{ $or : "$layers" }]
},
then: "$$DESCEND",
else: "$$PRUNE"
}
} }]);
Explanation: first understand that the $redact
operator walks the matched documents level wise downwards, like a tree / graph. The problem here was that the top level document already contains an _id
field. Therefore the { $not: "_id" }
expression evaluates to false. On the same, top level, so does the { $eq: ["$_id","5548c97eb8157a53e9ceb9a1"] }
expression since that id would only be found on the nested, next level. As a result the top level evaluates to false and "$$PRUNE" is done instead of "$$DESCEND".
说明:首先要了解$ redact操作符向下向下移动匹配的文档,如树/图。这里的问题是*文档已经包含一个_id字段。因此,{$ not:“_ id”}表达式的计算结果为false。在同一顶层,{$ eq:[“$ _id”,“5548c97eb8157a53e9ceb9a1”]}表达式也是如此,因为该id只能在嵌套的下一级找到。结果,*评估为false并且“$$ PRUNE”完成而不是“$$ DESCEND”。
The provided solution makes the top level pass by letting the test be true if the checked level has a layers
property - which the top level, and only the top level, does have.
如果检查的级别具有图层属性(*,只有*级别)具有图层属性,则提供的解决方案会使测试成为正确。