neo4j cypher基于两个关系过滤多路径

时间:2018-02-20 09:55:05

标签: neo4j cypher

我有以下图表:

enter image description here

我需要获取与特定用户节点相关的所有AD节点。如果我用户B1搜索,我应该得到所有通过HAS关系连接到B1节点的AD节点以及通过HAS关系连接到其父节点的AD节点。但是,如果这些AD节点中的任何一个通过EXCLUDES关系连接,我应该将其过滤掉。

例如,如果我按B1搜索,我应该得到AD4,AD2

AD1与D1有排除,AD3与C1排除,因此被过滤掉。

我正在使用以下密码

MATCH path=(p:AD)-[:HAS|EXCLUDES]-()<-[:CHILD_OF*]-(u:User) USING INDEX u:User(id) WHERE u.id = 'B1'
with p,
     collect( filter( r in rels(path) 
                      where type(r) = 'EXCLUDES'
              ) 
     ) as test
          where all( t in test where size(t) = 0 )
return p

问题是当我用C1搜索时,它返回AD4,AD3,AD2。如何从结果中消除AD3?

1 个答案:

答案 0 :(得分:1)

:CHILD_OF*不包含您的起始节点。要包含它,请设置下限为0:

[:CHILD_OF*0..]

也就是说,可能有更好的方法来形成您的查询。试试这个,也许吧:

MATCH (u:User)
WHERE u.id = 'B1'
WITH u, [(p:AD)-[:EXCLUDES]-()<-[:CHILD_OF*0..]-(u) | p] as excluded
MATCH (p:AD)-[:HAS]-()<-[:CHILD_OF*0..]-(u)
WHERE not p in excluded
RETURN p

修改

pattern comprehension功能随Neo4j 3.1发布。您将无法在旧版本中使用它。试试这个:

MATCH (u:User)
WHERE u.id = 'B1'
OPTIONAL MATCH (p:AD)-[:EXCLUDES]-()<-[:CHILD_OF*0..]-(u)
WITH u, collect(p) as excluded
MATCH (p:AD)-[:HAS]-()<-[:CHILD_OF*0..]-(u)
WHERE not p in excluded
RETURN p