我想根据一些基于图遍历的规则来增加用户的边缘。基本上在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强大吗?我是否必须将重量设置为边缘上的属性来实现它?
由于
答案 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
)。