Cypher:聚合和个人选择

时间:2016-03-04 13:12:42

标签: neo4j cypher

我想要一个查询来查找边上属性的最小值和最大值,以及连接到给定节点的边的值。

考虑这个示例数据库:

Simple graph database

我们有一个Game节点(以红色显示)和三个Person节点(以蓝色显示)。 GamePerson节点都具有name属性,对于此示例,我们假设名称是唯一的。 PersonGame个节点通过BEST_SCORE边缘连接,这些边缘上有score属性,每个人只能将一条边连接到游戏。

到目前为止,我已经想出了这个:

MATCH (g:Game)<-[s:BEST_SCORE]-(p:Person)
WHERE g.name='Pacman'
WITH MAX(s.score) AS max, MIN(s.score) AS min
MATCH (g:Game)<-[s:BEST_SCORE]-(p:Person) WHERE g.name='Pacman' AND p.name='Tom'
RETURN min, max, s.score

给出这些结果:

Cypher results

这些正是我想要的结果,但我不禁想到必须有一个更好的方法来做到这一点?我认为必须有一种比将Game节点及其与Person节点的连接匹配两次更好的方法,一次用于聚合,一次用于个别得分?也许这是最好的方式?

2 个答案:

答案 0 :(得分:2)

如果您正在寻找效率,而不是每次想要返回玩家得分时计算 public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; } min,您可以定期重新计算聚合并将其存储在游戏节点。过了一会儿,最小值和最大值会经常停止变化。

max

然后你可以在寻找球员得分时抓住它们。

MATCH (g:Game {name:'Pacman'} )<-[s:BEST_SCORE]-(p:Person)
WITH MAX(s.score) as max_score, MIN(s.score) as min_score, g
SET g.max_score = max_score, g.min_score = min_score

答案 1 :(得分:0)

首先,感谢一个详细的问题,+ 1。

您可以管理关系的集合以及min,max,然后UNWIND此集合:

MATCH (a:Game { name:'Pacman' })<-[r:BEST_SCORE]-(person)
WITH collect(r) AS rels, max(r.score) AS max, min(r.score) AS min 
UNWIND rels AS r
RETURN r.score AS score, min, max


score   min max
12.5    5   23.2
23.2    5   23.2
5       5   23.2