MongoDB:找到精确深度的人

时间:2014-07-02 11:42:48

标签: mongodb mongodb-query

我在MongoDB中有一些图形连接:

{ 
    from: ObjectID(user),
    to: ObjectID(user) 
}

如果我想让所有用户都在深度1,很容易:

db.connections.find({from:ObjectID(myUser)});

但是当我想要找到深度为2的所有用户时,很难:愚蠢的想法是“找到所有深度为1的人,然后为每个人做一个像前一个一样的查询。没办法,加上它会返回也是所有循环路径。

e.g 
1->2 
2->1 
1->3
2->4
results of user(1).findDepth2() would be 2,1,3,4 instead of 4. 

伪node.js中的示例:

var myFriends = db.connections.find({from:ObjectID(myUser)});
var friendAtDepth2 = [];
for(friend in myFriends){
    // I find friends of each friend
    var frendsOfFriend = db.connections.find({from:ObjectID(friend)});
    for(friendOfFriend in frendsOfFriend){
        if(friendAtDepth2.indexof(friendOfFriend)==-1 
             && myFriends.indexof(friendOfFriend)==-1
             && myUser!=friendOfFriend){
             // I haven't already found this user, so I it is actually at depth 2
             friendAtDepth2.push(friendOfFriend);
        }
    }
}

但是通过这种方式,我确实做了很多查询,我希望存在一种类似于mysql的连接查询,我只在一个查询中执行此操作

这样的查询是否可行?

1 个答案:

答案 0 :(得分:0)

实施Breath-First Search算法以查找距离特定节点2的所有节点。

它具有线性时间复杂度O(| E | + | V |),因此你不能做得比这更好。

如果你想要距离为2,3和3的所有节点,那么你可能需要查看All-Pairs最短路径算法并稍微定制它们。

通过自定义它我的意思是你应该从每个节点运行一个BFS并停在所需的深度。如果你想要一些具体的代码示例,你应该看一下类似的问题,比如All paths of length L from node n using python

另外,根据您的数据,您可以向节点添加显式邻居列表,这些列表具有过多的空间要求,您可以使用一个查询将所有数据放入内存中,或者您可以尝试使用聚合框架(可能是实施起来有点棘手,但这应该是最快的解决方案。)

或者,如果您的应用程序对图形和图形算法非常重视,您应该考虑图形数据库,例如Neo4j