Search code examples
neo4jcypherneo4j-ogm

NEO4J find any nodes that have relationships (direct/indirect) with all nodes in a set


I'm new to neo4j so I'm probably making some kind of basic mistake here:

This is a subset of my graph:

enter image description here

I have 3 kinds of nodes:

  • (blue) attribute
  • (red) business
  • (yellow) promotion

attributes can have relationships to promotions and businesses (:TAGS)

This is my best guess cypher query so far.

MATCH(a:Attribute)--(b:Business)--(p:Promotion)
WHERE a.name IN ["business", "casual", "happy_hour"]
RETURN a, b, p
UNION
MATCH(a:Attribute)--(p:Promotion)--(b:Business)
WHERE a.name IN ["business", "casual", "happy_hour"]
RETURN a, b, p;

This isn't quite what I'm looking, it returns promotions related to one or more attributes

I want to only return promotions that have relationships to all attributes in a given set of attributes. How should I do this?


Solution

  • This should work.

    // create collection of myTagNodes
    WITH ["business", "casual", "happy_hour"] AS myTags
    MATCH (myTagNode:TAG) WHERE myTagNode.name IN myTags
    WITH COLLECT(myTagNode) AS myTagNodes
    
    // only return promotions for which all 'myTagNodes'are in the 
    // (indirectly) connected tags, i.e. through buisnesses or directly
    MATCH (p:Promotion)
         WHERE ALL(myTagNode IN myTagNodes 
                   WHERE myTagNode IN [(p)<-[*1..2]-(pTagNode:TAG) | pTagNode] 
               )
    RETURN p
    

    See also https://neo4j.com/docs/developer-manual/current/cypher/syntax/lists/#cypher-list-comprehension and https://neo4j.com/docs/developer-manual/current/cypher/syntax/lists/#cypher-pattern-comprehension