I’m trying to use dynamic matching because I want to create generic queries with parameterized relations. But I found this strange behavior, can somebody explain why it ignores the filter on relations if I set depth traversal ?
If I do this (with no set depth traversal), it only returns node_2, which seems correct
MATCH (n:DtEntity {id: 'node_2'})
OPTIONAL MATCH (n)-[r:$any(['hasChild'])]->(c)
return n, c, r
But if I do this, with ‘*’ on depth or ‘*1..2’ or any other depth traversal, it will return, node_2, value_node_1 and the hasValueNode-relation….(but I filter on hasChild relations)
MATCH (n:DtEntity {id: 'node_2'})
OPTIONAL MATCH (n)-[r:$any(['hasChild'])*]->(c)
return n, c, r
You're seeing the correct behavior — Neo4j ignores your relationship type filter when you use variable-length patterns with parameters. This is because relationship types cannot be parameterized, especially when using *.
OPTIONAL MATCH (n)-[r:$any(['hasChild'])]->(c) -- This works
but when you add *
OPTIONAL MATCH (n)-[r:$any(['hasChild'])*]->(c)
Neo4j treats it as:
OPTIONAL MATCH (n)-[r*]->(c)
So it traverses all relationships, including hasValueNode
Official Neo4j Documentation (confirming this behavior)
Relationship types cannot be parameterized and link is -
Want something generic, not familiar with cypher, over confidence in apoc. I have seen that in the past and it appears to be a road filled with surprises.
I wish we could get some time together to cover in more detail what you are looking to accomplish. Can you share some more context? You can also write me in private in a direct message if you want to discuss this further.
So, given a node, you get a filtered sub graph around the node. Then what? I was expecting some more logic to be pushed down into the query so you get a result that is “not a graph” but rather “an answer to a question”.