我有以下图表:
我需要获取与特定用户节点相关的所有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?
答案 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