密码联盟组

时间:2016-04-21 20:23:59

标签: neo4j cypher

我想根据一些基于图遍历的规则来增加用户的边缘。基本上在mysql中我会这样做:

select id, sum(weight) as total
from
(
     select id, 10 as weight
     from user
     inner join userRel1 ON user.id = userRel1.userId
     where userRel1.attr1 in (1, 2)
  union
     select id, 5 as weight
     from user
     inner join userRel2 ON user.id = userRel2.userId
     inner join userRel3 ON user.id = userRel3.userId
     where userRel2.attr2 = 'a' and userRel3.attr2 = 'z'
  union
     ...
)
group by id 
order by total desc

另外,我已经在gremlin 3中提供了一些帮助,但我想将性能与cypher进行比较。但是我在这篇post中读到了关于联盟的小组还不可能,这意味着密码不如gremlin强大吗?我是否必须将重量设置为边缘上的属性来实现它?

由于

1 个答案:

答案 0 :(得分:0)

虽然post UNION处理确实是still an open feature request,但您无需使用UNION来执行您的用例。

此查询应该与您的SQL相同(忽略不完整的部分):

WITH [] AS res

OPTIONAL MATCH (user1:User), (userRel1:UserRel1) 
WHERE user1.id = userRel1.userId AND userRel1.attr1 IN [1, 2] 
WITH res, (CASE WHEN userRel1 IS NOT NULL THEN COLLECT({id: user1.id, weight: 10}) ELSE [] END) AS data 
WITH res + data AS res

OPTIONAL MATCH (user2:User), (userRel2:UserRel2)
WHERE user2.id = userRel2.userId AND userRel2.attr2 = 'a'
OPTIONAL MATCH (userRel3:UserRel3)
WHERE user2.id = userRel3.userId AND userRel3.attr2 = 'z' 
WITH res, (CASE WHEN userRel3 IS NOT NULL THEN COLLECT({id: user2.id, weight: 5}) ELSE [] END) AS data 
WITH res + data AS res 

UNWIND res AS result
RETURN result.id, SUM(result.weight) AS weight;

我在视觉上将此查询分解为单独的Cypher块,以便于阅读。

查询继续使用适当的res / id对扩展(并替换)weight集合,然后在最后聚合。

具有2个OPTIONAL MATCH子句的块可能是使用单个OPTIONAL MATCH编写的,但我认为更高效的是同样的工作零碎,并允许一个{{1}的失败有可能告知Cypher甚至不打扰另一个人。块的第二个OPTIONAL MATCH子句依赖于第一个WHERE找到的user2节点。如果第一个OPTIONAL MATCH失败,user2将具有值NULL,并且此类OPTIONAL MATCH值也会导致第二个NULL子句失败(这将在转动制作WHERE userRel3)。