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

neo4j cypher基于两种关系过滤多路径,neo4j,cypher,Neo4j,Cypher,我有以下图表: 我需要获取与特定用户节点相关的所有AD节点。如果我通过用户B1进行搜索,我应该获得通过HAS关系连接到B1节点的所有AD节点,以及通过HAS关系连接到其父节点的AD节点。但是,如果这些AD节点中的任何一个是通过排除关系连接的,我应该过滤掉它 例如,如果我按B1搜索,我应该得到AD4,AD2 AD1使用D1进行排除,AD3使用C1进行排除,因此被过滤掉 我正在使用以下密码 MATCH path=(p:AD)-[:HAS|EXCLUDES]-()<-[:CHILD_OF*]-

我有以下图表:

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

例如,如果我按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

匹配路径=(p:AD)-[:HAS | EXCLUDES]-()
:CHILD\u OF*
不包括起始节点。若要包含该值,请将lowerbound设置为0:

[:子元素*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
匹配(u:用户)
其中u.id='B1'

有了u,[(p:AD)-[:EXCLUDES]-()谢谢@InverseFalcon!!我完全错过了下限。但是当你说写这个查询更好的方法时,是基于性能还是其他因素?你能澄清一下吗?看看时间安排如何(在几次执行之后)站在两个查询之间。然后对两个查询运行配置文件,查看它们之间的db命中情况。从我个人的角度来看,我倾向于更简单易懂的查询。在这种情况下,我使用的方法是:匹配并收集排除的节点,然后匹配:HAS未排除的节点。谢谢。我一定会尝试。我我使用的是旧版本的neo4j(2.3.6)。您查询中的|符号为我抛出了错误。它在新版本中可用吗?是的,您将无法使用它。相应地更新了我的答案。
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