简体   繁体   English

密码查询可遍历特定类型的所有节点以及与组相关的节点

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

Can someone help a neo4j newbie (this is my 2nd day!) solve the following problem? 有人可以帮助neo4j新手(这是我的第二天!)解决以下问题吗?

I have a database and I have all players (P) that have played a game session (S) and the scores they achieved. 我有一个数据库,并且所有玩过游戏(S)的球员(P)及其得分。 There are numerous Ss, let's call them S1, S2, S3 ... etc. There are numerous Ps, P1, P2, P3 ... etc. 有很多S,我们称它们为S1,S2,S3等。还有很多P,P1,P2,P3等。

Each session has players, eg 每个环节都有玩家,例如

(P)-[:PLAYED]->(S) (P) - [:出场] - >(S)

Each session has a variable number of players, from 2 to 10. 每个环节的参与者人数从2到10不等。

What I want to do, is access every SESSION, get every player for that session and then rank them according to score. 我想做的是访问每个SESSION,获取该会话的每个玩家,然后根据得分对他们进行排名。 The players need to be first sorted by score and then ranked, with each player with a higher score than the preceding player having a BEAT relationship. 首先需要按得分对球员排序,然后对球员进行排名,每个球员的得分要高于前一个具有BEAT关系的球员。 Normally, I would use a FOREACH loop, but I can't figure out how to do the same with Cypher. 通常,我将使用FOREACH循环,但无法弄清楚如何使用Cypher进行同样的操作。

For example, S1 has players P1, P3, and P5. 例如,S1具有玩家P1,P3和P5。 If P3 got 100, P1 got 70, and P5 30, I would like to create the following relationships: 如果P3获得100,P1获得70,P5获得30,我想创建以下关系:

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

I need to do this for every session. 我需要在每个会话中都这样做。 What would be the best way to approach this problem? 解决这个问题的最佳方法是什么?

Regards, 问候,

Assuming that score is stored on the :PLAYED relationship, this should work: 假设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)

There is a simple Neo4j console example here 有一个简单的Neo4j控制台例子在这里

Of course there is a data modeling problem here, you are not associating the :BEAT relationships with a particular session. 当然,这里有一个数据建模问题,您没有将:BEAT关系与特定会话相关联。

Just to add a shortcut approach to save a few lines of Cypher, you can install APOC Procedures and use apoc.nodes.link() to quickly create your relationship chain. 只需添加一种快捷方式即可保存几行Cypher,即可安装APOC过程并使用apoc.nodes.link()快速创建关系链。

Using William Lyon's query as a base: 以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

If anyone finds this post useful, I would like to add, to process a large result set (to avoid running out of memory), try this: 如果有人觉得这篇文章有用,我想补充一下,以处理较大的结果集(以避免耗尽内存),请尝试以下操作:

// 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

ie the lines 即线

SKIP 500000*n
LIMIT 500000  

Were added. 添加。 Set n = 0, and keep increasing until no more records are updated. 设置n = 0,并保持增加直到没有更多的记录被更新。

Thank you to everyone who contributed to this thread. 感谢所有对此线程做出贡献的人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM