97

我正在尝试使用密码创建一个查询,该查询将“查找”厨师可能拥有的缺失成分,我的图表设置如下:

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

(ingredient)将具有名称 =“染料颜色”的键/值。 (ingredient_value)可能具有 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 完成的事情,还是最好通过返回所有成分并自己对它们进行分类来处理?

奖励:还有一种方法可以使用 cypher 将厨师拥有的所有值与食谱所需的所有值相匹配。到目前为止,我只返回了 a 返回的所有部分匹配项,chef-[:has_value]->ingredient_value<-[:requires_value]-recipe并自己汇总了结果。

4

6 回答 6

166

2013 年 1 月 10 日更新:

在 Neo4j 2.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

这 ?标记使关系可选。

或者

在 neo4j 2 中:

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

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

于 2013-01-10T09:09:41.337 回答
20

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

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

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

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

于 2014-12-08T07:31:48.917 回答
8

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

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

在andWITH子句之间使用子句也很重要,这样第一个子句定义了可选匹配的条件,第二个子句的行为类似于过滤器。OPTIONAL MATCHWHEREWHEREWHERE

假设我们有 2 种类型的节点:PersonCommunication. 如果我想获取所有从未通过电话交流但可能以其他方式交流的人,我会提出以下查询:

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

匹配模式将匹配所有人员与他们的通信,其中cNULL用于非电话通信。然后过滤器(WHEREWITH)将过滤掉电话通信而留下所有其他通信。

参考:

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

于 2015-05-08T13:25:03.263 回答
2

我使用 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()

这返回了所有缺失成分的路径。我无法用密码语言来表述这一点,至少对于 1.7 版来说是这样。

于 2012-06-11T07:12:10.800 回答
2

最后一个查询应该是:

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意味着关系的长度必须为零,这意味着成分和厨师必须是同一个节点,但它们不是。

于 2012-06-09T08:49:51.463 回答
2

我写了一个要点,展示了如何使用 Cypher 2.0 很自然地做到这一点

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

关键是对可用成分使用可选匹配,然后比较以过滤缺失(空)成分或具有错误值的成分。

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

于 2014-02-23T14:13:40.967 回答