0

使用 Neo4j 2.0.1,我试图在任何级别(2-5)的深度找到与用户不是朋友的朋友的朋友。

起初,我使用 cypher 来获取朋友的所有朋友,但遗憾的是,当我尝试在 4 和 5 深度查找朋友的朋友时,性能非常糟糕。所以,我从 cypher 转移到 traversal rest 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

暗号:

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;

Travesal 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 中,我们可以轻松删除已经与 user: 成为朋友的朋友的朋友1

WHERE NOT (U)-[:Friend]->(FFFU)

现在,如何在 Traversal Rest Api 中创建这样的条件?

我问是因为文档中没有太多信息。

请任何人帮助我。我真的需要你的帮助。

谢谢你。

4

1 回答 1

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 中完成设置部分,这意味着您要么需要编写一个服务器扩展,这将允许您用 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 遍历,作为您发送的脚本的一部分,就像您在问题中所做的那样,但您的应用程序会生成过滤器代码.

于 2014-04-05T17:18:54.770 回答