英文:
Retrieve nodes where all relationships match a criteria in neo4j
问题
我正在尝试检索那些与该节点的所有关系都不具有特定属性值的节点。例如,我希望查询在以下示例中返回foo
,因为与foo
的所有关系都具有prop = false
。
(bar0) -[{prop:false}]-> (foo) <-[{prop:false}]- (bar1)
另一方面,在以下示例中,我希望查询返回null
,因为与foo
的一部分关系具有prop = true
。
(bar0) -[{prop:false}]-> (foo) <-[{prop:true}]- (bar1)
到目前为止,我尝试过:
MATCH (foo)-[r]-(bar)
WITH collect(r) as rs, foo, bar
WHERE NONE(r in rs WHERE r.prop = True)
UNWIND rs as r
RETURN foo, bar, r
然而,这仍然返回了foo
,只是删除了prop = True
的关系。
我还尝试使用CASE
,但遇到了相同的问题。
MATCH (foo)-[r]-(bar)
WITH collect(r) as rs, foo
RETURN
CASE
WHEN ALL(r in rs WHERE r.prop=False)
THEN foo
ELSE null
END
理想情况下,查询还将返回没有任何关系的节点,但我也可以使用单独的查询处理这一点。
英文:
I'm trying to retrieve nodes where none of the relationships to that node have a specific property value. For example, I would like the query to return foo
in the following example, because both relationships to foo
have prop = false
.
(bar0) -[{prop:false}]-> (foo) <-[{prop:false}]- (bar1)
On the other hand, I would like the query to return null
in the following example, because a subset of the relationships to foo
have prop = true
.
(bar0) -[{prop:false}]-> (foo) <-[{prop:true}]- (bar1)
So far, I've tried:
MATCH (foo)-[r]-(bar)
WITH collect(r) as rs, foo, bar
WHERE NONE(r in rs WHERE r.prop = True)
UNWIND rs as r
RETURN foo, bar, r
However, this still returns foo
, it just removes the relationship where prop = True
.
I also tried using CASE
, but run into the same problem.
MATCH (foo)-[r]-(bar)
WITH collect(r) as rs, foo
RETURN
CASE
WHEN ALL(r in rs WHERE r.prop=False)
THEN foo
ELSE null
END
Ideally, the query would also return nodes with no relationships as well, but I can also handle that with a separate query.
答案1
得分: 2
这个查询使用EXISTS()
函数来避免扫描所有与每个Foo
节点相关的关系,以找到感兴趣的关系。一旦找到一个true
关系,它就会将一个Foo
节点过滤掉。
MATCH (foo:Foo)
WHERE NOT EXISTS((foo)<-[{prop: true}]-())
MATCH (foo)<-[r]-(bar)
RETURN foo, bar, r
*这个查询还使用了有方向的关系,以符合指定的数据模型。
英文:
This query uses the EXISTS()
function to avoid having to scan all relationships to every Foo
node to find the ones of interest. It filters out a Foo
node as soon as a true
relationship is found.
MATCH (foo:Foo)
WHERE NOT EXISTS((foo)<-[{prop: true}]-())
MATCH (foo)<-[r]-(bar)
RETURN foo, bar, r
This query also uses a directional relationship, to conform to the stated data model.
答案2
得分: 1
如果你想要仅返回没有 r{prop:True}
的节点,一种选择是:
OPTIONAL MATCH (ft:Foo)<--[r{prop:True}]-(b:Bar)
WITH COLLECT(ID(ft)) as ft_ids
MATCH (f:Foo)
WHERE NOT ID(f) IN ft_ids
RETURN DISTINCT (f)
对于示例数据:
MERGE (a1:Foo {name: 'a1'})
MERGE (a2:Foo {name: 'a2'})
MERGE (b1:Bar {name: 'b1'})
MERGE (b2:Bar {name: 'b2'})
MERGE (b3:Bar {name: 'b3'})
MERGE (a3:Foo {name: 'a3'})
MERGE (a4:Foo {name: 'a4'})
MERGE (b1)-[:POINTS{prop:true}]-(a1)
MERGE (b2)-[:POINTS{prop:true}]-(a1)
MERGE (b3)-[:POINTS{prop:false}]-(a2)
MERGE (b1)-[:POINTS{prop:false}]-(a2)
MERGE (b2)-[:POINTS{prop:false}]-(a3)
MERGE (b1)-[:POINTS{prop:true}]-(a3)
返回结果为:
╒═════════════╕
│"f" │
╞═════════════╡
│{"name":"a2"}│
├─────────────┤
│{"name":"a4"}│
└─────────────┘
不清楚你想要获取哪些关系和 bars
...
英文:
If you want to get back only nodes with no r{prop:True}
, one option is:
OPTIONAL MATCH (ft:Foo)<-[r{prop:True}]-(b:Bar)
WITH COLLECT(ID(ft)) as ft_ids
MATCH (f:Foo)
WHERE NOT ID(f) IN ft_ids
RETURN DISTINCT (f)
Which for sample data:
MERGE (a1:Foo {name: 'a1'})
MERGE (a2:Foo {name: 'a2'})
MERGE (b1:Bar {name: 'b1'})
MERGE (b2:Bar {name: 'b2'})
MERGE (b3:Bar {name: 'b3'})
MERGE (a3:Foo {name: 'a3'})
MERGE (a4:Foo {name: 'a3'})
MERGE (b1)-[:POINTS{prop:true}]-(a1)
MERGE (b2)-[:POINTS{prop:true}]-(a1)
MERGE (b3)-[:POINTS{prop:false}]-(a2)
MERGE (b1)-[:POINTS{prop:false}]-(a2)
MERGE (b2)-[:POINTS{prop:false}]-(a3)
MERGE (b1)-[:POINTS{prop:true}]-(a3)
returns:
╒═════════════╕
│"f" │
╞═════════════╡
│{"name":"a2"}│
├─────────────┤
│{"name":"a4"}│
└─────────────┘
It is not clear which relationships and bars
you want to get back...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论