问题描述
例如树结构为;
[{id: 1 , childrenIdList: [2, 3]},{id: 2 , childrenIdList: [4, 5]},{id: 3 , childrenIdList: []},{id: 4 , childrenIdList: [6, 7]},{id: 5 , childrenIdList: []},{id: 6 , childrenIdList: []},{id: 7 , childrenIdList: []}]就像;
12 34 56 7
如何从叶子节点(id=7)到根节点(id=1)追踪树?
找到id=7
的父节点很容易;
db.document.find({childrenList: { $in: [7]}}, {id: 1}).toArray(function(err), result{/*结果给出{"id" : NumberInt(4)}现在我应该看看 id=4 的父级和 id=2 的父级,正如你所知.*/})
在 mongodb 上可以进行递归查询吗?我该如何实施?
根据您的用例,MongoDB v3.4 提供了一个 聚合管道 操作符,称为 $graphLookup.聚合运算符能够对集合执行递归搜索.查看关于 $graphLookup 定义的更多定义.
使用上面的文档层次结构和值作为示例,您可以尝试在聚合下运行:
db.collectionName.aggregate([{$放松:{路径:"$childrenIdList",preserveNullAndEmptyArrays: true}},{$graphLookup:{来自:集合名称",startWith:"$_id",connectFromField:"_id",connectToField:"childrenIdList",如:我的父母",限制搜索匹配:{"_id"}}},{$match: {"_id": 7 } },{$组:{_id:"$_id",父母:{$addToSet:"$myparents._id"}}}]);
以上应该返回如下结果:
{ "_id" : 7, "parents" : [ [ 1, 2, 4 ] ] }
话虽如此,如果你有一个大集合,上面的查询可能性能不佳,因为你将执行 $unwind 并且无法使用索引.正如其他人所建议的,您应该重新考虑您的文档模型结构.请参阅数据模型树结构.根据您的应用程序逻辑和查询用例进行优化,让灵活的文档架构跟随.
For example a tree structure as;
[
{id: 1 , childrenIdList: [2, 3]},
{id: 2 , childrenIdList: [4, 5]},
{id: 3 , childrenIdList: []},
{id: 4 , childrenIdList: [6, 7]},
{id: 5 , childrenIdList: []},
{id: 6 , childrenIdList: []},
{id: 7 , childrenIdList: []}
]
which is like;
1
2 3
4 5
6 7
How can I trace tree from starting the leaf node(id=7) to root(id=1)?
Finding the parent of id=7
is easy as;
db.document.find({childrenList: { $in: [7]}}, {id: 1}).toArray(function(err), result{
/*result gives
{"id" : NumberInt(4)}
now I should look the parent of id=4, and parent of id=2 as you know.
*/
})
Is recursive queries possible on mongodb? How can I implement it?
Depending on your use case, MongoDB v3.4 provides an aggregation pipeline operator called $graphLookup. The aggregation operator is able to perform a recursive search on a collection. See more definiton on $graphLookup definition.
Using your documents hierarchy and values above as examples, you could try running below aggregation:
db.collectionName.aggregate([
{$unwind:{
path:"$childrenIdList",
preserveNullAndEmptyArrays: true}
},
{$graphLookup:{
from:"collectionName",
startWith:"$_id",
connectFromField:"_id",
connectToField:"childrenIdList",
as:"myparents",
restrictSearchWithMatch: {"_id"}}
},
{$match: {"_id": 7 } },
{$group:{
_id:"$_id",
parents:{$addToSet:"$myparents._id"}
}}
]);
The above should return result as below:
{ "_id" : 7, "parents" : [ [ 1, 2, 4 ] ] }
Having said that, if you have a large collection the above query may not be performant as you'll be performing $unwind on each documents and won't be able to utilise indexes. As suggested by others, you should re-consider your document model structure. See Data Models Tree Structures. Optimise based on your application logic and querying use case, and let the flexible document schema follow.
这篇关于如何使用 MongoDB 递归查询树结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!