Reputation: 161
I have a graph that where 'App' nodes connect either directly to other App nodes using a REQUIRES relationship, or via an intermediate Interface object. eg either:
(:App)-[:CONSUMES]->(:Interface)<-[:PROVIDES]-(:App)
or
(:App)-[:REQUIRES]->(:App)
I'm trying to do this using quantified paths to follow these relationships across multiple steps since that allows me to apply conditions (using a WHERE clause) to each step. But I'm having trouble expressing the fact that I want to allow each step between App nodes to be either of these alternatives.
I'm conceptually trying to do the following...
MATCH (a0:App {name: "origin"})
( (a1:App)-[c2:CONSUMES]->(i:Interface)<-[c3:PROVIDES]->(a2:App)
| // <- this isn't valid syntax
(a3:App)-[c4:REQUIRES]->(a4:App)
Where a1.name <> "some condition"
) {1,5}
RETURN ....
Any suggestions on how such alternatives can be described would be appreciated.
Upvotes: 1
Views: 47
Reputation: 67019
You can use the APOC procedure apoc.path.expandConfig instead.
For example, to meet your 2 stated conditions, and assuming you do not want any paths that contain an App
node whose name
is "some condition":
MATCH (a0:App {name: "origin"})
CALL apoc.path.expandConfig(a0, {
minLevel: 1,
maxLevel: 5,
sequence: 'App,CONSUMES>,Interface,<PROVIDES,App|App,REQUIRES>,App',
uniqueness: 'NODE_PATH'
}) YIELD path
WHERE ALL(a1 IN NODES(path) WHERE NOT a1:App OR a1.name <> "some condition")
RETURN path
In this example, the uniqueness value of 'NODE_PATH' is used to prevent any returned path from having cycles (where the same node appears multiple times). You may want to read the docs to see which value is appropriate for your use case.
Upvotes: 0
Reputation: 1426
The alternation syntax you're suggesting is not supported (yet). You could instead insert a relationship REQIURES_VIA_INTERFACE
like so:
MATCH (a:App)-[:CONSUMES]->(:Interface)<-[:PROVIDES]-(b:App)
WHERE NOT EXISTS { (a)-[:REQUIRES_VIA_INTERFACE]->(b) }
CREATE (a)-[:REQUIRES_VIA_INTERFACE]->(b)
Then your query above could become:
MATCH (a0:App {name: "origin"})
( (a1:App)-[c:REQUIRES|REQUIRES_VIA_INTERFACE]->(a2:App)
WHERE a1.name <> "some condition" ){1,5}
RETURN *
Upvotes: 0
Reputation: 286
This isn't possible in a single statement today. It is a feature that is being considered (and if so might actually get the syntax you proposed). For now, you would have to do a UNION between two QPP's.
MATCH (a0:App {name: "origin"})
( (a1:App)-[c2:CONSUMES]->(i:Interface)<-[c3:PROVIDES]->(a2:App)
Where a1.name <> "some condition"
) {1,5}
RETURN ....
UNION
MATCH (a0:App {name: "origin"})
(a3:App)-[c4:REQUIRES]->(a4:App)
Where a1.name <> "some condition"
) {1,5}
RETURN ....
You just need to make sure that the two RETURN statements returns the same things (the same columns)
Upvotes: 0