Warm tip: This article is reproduced from serverfault.com, please click

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

发布于 2021-12-14 08:36:49

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?

Questioner
Casey Flynn
Viewed
0
Graphileon 2021-12-14 19:50:57

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