One bill of material relationship is composed of two relationships.
I then find my component definition by searchin this relationship :
(a:Part)-[:consumes]->(b:partBom)-[:referencedBy]->(c:Part)
How can I repeat this pattern in a cypher request in order to find n levels of my bill of material ?
Yoann,
As a follow-on to Michael's answer, if you capture the path in a query of the form
MATCH (a:Part), p=(a)-[:consumes|referencedBy*2..]->(c:Part)
WHERE NOT (c)-[:consumes]->()
WITH a, rels(p) AS rs, nodes(p) AS ns
WITH a, rs, ns, FILTER(n IN ns WHERE 'partBom' IN LABELS(n)) AS boms, FILTER(n in ns WHERE 'Part' in LABELS(n)) AS parts
any following clauses have access to all of the nodes and relationships in the collections ns and rs, and to the BOMs in the collection boms, and the parts in collection parts. The query fragment above will match all of the longest chains of your pattern. You can read more about this relationship pattern concept in the Neo4j manual at this link. You might want to put an upper bound on the number of hops in the initial match if there is a chance of looping.
Grace and peace,
Jim
If you know the number of levels, then you can just spell them out.
(a:Part)-[:consumes]->(b:partBom)-[:referencedBy]->(c:Part)
(c)-[:consumes]->(d:partBom)-[:referencedBy]->(e:Part)
....
Or you can do it more dynamic.
(a:Part)-[:consumes|referencedBy*8]->(c:Part)
WITH rels(path) as rels, nodes(path) as nodes
WHERE ALL(idx in range(0,length(rels)-1,2) WHERE type(rels[idx]) = 'consumes')
AND ALL(idx in range(1,length(rels)-1,2) WHERE type(rels[idx]) = 'referencedBy')
AND ALL(idx in range(1,length(nodes)-1,2) WHERE labels(nodes[idx])[0] = 'partBom')
Usually for something like this, I'd look into the Java API for efficient incremental evaluation of something like that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With