1
votes

I have created one graph structure .Of them there are some relationship as follows

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

Now I want to write a cypher query which returns intersection of causes by Fever and Flu , Means here output should be Malaria.

I am writing the following query , but it is giving me no nodes.

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

Any help would be appreciated!

2
neo version? do you have any indexes do look things up?Eve Freeman
Nope , will there be indexes required , because when i search for causes by fever , it gives me proper results.pawan9977
You should have an index on Name, so it doesn't need to scan the graph to find them. Are you using neo 1.9 or 2.0? The reason you aren't getting any results is because you'll never have two different values for aa.Name in the same intermediate result, so you have to either use OR and count them, or if you want to only find these results, they need to be matched separately.Eve Freeman
I am using 1.9 , yeah i will create indexes when i have a graph structure containing more nodes , right now i just want to get result , "OR" not giving right result , can u write me down how to match them separately ?pawan9977

2 Answers

3
votes

Try using OR instead of AND in your WHERE clause.

Edit:

I think there are two parts two it.

First, for your 'intersection of causes', you should state a pattern that expresses that intersection. Think of it as stating exactly what data you want back, and then open up or generalize those parts of the pattern that you want to be filled in based on what's in your graph. If I understand your model and your intention this would make a pattern like

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

The identifiers for the nodes are only placeholders, but let them represent that you already know that flu and fever both have a relationship of this type to malaria. Then if you want to ask, "What are all the things that have this relationship both to flu and to fever?" you can generalize it as

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

In themselves these patterns are identical for cypher, but since you will provide two known nodes, the flu node and the fever node, and you know that you want something they have in common according to a certain relation, then you can declare precisely that pattern, and only leave out the unknown node that is common.

Second, you need to fill this pattern with the nodes that you already know. If you were to match the pattern as it is, the only known parts of it being the type and direction of the relationships, you would find all triplets of nodes related in that way. So if you want this pattern matched only for flu and fever, you need to provide or fill in these nodes into the pattern. Normally you will do this with index lookups (until 2.0 is realeased anyway), like

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

and then proceed with your pattern in a MATCH clause. That way the pattern is filled in completely except for the one unknown node that is the one you are looking for. (Note that you can fill in a placeholder in a pattern with a bag of nodes as well as single ones, but that part of the pattern still belongs to what's provided in the pattern.) If you don't have indexes you can fill in the placeholders for flu and fever with 'all nodes' and then provide a further filtering criteria. This is bad, but it works.

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

You could do something like this:

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

But ideally you would do an index lookup, similar to this.

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