0
votes

I have a sample graph as depicted below.

enter image description here The nodes have the following labels:

  • node (a) has label User
  • nodes (b) until (g) have label Attribute
  • nodes (h) and (i) have label Object

Node (a) has a relationship to (d) and also to (e)

I want to check which of the Object nodes (h) and (i) have relationships to all of the Attribute nodes that the user is connected to, i.e. (d) and (e).

So

  • node (h) has a relationship to (d) AND to (e) --> this is ok
  • node (i) only has a relationship to (e) --> this is not ok

How would I detect this in a Cypher query?

I started with something like:

MATCH p1 = (u:User)-->(ua:Attribute)-->(oa:Attribute)
WITH *
MATCH p2 = (oa)<-[*]-(o:Object)
RETURN p1,p2

This gives me the complete graph. But how do I refine this to get only (h) back and not (i).

I guess I will have to build a list of results from the first part and validate if a relation exist to all of these?

1

1 Answers

2
votes

You can check this with the ALL predicate :

// First retrieve the Attribute nodes the User is connected to and make it a collection
MATCH (u:User)-[:ASSOCIATED_TO]->(attribute)
WITH u, collect(attribute) AS attributes
// Find the objects having relationships to ALL elements in attributes
MATCH (o:Object) WHERE 
ALL( x IN attributes WHERE (o)--(x) )
RETURN u, attributes, collect(o) AS objects