我试图创建一个使用暗号,将“查找”,一个厨师可能缺少的成分查询,我的图形设置,如下所示:
(ingredient_value)-[:is_part_of]->(ingredient)
(ingredient)
将具有名称=“染料颜色”键/值。 (ingredient_value)
可以具有值=“红”的键/值和“是的一部分”的(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
但这返回任何内容。
这是不是可以通过暗号/ Neo4j的完成或者是这个东西,最好是通过返回所有成份处理,并通过他们自己的排序?
奖金:也有使用暗号,以匹配厨师有一个方案要求所有值所有值的方法。 到目前为止,我只返回被返回的所有部分匹配chef-[:has_value]->ingredient_value<-[:requires_value]-recipe
和综合这些结果自己。
更新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
现在,你可以检查不存在的(空)的关系。
对于没有任何关系获取节点
这是检查关系存在与否的好选择
MATCH (player)-[r:played]->()
WHERE r IS NULL
RETURN player
您还可以检查多个条件为此,它会返回所有节点,没有“打”或“notPlayed”的关系。
MATCH (player)
WHERE NOT (player)-[:played|notPlayed]->()
RETURN player
抓取其不具有任何realtionship节点
MATCH (player)
WHERE NOT (player)-[r]-()
RETURN player
它将检查节点不具有任何呼入/呼出的关系。
如果你需要“有条件排除”的语义,就可以实现这种方式。
由于Neo4j的2.2.1,您可以使用OPTIONAL MATCH
条款并筛选出无与伦比的( NULL
)节点。
同样重要的是使用WITH
之间子句OPTIONAL MATCH
和WHERE
子句,使得第一WHERE
限定用于可选的匹配,并且第二条件WHERE
表现得像一个过滤器。
假设我们有2种类型的节点: 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
的非电话通信。 然后过滤器( WHERE
后WITH
)将筛选出的电话通讯留给所有其他人。
参考文献:
http://neo4j.com/docs/stable/query-optional-match.html#_introduction_3 http://java.dzone.com/articles/new-neo4j-optional
我写了如何实现很自然的Cypher使用2.0来完成一个要点
http://gist.neo4j.org/?9171581
关键的一点是要使用的可选匹配现有的材料,然后比较筛选缺失(空)成分或配料用错误的值。
请注意,这个概念是声明,并不需要描述的算法,你只需写下你所需要的。
我用小鬼完成了这个任务。 我做了
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版本。
最后查询应该是:
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
意味着该关系的长度必须是零,这意味着,成分和厨师必须是相同的节点,该节点它们不是。