我的父记录和子记录在字段中是相同的。但是,某些字段仅在父级设置。
将父字段设置为空字符串("")表示记录是父记录。其他记录有一个指向父记录的值集,因此这些记录可以被视为子记录。
现在考虑以下记录:
{"_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}上面的记录包含两个父母,每个父母都有两个相关的子记录。我要执行的查询涉及到匹配两个给定的参数。首先是pValue上的一个值。一旦我得到所有的父母,在他们的数组中有一个特定的pValue。然后,我希望将该父记录及其所有相关的子记录与fieldA值匹配。
因此,如果给定pValue="d“和fieldA=9,我希望游标中有以下记录:
{"_id": 4, parent: "", "pValue": ["d"], fieldA: 9}
{"_id": 6, parent: 4, "pValue": [],fieldA: 9}备注:
我的尝试:
cursor=self.pCollection.aggregate([
{ "$match": {"pValue":{"$in":[pCheck]}},
{ "$graphLookup" : {
"from": "pCollection",
"startWith": "$_id",
"connectFromField": "_id",
"connectToField": "parent",
"as" : "children"
}
}])然后,我发现所有与父级关联的子类都是数组,而不知道如何重新包装它们。
发布于 2017-01-17 07:00:34
您需要使用$match选择与查询条件匹配的文档,并在添加$addFields阶段中筛选“子”数组。
在$filtering之后,您可以使用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 }坦率地说,我不认为这是你应该在你的应用程序中做的事情。第一种选择是你可以而且应该接受的东西。
如果您真的需要这样做,我建议您在应用程序中使用创建视图并查询视图。
发布于 2017-01-17 23:51:04
通过反转查询并在fieldA上进行第一次匹配,然后执行来自父-> _id的graphyLookup (因此将父映射到子),我就能够将其子节点关联到其父级的fieldA。
这是我最后得到的查询:
cursor=self.collection.aggregate([
{ "$match": {"fieldA":9}},
{ "$graphLookup" : {
"from": "collection",
"startWith": "$parent",
"connectFromField": "parent",
"connectToField": "_id",
"as" : "parents"
}
},
{ "$project" : {
"pValue": { "$cond":[ {"$ne":["$pValue",[]]},"$pValue",
{"$let":{"vars": {"obj": {"$arrayElemAt": ["$parents", 0]}},
"in": "$$obj.pValue"}}]}
}
},
{ "$match": {"pValue":{"$in":["d"]}}}
])https://stackoverflow.com/questions/41690606
复制相似问题