2

So I have a graph database that looks like this:

Neo4J Graph

The only really interesting thing about it is that SomeProperty can be 'Yes' or 'No'.

In the top row, 1 of the 3 nodes have a 'Yes' for this property.

On the bottom row, all 3 nodes have a 'Yes' for this property.

How do I write a Cypher query that returns only the bottom row, by asking the question: Which subgraph has 2 or more values for SomeProperty = 'Yes'?

Here is my code:

CREATE (person:Person {gender: 'Male', name: 'Albert', SomeProperty: 'Yes'})
CREATE (person:Person {gender: 'Female', name: 'Annie', SomeProperty: 'Yes'})
CREATE (person:Person {gender: 'Female', name: 'Adrian', SomeProperty: 'No'})

MATCH (a1:Person),(a2:Person)
WHERE a1.name = 'Albert' AND a2.name = 'Annie'
CREATE (a1)-[r:RELATED_TO]->(a2)
SET r.relationship='related'

MATCH (a1:Person),(a2:Person)
WHERE a1.name = 'Annie' AND a2.name = 'Adrian'
CREATE (a1)-[r:RELATED_TO]->(a2)
SET r.relationship='related'

CREATE (person:Person {gender: 'Male', name: 'Bill', SomeProperty: 'Yes'})
CREATE (person:Person {gender: 'Female', name: 'Barb', SomeProperty: 'Yes'})
CREATE (person:Person {gender: 'Male', name: 'Barry', SomeProperty: 'Yes'})

MATCH (a1:Person),(a2:Person)
WHERE a1.name = 'Bill' AND a2.name = 'Barb'
CREATE (a1)-[r:RELATED_TO]->(a2)
SET r.relationship='related'

MATCH (a1:Person),(a2:Person)
WHERE a1.name = 'Barb' AND a2.name = 'Barry'
CREATE (a1)-[r:RELATED_TO]->(a2)
SET r.relationship='related'
Monica Heddneck
  • 2,973
  • 10
  • 55
  • 89

2 Answers2

1

To return all paths that have more than 2 'Yes' nodes:

MATCH p=(:Person)-[:RELATED_TO*]->(:Person)
WHERE 2 < REDUCE(s = 0, x IN NODES(p) | CASE WHEN x. SomeProperty = 'Yes' THEN s + 1 ELSE s END)
RETURN p;

The REDUCE function is used to calculate the number of nodes with a SomeProperty value of 'Yes'.

cybersam
  • 63,203
  • 6
  • 53
  • 76
  • It returns a collection of the nodes in the path `p`. – cybersam Apr 17 '16 at 18:35
  • This is really amazing -- I never would have used `REDUCE`, mostly because I never knew it existed! Would you mind if I asked you: how would I possibly return the whole graph instead of just the path, given this path in the graph exists? – Monica Heddneck Apr 19 '16 at 02:16
  • What do you mean by "the whole graph"? Do you mean you want to the result to not show sub-paths? – cybersam Apr 19 '16 at 02:41
  • yes! As if, there were 100 more nodes that start with 'B' as an extension of the example above: and I'd like to show all 100 if there are 2 or more out of the 100 that satisfy `SomeProperty`. Maybe I should ask a separate question? – Monica Heddneck Apr 19 '16 at 02:53
  • @cybersam: Ok...I asked a new one :D http://stackoverflow.com/questions/36708177/if-the-number-of-properties-is-greater-than-n-return-a-subgraph-in-neo4j – Monica Heddneck Apr 19 '16 at 03:49
0

I think I am a bit confused, because I am not sure how long a chain can be, if it's always only three then I guess something like this could return them maybe

MATCH (p1)-[r1]-(p2)-[r2]-(p3) 
WHERE (a1.SomeProperty ='Yes' AND a2.SomeProperty ='Yes') 
OR (a1.SomeProperty ='Yes' AND a3.SomeProperty ='Yes') 
RETURN a1,a2,a3 

And if it can be longer then maybe starting finding the 2 nodes

MATCH (a1)-[..]-(a2) 
WHERE (a1.SomeProperty ='Yes' AND a2.SomeProperty ='Yes')
RETURN a1,a2

and then extract the subgraph starting from those nodes as here: Extract subgraph in neo4j

Granted I haven't played with Neo4J all that much, so I am sure someone will pop by and give a better tip

Community
  • 1
  • 1