簡體   English   中英

密碼查詢可遍歷特定類型的所有節點以及與組相關的節點

[英]Cypher query to iterate through all nodes of a specific type and group related nodes

有人可以幫助neo4j新手(這是我的第二天!)解決以下問題嗎?

我有一個數據庫,並且所有玩過游戲(S)的球員(P)及其得分。 有很多S,我們稱它們為S1,S2,S3等。還有很多P,P1,P2,P3等。

每個環節都有玩家,例如

(P) - [:出場] - >(S)

每個環節的參與者人數從2到10不等。

我想做的是訪問每個SESSION,獲取該會話的每個玩家,然后根據得分對他們進行排名。 首先需要按得分對球員排序,然后對球員進行排名,每個球員的得分要高於前一個具有BEAT關系的球員。 通常,我將使用FOREACH循環,但無法弄清楚如何使用Cypher進行同樣的操作。

例如,S1具有玩家P1,P3和P5。 如果P3獲得100,P1獲得70,P5獲得30,我想創建以下關系:

(P3) - [:BEAT] - >(P1) - [:BEAT] - >(P5)

我需要在每個會話中都這樣做。 解決這個問題的最佳方法是什么?

問候,

假設score存儲在:PLAYED關系中,則該方法應該起作用:

// Find all players who have played in a session
MATCH (p:Player)-[r:PLAYED]->(s:Session)           
// for each Session, order the players by their score for that session
WITH s, p ORDER BY r.score DESC       
// for each session, group the players (now ordered by their scores)
WITH s, COLLECT(p) AS players   
// iterate over the sequence 0..number_of_players_in_this_session-2
UNWIND range(0,size(players)-2) AS i      
// grab pairs of players, starting from the highest scoring
WITH players[i] AS l1, players[i+1] AS l2      
// create :BEAT relationship
CREATE (l1)-[:BEAT]->(l2)

有一個簡單的Neo4j控制台例子在這里

當然,這里有一個數據建模問題,您沒有將:BEAT關系與特定會話相關聯。

只需添加一種快捷方式即可保存幾行Cypher,即可安裝APOC過程並使用apoc.nodes.link()快速創建關系鏈。

以William Lyon的查詢為基礎:

// Find all players who have played in a session
MATCH (p:Player)-[r:PLAYED]->(s:Session)           
// for each Session, order the players by their score for that session
WITH s, p ORDER BY r.score DESC       
// for each session, group the players (now ordered by their scores)
WITH s, COLLECT(p) AS players  
CALL apoc.nodes.link(players, 'BEAT')
// can't end a query with CALL, so just do a dummy return of some kind
RETURN DISTINCT true

如果有人覺得這篇文章有用,我想補充一下,以處理較大的結果集(以避免耗盡內存),請嘗試以下操作:

// Find all players who have played in a session
MATCH (p:Player)-[r:PLAYED]->(s:Session)           
// for each Session, order the players by their score for that session
WITH s, p ORDER BY r.score DESC
//Paginate/batch process results to avoid exhausting memory
SKIP 500000*n
LIMIT 500000          
// for each session, group the players (now ordered by their scores)
WITH s, COLLECT(p) AS players  
CALL apoc.nodes.link(players, 'BEAT')
// can't end a query with CALL, so just do a dummy return of some kind
RETURN DISTINCT true

即線

SKIP 500000*n
LIMIT 500000  

添加。 設置n = 0,並保持增加直到沒有更多的記錄被更新。

感謝所有對此線程做出貢獻的人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM