我有字段相同的父记录和子记录。然而,某些字段仅在父级别设置。
父字段设置为空字符串 ("") 表示该记录是父记录。其他记录有一个指向父记录的值集,因此这些记录可以被视为子记录。
现在考虑以下记录:
{"_id": 1, parent: "", "pValue": ["a", "b", "c"], fieldA: 2},
{"_id": 2, parent: 1, "pValue": [], fieldA: 2},
{"_id": 3, parent: 1, "pValue": [], fieldA: 2},
{"_id": 4, parent: "", "pValue": ["d"], fieldA: 9},
{"_id": 5, parent: 4, "pValue": [], fieldA:2},
{"_id": 6, parent: 4,"pValue": [], fieldA: 9}
上述记录包含两个父记录,每个父记录有 2 个关联的子记录。我尝试执行的查询涉及匹配两个给定的参数。首先是 pValue 的值。一旦我得到了数组中具有特定 pValue 的所有 parent 。然后,我想要将该父记录及其所有关联的子记录与 fieldA 值相匹配。
因此,如果给定 pValue="d"且 fieldA=9 我希望光标内包含以下记录:
{"_id": 4, parent: "", "pValue": ["d"], fieldA: 9}
{"_id": 6, parent: 4, "pValue": [],fieldA: 9}
注释:
- 每个父级都可以有多个与其关联的子级。
- 父级可以具有与子级不同的 fieldA 值,并且查询只能返回子级而不是父级
我的尝试:
cursor=self.pCollection.aggregate([
{ "$match": {"pValue":{"$in":[pCheck]}},
{ "$graphLookup" : {
"from": "pCollection",
"startWith": "$_id",
"connectFromField": "_id",
"connectToField": "parent",
"as" : "children"
}
}])
然后,我陷入了所有与父级相关联的子级作为数组的困境,而不知道如何包装它们。
最佳答案
您需要使用 $match
选择与您的查询条件匹配的文档并过滤“children”数组,添加 $addFields
阶段。
$filter
之后ing,您可以使用arrayElemAt
将项目分配给字段。
{ "$match": { "fieldA": 9, "children.fieldA": 9 } },
{ "$addFields": {
"children": {
"$arrayElemAt": [
{ "$filter": {
"input": "$children",
"as": "child",
"cond": { "$eq": [ "$$child.fieldA", 9 ] }
}},
0
]
}
}}
您的查询将产生如下内容:
{
"_id" : 4,
"parent" : "",
"pValue" : [ "d" ],
"fieldA" : 9,
"children" : { "_id" : 6, "parent" : 4, "pValue" : [ ], "fieldA" : 9 }
}
但是,只要有一点信心,您就可以获得预期的结果。
db.collection.aggregate([
{ "$graphLookup": {
"from": "collection",
"startWith": "$_id",
"connectFromField": "_id",
"connectToField": "parent",
"as" : "children"
}},
{ "$match": { "fieldA": 9, "children.fieldA": 9 } },
{ "$addFields": {
"children": {
"$arrayElemAt": [
{ "$filter": {
"input": "$children",
"as": "child",
"cond": { "$eq": [ "$$child.fieldA", 9 ] }
}},
0
]
}
}},
{ "$project": {
"children": [
"$children",
{
"_id": "$_id",
"parent": "$parent",
"pValue": "$pValue",
"fieldA": "$fieldA"
}
]
}},
{ "$unwind": "$children" },
{ "$replaceRoot": { "newRoot": "$children" } }
])
它会产生这样的东西:
{ "_id" : 6, "parent" : 4, "pValue" : [ ], "fieldA" : 9 }
{ "_id" : 4, "parent" : "", "pValue" : [ "d" ], "fieldA" : 9 }
坦白说,我不认为这是您应该在应用程序中执行的操作。第一个选项是您可以并且应该接受的。
如果你确实需要这个,我建议你create a view并查询应用程序中的 View 。
关于python - $graphLookup 管道阶段后过滤结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41690606/