4

How to efficiently construct a query of the form:

MATCH (a)-[:Foo]->(b) WHERE (a)-[:Bar]->(c) AND (a)-[:Bar]->(d) RETURN a

which is a query for

       [Foo]----(b)
(a)---|
       [Bar]----(c)
      |
       [Bar]----(d)

However I would like to have a variable number of destination nodes with relationship Bar (not just c and d, but any list of nodes).

Another way to say it: Return 'a' if it has Bar relationship to [c,d,...] list of nodes

Currently I manually concatenate the WHERE clause as on top, but I feel like there is a sexier way to do this.

PQuinn
  • 992
  • 6
  • 11

1 Answers1

6

Yes, there is a sexier way for this. See http://console.neo4j.org/r/8zx2l2 for a minimal setup of this in Neo4j console. I've used the following cypher query:

MATCH (a:A)-[:Foo]->(b)
WITH a
MATCH (a)-[:Bar]->(other)
WITH a, count(other) AS count
WHERE count=2
RETURN a

The WHERE condition checks if the number of paths equals your requirement (assuming 2 here). So you need only one where check. Is that sexy enough ;-) ?

addendum

In case you want to make sure that the other nodes are in a given list of target nodes:

MATCH (a:A)-[:Foo]->(b)
WITH a
MATCH (a)-[:Bar]->(other)
WITH a, count(other) AS count, collect(other) as others
WHERE all(x in [c,d,....] WHERE x in others) 
RETURN a

This makes sure that a has a Bar relationship to all nodes listed in the array [c,d,...].

Community
  • 1
  • 1
Stefan Armbruster
  • 39,465
  • 6
  • 87
  • 97
  • Thanks, but I need specific c,d nodes to match, not just any nodes with Bar relationship. IOW, return 'a' if it has Bar relationship to [c,d,...] list of nodes. More ideas? – PQuinn Sep 20 '14 at 17:45
  • The "WHERE all(... WHERE ... )" syntax is just what I needed. Thanks! – PQuinn Sep 20 '14 at 23:49