cancel
Showing results for 
Search instead for 
Did you mean: 

Join the community at Nodes 2022, our free virtual event on November 16 - 17.

Traversal across intermediate nodes

espen_solbu
Node Link

I am modelling Software components and their interfaces. A simplified model contains the following labels: SoftwareComponent and Interface. A software component may provide 0 or more Interfaces, and utilize 0 or more interfaces.

An example may look like this:

espen_solbu_0-1656936984272.png

Note that in the real model, both the components and the interfaces has additional relationships to "other things" (aka what they carry, protocols, etc)

I want to write a query that allows me to return the paths to all "downstreams" components from an anchor component.

I have managed to write queries that return almost what i want, but I don't think i'm doing it right...

Closest I have gotten is:

match (p:Component) where p.name STARTS WITH 'A'
WITH p
match path=(p)-[:PROVIDES|UTILIZES*1..5]-(n) WHERE (n:Component or n:Interface) AND (n)-[:UTILIZES]-()
return path

(Since I try to capture multiple (Component)-PROVIDES->(Interface)<-UTILIZES-(Component), I cannot use direction on those relationships)

However, I have been unable to restrict this to only show the paths that are downstreams. Aka i'd like the full path from p, (:Component)-PROVIDES->(:Interface)<-UTILIZES-(:Component), all the way down to the bottom Component or Interface.

Also if i remove the relationship restriction (5 in the example), the query now takes forever. 

I am sure there must be a better way to collect all the downstream interfaces and components. Any suggestions?

 

regards

Espen

1 ACCEPTED SOLUTION

bennu_neo
Neo4j
Neo4j

Hi @espen_solbu !

Have you already installed APOC? If you haven't... do it. 😄  In any case, something like this may work:

 

match (p:Component) where p.name STARTS WITH 'A'
WITH p
CALL apoc.path.spanningTree(p, {
    relationshipFilter: "PROVIDES>|<UTILIZES",
    labelFilter: "Component|Interface",
    minLevel: 1,
    maxLevel: 5 //??
})
YIELD path
with path //, last(nodes(path)) as n ??
//where not (n)<-[:UTILIZES]-() ??
RETURN path

 

Oh, y’all wanted a twist, ey?

View solution in original post

3 REPLIES 3

bennu_neo
Neo4j
Neo4j

Hi @espen_solbu !

Have you already installed APOC? If you haven't... do it. 😄  In any case, something like this may work:

 

match (p:Component) where p.name STARTS WITH 'A'
WITH p
CALL apoc.path.spanningTree(p, {
    relationshipFilter: "PROVIDES>|<UTILIZES",
    labelFilter: "Component|Interface",
    minLevel: 1,
    maxLevel: 5 //??
})
YIELD path
with path //, last(nodes(path)) as n ??
//where not (n)<-[:UTILIZES]-() ??
RETURN path

 

Oh, y’all wanted a twist, ey?

espen_solbu
Node Link

Thanks! that worked perfectly! 

I guess there isnt a way to do "arbitrary lengths of subqueries" in native cypher?

Two comments for others reading this thread:

  • typo in the query in the acccepted answer, need a comma after "Component|Interface" in the answer above
  • One can remove the maxLevel: 5 entry to make it go out further

 

Hi @espen_solbu,

I solved the first type. Sorry about that. Yes, you can remove the min and max level as well as play with other variables. Native Cypher supports arbitrary lengths but it will not do it based on directions sub patterns (yet 😉). 

Lemme know if I can help you in any other way 

Bennu

Oh, y’all wanted a twist, ey?