Restricting path to a list of nodes and relationship types

Hi,

How can i mention the allowed Labels and Relationship in a path query.

Also,
Please give some pointers to cypher manual, where i can query closed loops in Nodes.
If my query is too complex, can I use Traversal framework. Because, I see Deprecated messages in the Documents.

Thanks,
Murali V

Hello @murali.venugopal and welcome to the Neo4j community :slight_smile:

You should have a look at the apoc.path.expandConfig() function in the APOC plugin.

Regards,
Cobra

I am going to assume you are asking about the syntax for specifying node labels and relationship types along a path query, or any query for that matter.

Node label criteria syntax:

  1. 'match(n:X:Y)' will match nodes that have both X and Y labels
  2. 'match(n) where n:X or n:Y' will match nodes with either labels
  3. 'match(n) where any(label in labels(n) where label in ['X', 'Y', 'Z']) will match nodes with any of the labels 'X', 'Y', or 'Z'. This syntax would be more compact than listing separate labels in the where clause as in 2, if there are many labels

Relationship label criteria:

  1. 'match(n)-[r:X|Y|Z]->(p)' will match paths with a relationship that has either 'X', 'Y', or 'Z' labels (remember relationships can have zero or one types, unlike a node with can have multiple labels)
  2. match(n)-[r]->(p) where r:X or r:Y or r:Z' is an alternative form to item 1, but this is less compact.

I find the Cypher docs to be very helpful. The Match clause section will discuss searching by node labels and relationship types.

I also like the cypher quick reference when recalling syntax and behavior, after reading the cypher manual.

https://neo4j.com/docs/cypher-refcard/current/

If this is not the information you were looking for, can you direct me better and I will try to help.

1 Like

@Cobra ,
Thanks for your reply and it worked. But, in my sample dataset. like this.


with the query,
MATCH (one:Dev {id : "1"})
CALL apoc.path.expandConfig(one, {
relationshipFilter: "INTERFACE|IS_CONNECTED_TO",
labelFilter: "Dev|Int",
minLevel: 10,
maxLevel: 20
})
YIELD path
RETURN path, length(path) AS hops
ORDER BY hops;

But in my actual dataset like this

with the query,
MATCH (sma:Device {ip: "x.x.x.x"})
CALL apoc.path.expandConfig(sma, {
relationshipFilter: "HAS|CONNECTED",
labelFilter: "Device|Interface",
minLevel: 10,
maxLevel: 30
})
YIELD path
RETURN path, length(path) AS hops
ORDER BY hops;

the query takes for ever.
so i tried limiting the nodes using whitelistNodes, but that returned none.
am i doing something basically wrong here. Please suggest.

Regards,
Murali V

Hi @glilienfield

thanks for your support. please look at my sample dataset. I'm basically modelling a Metro Ether Network Ring in an ISP Environment. Which consists of LLDP data of Device and Interface connected to each other.

please use the below sample data to evaluavate.

LD LI RI RD
1 12 21 2
2 23 32 3
3 34 43 4
4 45 54 5
5 51 15 1
1 16 61 6
6 67 76 7
7 78 87 8
8 81 18 1
![image 257x201](upload://abrkDiamBDM2rwDVDJlXMio2w2D.png)

LD - Local Device, LI - Local Interface, RI - Remote Interface, RD - Remote Device

import statements for the above data is given below.

LOAD CSV WITH HEADERS FROM 'file:///sample.csv' AS row
MERGE (ld:Dev {id : row.LD})
MERGE (li:Int {name : row.LI})
MERGE (ri:Int {name : row.RI})

LOAD CSV WITH HEADERS FROM 'file:///sample.csv' AS row
MATCH (ld:Dev {id : row.LD})
MATCH (li:Int {name : row.LI})
MERGE (ld) -[:INTERFACE]- (li)

LOAD CSV WITH HEADERS FROM 'file:///sample.csv' AS row
MATCH (rd:Dev {id : row.RD})
MATCH (ri:Int {name : row.RI})
MERGE (rd) -[:INTERFACE]- (ri)

LOAD CSV WITH HEADERS FROM 'file:///sample.csv' AS row
MATCH (li:Int {name : row.LI})
MATCH (ri:Int {name : row.RI})
MERGE (li) -[:IS_CONNECTED_TO]- (ri)

im using the below whitelistNodes but i cannot get the loop

MATCH (one:Dev {id : "1"})
MATCH (allowed:Dev)
WHERE allowed.id IN ["1", "2", "3", "4", "5"]
WITH one, collect(allowed) as allowedNodes
CALL apoc.path.expandConfig(one, {
relationshipFilter: "INTERFACE|IS_CONNECTED_TO",
labelFilter: "Dev|Int",
minLevel: 10,
maxLevel: 20,
whitelistNodes: allowedNodes
})
YIELD path
RETURN path, length(path) AS hops
ORDER BY hops

I briefly looked at the source code of that apoc procedure. It relies on the Traversal framework, which has been deprecated, so I am not sure you want to build a new application using it.

The Traversal framework traverses your graph from a starting node and expands the graph at each node based on a number of configurations, such as node labels, relationship types, and many more. At the end you will get a whole bunch of paths originating from your starting node that comply with your configuration constraints. You results using real data then look feasible based on this. It doesn't sound like this is what you want. What other constraints to you want to impose on your answer? You mentioned this models a metro ethernet ring, so is the path supposed to be a ring?

@glilienfield,

if the traversal framework is deprecated, is there an alternate way to solve this problem? please suggest. im using a java client. is there a possiblity i can write my own code / implement a logic to achieve the same?

Regards,
Murali V

Since you are using the java client, you can run multiple queries and process the results in java to get what you want if a single query does not work. An example would be to iteratively walk the graph and calculate metrics. It would be a little inefficient to do something like this with the java client, as you make a call for each node to get its child nodes to process, repeating this process until you reach a leaf node and terminate. You could also query at once and get a list of paths and merge the paths into a consolidated subgraph using java.

An alternative is to write your own procedure that runs on the server if you have an algorithm you want to repeat often. I have done this for an application I am building that uses calculations I need for any given subgraph. Once the procedure is deployed, you just call it in your query. This is what the APOC library is. You call the procedures with the CALL clause. You write your procedures using the neo4j Java API and you deploy your procedures by placing your jar file in a folder on the server. This requires you have access to the server. I don't believe this is allowed if you are using Aura.

Before doing any of this, maybe we can still help if we understand your requirements more. It doesn't seem like you want all the paths originating from a single node. Is there more restrictions you can explain that would help us suggest a solution? Are you looking for closed paths originating from a single node, i.e., the path would terminate back on the starting node?