1
votes

I'm working on a project modeling product use patterns and I'm having trouble identifying the best way to make an exact match to a single pattern

In the model I have several "product_pattern" nodes acting as the center or hub to several nodes representing various products. Each product node is unique and can be connected to any product_pattern. A series of product pattern nodes may look like:

--pattern_1
--- Product A
--- Product B
--- Product C

--pattern_2
--- Product A
--- Product B
--- Product C
--- Product D

--pattern_3
--- Product B
--- Product C

I would like to query the graph for product_patterns that use products B and C and ONLY B and C. If I just used:

Start b = node(16), c = node(37)
MATCH (b)<-[:PRODUCT_USED]-(n)-[:PRODUCT_USED]->(c)
RETURN n

I would have all product_patterns returned because they all have relationships to B and C. To Remove matches that have additional relationships from what I'm querying I foresee two strategies..

  1. Create a property in each pattern node of product_pattern.num_products to use against a WHERE clause after the initial MATCH. In this case the num_products property would have to match '2' for nodes with relationships ONLY to B and C. My concern here is that I have to dig into each returned node for properties and popular products will make the return list much larger.

  2. Create a WHERE NOT clause for every other product in the graph that I don't won't a relationship to... not ideal and most likely traversing the entire graph.

Are there any elegant ways to confirm that your query returns exactly the relationship match you ask for and not nodes that match your query but also have additional relationships?

1

1 Answers

2
votes

Can you try this:

Start b = node(16), c = node(37)
MATCH (b)<-[:PRODUCT_USED]-(n)-[:PRODUCT_USED]->(c)
WHERE length((n)-[:PRODUCT_USED]->(c)) == 2
RETURN n