使用Neo4j 2.0.1,我试图在任何级别(2-5)的深度找到与用户不是朋友的朋友的朋友。
起初,我使用cypher来吸引所有朋友的朋友,但遗憾的是,当我试图在4和5深度找到朋友的朋友时,表现非常糟糕。所以,我从密码转移到遍历休息api后来我将用于Neo4jPHP遍历。所以这就是我所做的改变:
注意:
- there are 10 users with 5 friends of each user
- user that I want to traverse at depth of 3 is 1
- traversal at depth of 3
好友列表:
User | Friends
1 | 9,2,8,7,5
2 | 1,6,3,8,10
3 | 5,7,1,10,2
4 | 3,10,6,9,5
5 | 4,8,1,9,3
6 | 7,9,3,2,10
7 | 9,5,10,6,8
8 | 6,9,1,10,5
9 | 6,5,10,1,8
10 | 8,6,4,5,9
的Cypher:
MATCH (U:User)-[F:Friend]->(FU:User)-[FF:Friend]->(FFU:User)
WHERE U.user_id=1
WITH DISTINCT U, FFU
WHERE FFU<>U
WITH DISTINCT U, FFU
MATCH (FFU:User)-[FFF:Friend]->(FFFU:User)
WHERE FFFU<>U AND NOT (U)-[:Friend]->(FFFU)
RETURN DISTINCT FFFU.username;
Traveal Rest Api [更新]:
POST http://localhost:7474/db/data/node/1/traverse/node
{
"order" : "breadth_first",
"uniqueness" : "node_global",
"prune_evaluator" : {
"name" : "none",
"language" : "builtin"
},
"return_filter" : {
"body" : "position.endNode().getProperty('user_id')!=1 && position.endNode().getProperty('user_id')!=9 && position.endNode().getProperty('user_id')!=2 && position.endNode().getProperty('user_id')!=8 && position.endNode().getProperty('user_id')!=7 && position.endNode().getProperty('user_id')!=5;",
"language" : "javascript"
},
"relationships" : {
"direction" : "out",
"type" : "Friend"
},
"max_depth" : 3
}
Neo4jPHP遍历[更新]:
$traversal->addRelationship('Friend', Relationship::DirectionOut)
->setPruneEvaluator(Traversal::PruneNone)
->setReturnFilter('javascript', "position.endNode().getProperty('user_id')!=1 && position.endNode().getProperty('user_id')!=9 && position.endNode().getProperty('user_id')!=2 && position.endNode().getProperty('user_id')!=8 && position.endNode().getProperty('user_id')!=7 && position.endNode().getProperty('user_id')!=5;")
->setMaxDepth(3)
->setUniqueness(Traversal::UniquenessNodeGlobal)
->setOrder(Traversal::OrderBreadthFirst);
使用Traversal Rest Api和Neo4jPHP Traversal,我得到了结果:9,6,7,3,2,10,5,4,8
虽然我想要的结果是:6,3,10,4
由于9,7,2,5,8
已经是用户的朋友:1
注:
I just updated the way I traverse my graph to find friends of friends at depth of 3, so I updated my question too.
我们可以看到我在return_filter中创建的条件是手动的:
"body" : "position.endNode().getProperty('user_id')!=1 && position.endNode().getProperty('user_id')!=9 && position.endNode().getProperty('user_id')!=2 && position.endNode().getProperty('user_id')!=8 && position.endNode().getProperty('user_id')!=7 && position.endNode().getProperty('user_id')!=5;"
在Cypher中,我们可以轻松删除已经与用户成为朋友的朋友的朋友:1
:
WHERE NOT (U)-[:Friend]->(FFFU)
现在,如何在Traversal Rest Api做出类似的情况?
我问,因为文档中的信息不多。
请有人帮助我。我真的需要你的帮助。
谢谢。
答案 0 :(得分:1)
这不可能只需指定:
MATCH (user:User)-[:FRIEND*2..4]->(fof)
WHERE NOT (user)-[:FRIEND]->(fof)
或许我遗漏了一些东西,您是否正在使用DISTINCT语句来提高性能?我很惊讶cypher在这里表现不佳,你能用Neo4j shell中的PROFILE命令尝试查询,并将结果发给我吗?你可以发邮件给我jakewins AT gmail.com
至于遍历,从概念上讲,我会这样做:
Start at User
Find all Users friends, and put them in a Set 'friends'
Start at each friend, and traverse out as many hops you like
Return each user found that is not in the set of friends
我不相信你可以在REST遍历API中执行set set,这意味着你需要编写一个服务器扩展,这将允许你用Java编写它并使用更强大的Java遍历API ,您可以在此处阅读有关扩展的内容:http://docs.neo4j.org/chunked/stable/server-unmanaged-extensions.html和Java遍历API:http://docs.neo4j.org/chunked/stable/tutorial-traversal-java-api.html
或者,您可以执行两个调用,一个用于获取所有用户朋友,另一个用于作为您发送的脚本的一部分与用户朋友进行REST遍历,就像您在问题中所做的那样,但是您的应用生成了过滤器代码。