如果关系不存在,则返回节点

wribegjk  于 2022-10-01  发布在  其他
关注(0)|答案(7)|浏览(149)

我正在尝试使用Cypher创建一个查询,该查询将“查找”厨师可能拥有的缺少的配料,我的图表设置如下:

(ingredient_value)-[:is_part_of]->(ingredient)

(ingredient)将有一个键/值,其名称=“Dain Colors”。(ingredient_value)可以具有值=“red”的键/值,并且“是”(ingredient, name="dye colors")的一部分。

(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)

我使用这个查询来获取食谱所需的所有ingredients,而不是它们的实际值,但我希望只返回厨师没有的ingredients,而不是每个食谱所需的所有配料。我试过了

(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)<-[:has_ingredient*0..0]-chef

但这没有任何回报。

这是通过cypher/neo4j就可以完成的事情,还是通过退回所有配料并自己分类来处理最好的事情?

额外好处:还有一种方法可以使用密码将厨师拥有的所有价值观与食谱所需的所有价值观进行匹配。到目前为止,我只返回了chef-[:has_value]->ingredient_value<-[:requires_value]-recipe返回的所有部分匹配,并亲自聚合结果。

wwodge7n

wwodge7n1#

2013-01-10更新:

在Neo4j2.0参考中发现了这一点:

  • 尽量不要使用可选的关系。最重要的是*

  • 不要这样使用:*

  • MATCH a-[r?:LOVES]->() WHERE r IS NULL,您只需确保它们不存在。*

  • 取而代之的是:*

MATCH a WHERE NOT (a)-[:LOVES]->()

使用密码检查关系是否不存在:

...
MATCH source-[r?:someType]-target
WHERE r is null
RETURN source

那个?Mark使关系成为可选的。

在新的4j 2中做:

...
OPTIONAL MATCH source-[r:someType]-target
WHERE r is null
RETURN source

现在您可以检查不存在的(空)关系。

pokxtpni

pokxtpni2#

用于获取不具有任何关系的节点

这是检查关系是否存在的好选择

MATCH (player)
    WHERE NOT(player)-[:played]->()
    RETURN player

您还可以检查多个条件,这将返回所有节点,其中没有“播放”或“不播放”的关系。

MATCH (player) 
 WHERE NOT (player)-[:played|notPlayed]->()
 RETURN player

获取不具有任何关系的节点

MATCH (player) 
WHERE NOT (player)-[r]-()
RETURN player

它将检查没有任何传入/传出关系节点。

yqlxgs2m

yqlxgs2m3#

如果你需要“条件排除”的语义,你可以这样实现。

从neo4j 2.2.1开始,您可以使用OPTIONAL MATCH子句并过滤掉不匹配的(NULL)节点。

OPTIONAL MATCHWHERE子句之间使用WITH子句也很重要,以便第一个WHERE定义可选匹配的条件,而第二个WHERE的行为类似于筛选器。

假设我们有两种类型的节点:PersonCommunication。如果我想要得到所有从未通过电话交流,但可能通过其他方式交流的人,我将进行以下查询:

MATCH (p: Person) 
OPTIONAL MATCH p--(c: Communication) 
WHERE c.way = 'telephone'
WITH p, c 
WHERE c IS NULL 
RETURN p

匹配模式将匹配所有人员与他们的通信,其中对于非电话通信,c将为NULL。然后,过滤器(WITH之后的WHERE)将过滤掉电话通信,留下所有其他通信。

参考资料:

Http://neo4j.com/docs/stable/query-optional-match.html#_introduction_3http://java.dzone.com/articles/new-neo4j-optional

pinkon5k

pinkon5k4#

我写了一个要点,说明如何使用Cypher 2.0很自然地实现这一点

http://gist.neo4j.org/?9171581

关键是使用可选的可用配料匹配,然后比较筛选缺失(空)配料或具有错误值的配料。

请注意,这个概念是声明性的,不需要描述算法,您只需写下您需要的内容。

olmpazwi

olmpazwi5#

最后一个查询应该是:

START chef = node(..)
MATCH (chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)
WHERE (ingredient)<-[:has_ingredient]-chef
RETURN ingredient

此模式:(ingredient)<-[:has_ingredient*0..0]-chef

就是它没有返还任何东西的原因。*0..0意味着关系的长度必须为零,这意味着配料和厨师必须是相同的节点,但它们不是。

oalqel3c

oalqel3c6#

我使用gremlin完成了这项任务。我做了

x=[]

g.idx('Chef')[[name:'chef1']].as('chef')
.out('has_ingredient').as('alreadyHas').aggregate(x).back('chef')
.out('has_value').as('values')
.in('requires_value').as('recipes')
.out('requires_ingredient').as('ingredients').except(x).path()

这返回了所有缺少的配料的路径。我无法用Cypher语言来表述这一点,至少在1.7版中是这样。

bmvo0sr5

bmvo0sr57#

对于新版本的Neo4j,您将看到以下错误:

MATCH (ingredient:Ingredient)
WHERE NOT (:Chef)-[:HAS_INGREDIENT]->(ingredient)
RETURN * LIMIT 100;

此功能已弃用,并将在未来版本中删除。不推荐强制将列表转换为布尔值。请考虑改用NOT isEmpty(...)

要修复它,请执行以下操作:

MATCH (ingredient:Ingredient)
WHERE NOT EXISTS((:Chef)-[:HAS_INGREDIENT]->(ingredient))
RETURN * LIMIT 100;

相关问题