Expand paths but exclude relationships for specific labels (not all labels)

Hello,

I want to expand all paths from a starting node, but exclude certain relationships for specific labels. Is this possible?

Here is an example:

Query to recreate the graph
MERGE (startFile:File {name: "StartFile"})
MERGE (file2:File {name: "File2"})
MERGE (file3:File {name: "File3"})
MERGE (sql1:SQL {name: "SQL1"})
MERGE (sql2:SQL {name: "SQL2"})
MERGE (script:Script {name: "Script"})

MERGE (startFile)<-[:WRITES]-(sql1) //should not be excluded
MERGE (sql1)<-[:READS]-(file2)
MERGE (sql1)-[:WRITES]->(file3)
MERGE (sql2)<-[:READS]-(startFile)
MERGE (script)-[:CONTAINS]->(sql1)
MERGE (script)<-[:READS]-(file2)
MERGE (script)-[:WRITES]->(file3)

This graph contains File, SQL, and Script nodes. I want to expand all paths from StartFile, excluding these relationships:

  • (:File)-[:READS]->()
  • (:SQL)-[:WRITES]->()
  • (:Script)-[:WRITES]->()
  • (:Script)-[:READS]->()

This is my current approach, which returns all nodes:

MATCH (start:File {name: 'StartFile'})

WITH start
CALL apoc.path.expandConfig(
        start,
        { minLevel:1,
          maxLevel:5,
          uniqueness:'RELATIONSHIP_PATH',
          bfs:true } )
YIELD path

RETURN path

So far, I have only found ways to exclude either labels or relationships. But no way to exclude relationships for specific labels.

Any help would be greatly appreciated!

You can do things like:

MATCH (A)-[R]->(B) 
WHERE NOT type(R)  IN [ 'a', 'b' ] RETURN A, B

Hi, you don't say what Neo4j version you are using, but assuming a recent one, this might be what you want:

MATCH p=(start:File {name: 'StartFile'})
                     (()-[r]-() WHERE
                     endNode(r)=start OR
                     NOT (type(r)="WRITES" AND labels(startNode(r))[0] IN ["SQL", "Script"])
                          OR (type(r)="READS" AND labels(startNode(r))[0] IN ["File", "Script"]))*
 RETURN p;

I am not sure about the first WHERE condition, you might have to move it somewhere else in the filtering expression. It is an attempt to accommodate:

MERGE (startFile)<-[:WRITES]-(sql1) //should not be excluded

which breaks your rules, without specifying a new one.

I must say that the logic seems quite complex, and I wonder if your data model is suitable for what you want to do.