Julian
Julian

Reputation: 35

Cypher - Match node by properties of its connected nodes?

We've built a Neo4j model where each "Entity" node is linked to a set of "Attribute" nodes, each of which carrying one "label" and one "value" properties.

What would be the (most efficient) Cypher request to fetch that "Entity" node that has all the requested "Attribute" neighbours given their "label"/"value" properties?

Upvotes: 1

Views: 347

Answers (2)

cybersam
cybersam

Reputation: 66999

Assuming you use the HAS relationship type, and you pass a props parameter containing a list of the desired label/value pairs in the following sample format: [['foo', 123], ['bar', true], ['foo', 234], ['baba', 'black sheep']], this query should work:

MATCH (e:Entity)
WHERE ALL(p IN $props WHERE SIZE([(e)-[:HAS]->(a:Attrib) WHERE a[p[0]] = p[1] | 1]) > 0)
RETURN e

[UPDATE]

The returned e nodes must have related Attrib node(s) containing all the property name and value pairs that are in the props parameter.

A pattern comprehension must specify a projection, so this query just uses 1 as the projection since we don't care about the contents of the generated list. We only care about the testing size of the list.

To test the above query with the sample props parameter value, first create some suitable nodes and relationships. For example:

CREATE (e:Entity {id: 1}),
  (e)-[:HAS]->(:Attrib {id: 22, foo: 123, bar: true}),
  (e)-[:HAS]->(:Attrib {id: 33, baba: 'black sheep'}),
  (e)-[:HAS]->(:Attrib {id: 44, foo: 234})

Upvotes: 1

Julian
Julian

Reputation: 35

So I ended up creating the following attributes:

:params {props: [["name", "Athanase"], ["age", 22], ["color", "blue"]]}

I then updated the query as such:

MATCH (e:Entity) WHERE ALL(p IN $props WHERE SIZE ([(e)-[:HAS]->(a:Attrib) WHERE (a.label = p[0] AND a.value = p[1]) | 1]) > 0) RETURN e;

Looks like it is working fine.

Upvotes: 0

Related Questions