2014-04-04 68 views
0

使用Neo4j 2.0.1,我試圖找到與用戶不在一起的朋友的朋友, 5)。當我試圖在4和5的深度尋找朋友的朋友時,我的表現非常糟糕。所以,我從密碼移動到遍歷休息api,然後我將在Neo4jPHP遍歷中使用。所以這就是我所做的更改:Neo4j - 遍歷找到與用戶不是朋友的朋友

注:

- 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); 

使用橫越REST API和Neo4jPHP穿越上述我得到的結果是:9,6,7,3,2,10,5,4,8

雖然結果我想要的是:6,3,10,4

因爲9,7,2,5,8是已與用戶朋友:1

NOTE:

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中創建這樣的條件?

我問,因爲沒有太多的文件信息。

請任何人都幫助我。我真的需要你的幫助。

謝謝。

回答

1

不應該這樣有可能通過簡單地指定:

MATCH (user:User)-[:FRIEND*2..4]->(fof) 
WHERE NOT (user)-[:FRIEND]->(fof) 

也許我失去了一些東西,你使用DISTINCT語句,以此來提高性能?我很驚訝密碼在這裏表現不佳,你能用Neo4j外殼中的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遍歷作爲腳本的一部分你發送過來,就像你在你的問題中做的一樣,但是你的應用程序會生成過濾器代碼。