Reputation: 35
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
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
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