Neo4j:多个谓词过滤器

时间:2013-10-12 12:23:05

标签: neo4j cypher

我创建了一个图形结构。如果它们存在以下关系

Fever --causes--> Malaria  ,  Fever --causes--> dehydration
Flu   --causes--> Malaria  ,  Flu   --causes--> SwineFlu

现在我想编写一个cypher查询,它返回Fever和Flu的原因交集,这里的输出应该是Malaria。

我正在编写以下查询,但它没有给我任何节点。

START aa=node(*) MATCH (aa)-[:causes]->(symptoms) 
WHERE (aa.Name = "Fever") AND (aa.Name = "Flu") RETURN distinct symptoms;

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:3)

尝试在OR子句中使用AND代替WHERE

修改

我认为它有两个部分。

首先,对于你的'原因交叉',你应该陈述一个表达交叉点的模式。可以认为它确切地说明了您想要返回的数据,然后根据图表中的内容打开或概括您想要填充的模式的那些部分。如果我理解你的模型和你的意图,那就会产生类似

的模式
(fever)-[:CAUSES]->(malaria)<-:[CAUSES]-(flu)

节点的标识符只是占位符,但让它们代表您已经知道流感和发烧都与疟疾有这种关系。然后,如果你想问,“流感和发烧之间有什么关系?”你可以把它概括为

(fever)-[:CAUSES]->(unknown)<-[:CAUSES]-(flu)

这些模式本身对于密码是相同的,但是因为你将提供两个已知的节点,流感节点和发烧节点,并且你知道你想要根据某种关系共同拥有的东西,那么你可以声明正是这种模式,只留下了常见的未知节点。

其次,您需要使用您已知的节点填充此模式。如果您要匹配模式,它的唯一已知部分是关系的类型和方向,您会发现以这种方式相关的所有节点三元组。因此,如果您希望此模式仅与流感和发烧相匹配,则需要在模式中提供或填充这些节点。通常你会用索引查找(直到2.0被重新发布),比如

START flu=node:Symptom(name="Flu"), fever=node:Symptom(name="Fever")

然后在MATCH子句中继续执行您的模式。这样,除了您正在寻找的一个未知节点之外,模式完全填充。 (请注意,您可以使用一包节点和单个节点填充模式中的占位符,但该模式的该部分仍属于模式中提供的内容。)如果您没有索引,则可以填写使用“所有节点”进行流感和发烧的占位符,然后提供进一步的过滤标准。这很糟糕,但确实有效。

START flu=node(*), fever=node(*) 
MATCH (flu)-[:CAUSES]->(unknown)<-[:CAUSES]-(fever) 
WHERE flu.Name="Flu" AND fever.Name="Fever" 
RETURN DISTINCT unknown

答案 1 :(得分:2)

你可以这样做:

START aa=node(*) 
MATCH aa-[:causes]->symptom 
WITH collect(aa.name) AS aa, symptom 
WHERE ALL (x IN ['Fever' , 'Flu'] 
           WHERE x IN aa) 
RETURN symptom

http://console.neo4j.org/r/7awspi

但理想情况下,你会进行索引查找,类似于此。

START aa=node:node_auto_index('name:("Fever", "Flu")') 
MATCH aa-[:causes]->symptom 
RETURN symptom, count(*) 
ORDER BY count(*) DESC

http://console.neo4j.org/r/bawo5d