Apoc: apoc.path.subgraphAll Terminate Node Option

I am going through the apoc.path.subgraphAll - APOC Documentation (neo4j.com) webpage. Its is pretty good, but a question (confusion) remains. maybe someone here could explain.
using the example graph I present this apoc command.


Joe is on the terminator node list.. so.. why do we not terminate on Joe and progress to Mark? Shouldn't we Stop at Joe, or any of the other terminating nodes? Why do we progress to Mark? thanks guys. :slight_smile:

here, let me give you the code to make it easier..
MATCH (p:Person {name: "Alicia"})
MATCH (terminator:Person)
WHERE terminator.name IN ["Mark", "Joe", "Zhen", "Rik"]
WITH p, collect(terminator) AS terminatorNodes
CALL apoc.path.subgraphAll(p, {
relationshipFilter: "FOLLOWS>|KNOWS",
minLevel: 0,
maxLevel: 3,
terminatorNodes: terminatorNodes
})
YIELD nodes, relationships
RETURN nodes, relationships, p;

I got the expected results. What results did you get?

Data:

create(:Person{name:'Alicia'})-[:FOLLOWS]->(:Person{name:'Joe'})-[:FOLLOWS]->(:Person{name:'Mark'})

Result:

No Captain.. see I need to have more control over which nodes and relationships are shown for specific explorations.. Basically our model is complex and will display a lot of elements that the client would not need to see. Because it requires very specialized knowledge they wont know which elements to expand or delete. Thus I am looking into using the following Apoc mechanism. But this call, seems to go past the nodes I listed as Termination nodes.

image
it should have Stopped at Joe and not gone to Mark.. but.. it does.. see? but, why?

apoc.path.subgraphAll - APOC Documentation (neo4j.com)

I don't know. I created data that represented your graph and executed your query and did not get Mark back. Can you provide a script to recreate your data?

In the meantime, maybe the apoc virtual nodes and relationships would help you out. They are nodes you can create that are not in the database, but are returned from your query for the purpose of visualization. They allow you to project a complex graph to a simpler graph that represents what you want to display to the user.

Yes Captain.. I am using the data from the neo4j web page..
MERGE (mark:Person:DevRel {name: "Mark"})

MERGE (lju:Person:DevRel {name: "Lju"})

MERGE (praveena:Person:Engineering {name: "Praveena"})

MERGE (zhen:Person:Engineering {name: "Zhen"})

MERGE (martin:Person:Engineering {name: "Martin"})

MERGE (joe:Person:Field {name: "Joe"})

MERGE (stefan:Person:Field {name: "Stefan"})

MERGE (alicia:Person:Product {name: "Alicia"})

MERGE (jake:Person:Product {name: "Jake"})

MERGE (john:Person:Product {name: "John"})

MERGE (jonny:Person:Sales {name: "Jonny"})

MERGE (anthony:Person:Sales {name: "Anthony"})

MERGE (rik:Person:Sales {name: "Rik"})

MERGE (zhen)-[:KNOWS]-(stefan)

MERGE (zhen)-[:KNOWS]-(lju)

MERGE (zhen)-[:KNOWS]-(praveena)

MERGE (zhen)-[:KNOWS]-(martin)

MERGE (mark)-[:KNOWS]-(jake)

MERGE (alicia)-[:KNOWS]-(jake)

MERGE (jonny)-[:KNOWS]-(anthony)

MERGE (john)-[:KNOWS]-(rik)

MERGE (alicia)-[:FOLLOWS]->(joe)

MERGE (joe)-[:FOLLOWS]->(mark)

MERGE (joe)-[:FOLLOWS]->(praveena)

MERGE (joe)-[:FOLLOWS]->(zhen)

MERGE (mark)-[:FOLLOWS]->(stefan)

MERGE (stefan)-[:FOLLOWS]->(joe)

MERGE (praveena)-[:FOLLOWS]->(joe)

MERGE (lju)-[:FOLLOWS]->(jake)

MERGE (alicia)-[:FOLLOWS]->(jonny)

MERGE (zhen)-[:FOLLOWS]->(john)

MERGE (anthony)-[:FOLLOWS]->(joe)

here is their script which creates this graph

this is a good article.. I now know what I will be doing over this weekend.. :) thanks man.. maybe I should use this instead of the APOC stuff I was looking at.. Need to study up on this .. thanks man

if you have any ideas why the apoc.path.subgraphAll is acting so .. strange.. that would be great.. thanks man

Ok, like you, I am confused. The only explanation I have after experimenting with the result is that the algorithm only returns the end nodes or terminal nodes when they are specified. You don't get the nodes along the path. This is demonstrated with the following data set and query:

create(:TEST{id:0})-[:REL]->(:TEST{id:1})-[:REL]->(:TEST{id:2})-[:REL]->(:TEST{id:3})-[:REL]->(:TEST{id:4})

MATCH (p0:TEST {id:0}),(p1:TEST {id:1}),(p2:TEST {id:2}),(p3:TEST {id:3}), (p4:TEST {id:4})
WITH p0, [p3] AS terminatorNodes
CALL apoc.path.subgraphAll(p0, {
    terminatorNodes: terminatorNodes
})
YIELD nodes, relationships
RETURN nodes, relationships;

This explains the results you got. The reason Mark is included is because there is a path from Alicia through Jake to Mark. There is a relationship between Joe and Mark because the algorithm in includes all the relationships that exist in the graph between all the nodes returned. This makes it look like the algorithm traversed through Joe to get to Mark. This is not the case. I verified that by adding Jake to the terminatorNodes. This resulted in Mark being removed from the results and Jared added.

Honestly, this is not how I interpreted the definition of a terminatorNode, but this is the way I see explains the results.

AH... got it.. thanks again.. sigh.. hum.. okay.. at least now I know Why this is happening.. Thanks man.. got it.. you are right. as usual.. its nice to have another set of eye's and a mentor. thanks man thanks

1 Like