Neo4j / Cypher - 过滤并返回相同的关系类型

时间:2013-07-06 18:38:48

标签: database neo4j cypher

假设我有一些FOLLOWS个其他节点的用户节点。我想加载所有用户的列表,以及完整的列表,其中列出了他们关注过滤该列表的人员,以便仅获取跟踪某些特定节点的用户。这样做的正确方法是什么?


我的第一次尝试是:

START n=node(*)
MATCH n-[:FOLLOWS]->following
WHERE following.name='John'
RETURN n, COLLECT(following)

除了John之外,所有被跟踪的用户都被过滤,这显然不起作用,因此COLLECT()始终只有该单个用户。


我的下一次尝试是加载相关节点两次:

START n=node(*)
MATCH n-[:FOLLOWS]->following_filter
    , n-[:FOLLOWS]->following_all
WHERE following_filter.name='John'
RETURN n, COLLECT(following_all)

一开始看起来效果很好,但是当我添加另一个MATCH子句时,我开始重新获得所关注用户的部分列表。知道为什么会这样吗?


另一个可行的解决方案似乎效果很好的是WITHANY

START n=node(*)
MATCH n-[:FOLLOWS]->following
WITH n, COLLECT(following) AS following
WHERE ANY(x in following WHERE x.name='John')
RETURN n, COLLECT(following)

但是,我更喜欢现在避免使用WITH并找到另一种解决方案。我正在使用query builder生成那些尚未支持WITH的查询,并且需要进行一些体系结构更改以添加对此的支持,这需要一些时间。我确实意识到这不是一个很好的理由来避免WITH,我最终会加入对此的支持 - 但我真的更喜欢现在就开始工作并在必要时稍后更改。


我也可以将模式用作WHERE子句:

START n=node(*), john=node(888)
MATCH n-[:FOLLOWS]->following
WHERE n-[:FOLLOWS]->john
RETURN n, COLLECT(following)

但似乎我只能使用ID或lucene索引加载我的“John”节点,并失去Cypher的WHERE的完整表现力。

1 个答案:

答案 0 :(得分:1)

START n=node(*)
MATCH following_all<-[:FOLLOWS]-n-[:FOLLOWS]->following_filter
WHERE following_filter.name='John'
RETURN n, COLLECT(following_all)