I have the following situation (as shown in the image below), where I have to return always the latest tagged Person node on the path while having to traverse an undefined number of hops in the HAS_PARENT relationship type.
which works fine for CASE III, but not for CASE I and II. The reason for it is that I get also the upper tagged Person nodes, where I am interested only in the last tagged one. Would filtering on uniqueness: "RELATIONSHIP_PATH|LABEL" satisfy CASE I and II as well? Thanks!
so in this case I would also get the results for parentFamily, right? Also, I am not interested in the path of it but in the node itself, as I use it later on in a subsequent query. Is there a way to set the limit: * (just as an unknown depth)?
It will not get info from the parentFamily due to Family not being whitefiltered.
Please consider that this approach will first open the entire tree and just after retrieving all of the, it will prune non valid paths.
You have two options, you can use the property tagged as a Label, so then you can add it to the labelFilter as a Terminator. Or, if you don't want or can't modify your model, you may need to check the traversal api framework.
Thanks for the explanation. The point is that the model cannot change at the moment speaking but also what I think happens, in this case, is that even the shorter paths are considered valid paths. The only issue is that I am interested in the last-tagged person and not the entire path above him. So basically, I only am interested in the last Person node that is tagged, so considering the depth-first search, it would be:
go until the last Person node in the path,
check if it is tagged
if yes, return it and break
if not, continue up the tree until (line 3) is the case.
if (line 3) is not possible, go to the next path
MATCH (family:Family)<-[:BELONGS_TO]-(person)
CALL apoc.path.expandConfig(person, {
relationshipFilter: "HAS_PARENT",
labelFilter: "+Person",
filterStartNode: true,
uniqueness: "RELATIONSHIP_PATH",
bfs: false
})
YIELD path
WHERE last(nodes(path)).tagged = true
WITH family, nodes(path) AS nodes
WITH family, apoc.coll.indexOf(nodes, last(nodes)) AS index, last(nodes) AS node
WITH family, apoc.coll.sortMaps(collect({index: index, node: node}), "index")[0] AS result
RETURN family.id AS family, result.node.id AS node
@busymo16 Yes, you're right. I'm missing some nuance of the requirements that I cannot see no matter how many times I read the thread. I've been testing with your data - what am I missing that is eliminating node 7 from the results?
@busymo16 I did some testing with the new k-hop optimizations in v5. There are some requirements for it to kick in (hence the 0..999 and the distinct in my example), but this seems to work, if I'm understanding your requirements correctly:
match (f:Family)<-[:BELONGS_TO]-(:Person)-[:HAS_PARENT*0..999]->(p:Person {tagged:true})
return distinct p
Thanks for your answer. Logically this is the expected behavior but it is quite not performant for bigger use cases. I will have to use it in a graph that is going over through 100mil nodes more or less. I have also part of the query before this logic, and parts of it after the query. Any idea on speeding it up?