繁体   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