Reputation: 23
Here is a simplified schema of my Neo4j DB model. I tried several Cypher queries based on some posts, but nothing work.
I would like to find all the components and all the suppliers, for a bike number.
The complexity is that some components are linked to suppliers and in that cases, the branch is followed only if the upper component has the right version.
Examples:
I would like to get the nodes and the relationships.
Can someone help me ?
Upvotes: 0
Views: 174
Reputation: 8833
Basically, what you want is to pull all sub-graph items but filtering out relations paths that fail a filter. You can use ALL/NONE/ANY to make sure the picked up paths don't violate any constraints.
Here is an example that assumes that from and to can be defined independently, but I think it is clear enough to adjust to your needs as you like. (Note: You can use TYPE(r)
to check the relation type name too)
WITH 11 as num
MATCH p=(s:Bike)-[*..25]-(n)
WHERE
ALL(r IN RELATIONSHIPS(p) WHERE
(NOT EXISTS(r.RANGEFROM) OR toInteger(r.RANGEFROM) <= num) AND
(NOT EXISTS(r.RANGETO) OR num <= toInteger(r.RANGETO)))
AND TYPE(RELATIONSHIPS(p)[-1]) = "LO"
WITH NODES(p) as ns, RELATIONSHIPS(p) as rs
UNWIND ns as n UNWIND rs as r
RETURN COLLECT(DISTINCT n), COLLECT(DISTINCT r)
Or this should be more efficient.
WITH 11 as num
MATCH (ci)-[lo:LO]->(ds)
WHERE toInteger(lo.RANGEFROM) <= num <= toInteger(lo.RANGETO)
WITH ds, COLLECT(lo) as lo
MATCH p=shortestpath((b:Bike)-[*..25]->(ds))
WHERE ALL(r IN RELATIONSHIPS(p) WHERE TYPE(r) <> "LO" OR r in lo)
WITH NODES(p) as ns, RELATIONSHIPS(p) as rs
UNWIND ns as n UNWIND rs as r
RETURN COLLECT(DISTINCT n), COLLECT(DISTINCT r)
Note: If you need better performance, you might want to look into using the Neo4J Traversal API.
Upvotes: 0
Reputation: 2656
Not sure if I understand correctly, but would this work ?
MATCH p=(b:Bike {bnumber = 6})-[hc:HAS_COMPONENT]-(c:Component)-[hs:HAS_SUPPLIER]-(s:Supplier)
WHERE hs.frombike >= bnumber
AND hs.tobike <= bnumber
RETURN p;
I agree with @cybersam that you could do with a simplification of the model. Do raise that concern.
Hope this helps.
Regards, Tom
Upvotes: 1
Reputation: 66947
Here is a simple data model. In addition to the Bike
, Component
, and Supplier
node labels, this model adds a Part
node label.
(b:Bike)-[HAS_COMPONENT]->(c:Component)-[:IS_PART]->(p:Part)
(c)-[:SUPPLIED_BY]->(s:Supplier)
In this model:
Part
is a specific item made by a specific manufacturer, and it can be sold by any number of Supplier
s.Bike
is made up of multiple Component
s, each of which is a Part
that was purchased from a specific Supplier
.With this model, here is a sample query to return, for a specific bike, each component part and its supplier:
MATCH
(:Bike {id: 1})-[HAS_COMPONENT]->(c)-[:IS_PART]->(part),
(c)-[:SUPPLIED_BY]->(supplier)
RETURN part, supplier;
Upvotes: 3