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

Neo4j 如果关系不存在,则返回节点,neo4j,cypher,Neo4j,Cypher,我正在尝试使用cypher创建一个查询,该查询将“查找”厨师可能缺少的配料,我的图表设置如下: (ingredient_value)-[:is_part_of]->(ingredient) (配料)的键/值为name=“染料颜色”(配料值)可以有value=“red”和“是(配料,name=“染料颜色”)的键/值 但这没有任何回报 这是cypher/neo4j可以完成的事情,还是返回所有成分并自己进行分类是最好的处理方式 另外,还有一种方法可以使用cypher将厨师拥有的所有值与食谱要求

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

(ingredient_value)-[:is_part_of]->(ingredient)
(配料)
的键/值为name=“染料颜色”<代码>(配料值)可以有value=“red”和“是
(配料,name=“染料颜色”)
的键/值

但这没有任何回报

这是cypher/neo4j可以完成的事情,还是返回所有成分并自己进行分类是最好的处理方式


另外,还有一种方法可以使用cypher将厨师拥有的所有值与食谱要求的所有值进行匹配。到目前为止,我只返回了由
chef-[:has_value]->component_value返回的所有部分匹配。最后一个查询应该是:

START chef = node(..)
MATCH (chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)
WHERE (ingredient)<-[:has_ingredient]-chef
RETURN ingredient
START chef=节点(…)
搭配(厨师)-[:有价值]->(配料价值)(配料)

其中(成分)我使用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版是这样。

2013年10月1日更新:

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

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

不要这样使用它们:

匹配a-[r?:LOVES]->(),其中r为NULL
您只需确保它们不存在

而是这样做:

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

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

...
MATCH source-[r?:someType]-target
WHERE r is null
RETURN source
那个?mark使关系成为可选关系

在neo4j 2中,请执行以下操作:

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

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

我写了一个要点,说明如何使用Cypher 2.0非常自然地完成这项工作

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

关键的一点是使用可选的匹配到可用的成分,然后比较缺少(空)成分或成分值错误的过滤器


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

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

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

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
它将检查没有任何传入/传出关系的节点。

如果需要“条件排除”语义,可以通过这种方式实现

MATCH (player) 
 WHERE NOT (player)-[:played|notPlayed]->()
 RETURN player
从neo4j 2.2.1开始,您可以使用
可选匹配
子句并过滤掉不匹配的(
NULL
)节点

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

假设我们有两种类型的节点:
Person
Communication
。如果我想让所有从未通过电话沟通但可能通过其他方式沟通的人都参与进来,我会提出以下问题:

MATCH (p: Person) 
OPTIONAL MATCH p--(c: Communication) 
WHERE c.way = 'telephone'
WITH p, c 
WHERE c IS NULL 
RETURN p
匹配模式将所有人员与其通信进行匹配,其中对于非电话通信,
c
将为
NULL
。然后过滤器(
,其中
之后,带有
)将过滤掉所有其他电话通信

参考资料:


是,但它不会返回所需的成分。在Neo4j 2.0中,使用OPTIONAL MATCH来匹配可选关系,即第一个示例看起来像OPTIONAL MATCH(源)-[r:someType]-(目标)返回源,我试图在其中有一个标记的节点,但它不起作用。比如:匹配一个WHERE NOT(a)-[:LOVES]->(陌生人),在这个“陌生人”中是一个节点标签。我使用的是neo4j版本2.1.2Evermind,我理解为什么您希望显示实现此答案的过程:匹配a WHERE NOT(a)-[:LOVES]->()
MATCH a…
示例现在应该是
MATCH(a)WHERE NOT(a)-[:LOVES]->()
@gil stal为什么我不能像这样在这个查询中使用节点名。匹配a,其中不匹配(a)-[:LOVES]->(b:SomeLabel)。如果我不使用节点名,它就会工作。
MATCH(player)WHERE NOT(player)-[r]-()RETURN player
给出变量r NOT defined error。如何定义r?若要解决此问题,请指定一个关系(例如
(player-[:rel]-()
),或将任何关系
(player-[]-()
匹配(player)而不是(player)-[]-()RETURN player
-效果很好您的第一个查询实际上是错误的。匹配模式本身总是只返回现有的关系,没有一个是空的。因此您的WHERE行没有任何可过滤的内容。@CristiS。感谢您让我知道。我已经更新了查询,它应该可以工作。有关v3:供未来用户使用的信息,请查看此处;有关详细信息,可以在
WHERE
子句中使用
exists
(也可以将其否定)。