cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Some questions about path pattern matching

czp
Node Link

Neo4j Version: 4.2.4
Operating System: MacOs
API: Cypher

According to the documentation, the same path cannot contain the same relationship. Does this mean that variables of type relationship collection cannot appear in the same path matching?


Relationship isomorphism
The same relationship cannot be returned more than once for each path matching record. Cypher makes use of relationship isomorphism for path matching.
Neo4j Cypher makes use of relationship isomorphism for path matching and is a very effective way of reducing the result set size and preventing infinite traversals.

So I tested this statement and it behaves exactly as documented:

 

 

neo4j@neo4j> match (v1)-[e]->(v2)-[e]-(v3) return p;
Cannot use the same relationship variable 'e' for multiple patterns (line 2, column 13 (offset: 14))
"match (v1)-[e]->(v2)-[e]-(v3) return p;"

 

 


But for the statement with the same semantic, or so I thought, I got different returns:

 

 

neo4j@neo4j> match p=(v1)-[e*1]->(v2)-[e*1]-(v3) return p;
+-------------------------------------------+
| p |
+-------------------------------------------+
| ({id: 2})-[:E]->({id: 1})<-[:E]-({id: 2}) |
| ({id: 3})-[:E]->({id: 1})<-[:E]-({id: 3}) |
| ({id: 4})-[:E]->({id: 1})<-[:E]-({id: 4}) |
| ({id: 1})-[:E]->({id: 2})<-[:E]-({id: 1}) |
| ({id: 1})-[:E]->({id: 3})<-[:E]-({id: 1}) |
| ({id: 1})-[:E]->({id: 4})<-[:E]-({id: 1}) |
| ({id: 4})-[:E]->({id: 4})-[:E]->({id: 4}) |
+-------------------------------------------+

 

 


So my question 1 is, how does it make sense that the two statements above get different results? If the comparison of the relationships ignores the direction, shouldn't statement `match (v1)-[e]->(v2)-[e]-(v3) return p` also report an error?

I also tested this statement:

 

 

neo4j@neo4j> match p=(v1)-[e*1]->(v2)-[e*2]-(v3) return p,length(p);
+---------------------------------------------------------------------------------------+
| p | length(p) |
+---------------------------------------------------------------------------------------+
| ({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1}) | 4 |
| ({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1}) | 4 |
| ({id: 4})-[:E]->({id: 4})<-[:E]-({id: 4})-[:E]->({id: 4})<-[:E]-({id: 1}) | 4 |
| ({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1}) | 4 |
| ({id: 2})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 2}) | 4 |
| ({id: 3})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 3}) | 4 |
| ({id: 4})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 4}) | 4 |
+---------------------------------------------------------------------------------------+

 

 

``As you can see, the same relationship returned more than once for each path matching record and the length of path is not as expected.
So question 2, is the result of this statement unexpected?

Similarly, such problems exist in directed edge patterns:
```

 

 

neo4j@neo4j> match p=(v1)-[e]->(v2)-[e]->(v3) return p,length(p);
Cannot use the same relationship variable 'e' for multiple patterns (line 2, column 15 (offset: 16))
"match p=(v1)-[e]->(v2)-[e]->(v3) return p,length(p);"
^
neo4j@neo4j> match p=(v1)-[e*1]->(v2)-[e*1]->(v3) return p,length(p);
+-------------------------------------------------------+
| p | length(p) |
+-------------------------------------------------------+
| ({id: 4})-[:E]->({id: 4})-[:E]->({id: 4}) | 2 |
+-------------------------------------------------------+

1 row available after 24 ms, consumed after another 0 ms

neo4j@neo4j> match p=(v1)-[e*1]->(v2)-[e*2]->(v3) return p,length(p);
+---------------------------------------------------------------------------------------+
| p | length(p) |
+---------------------------------------------------------------------------------------+
| ({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1}) | 4 |
| ({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1}) | 4 |
| ({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1}) | 4 |
| ({id: 2})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 2}) | 4 |
| ({id: 3})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 3}) | 4 |
| ({id: 4})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 4}) | 4 |
+---------------------------------------------------------------------------------------+

 

 


Question 3, do these statements behave as expected? What are the semantics of these statements?

---

I also tested some other statements:
```

 

 

neo4j@neo4j> match p=(v1)-[e*1..2]->(v2)-[e*2..4]->(v3) return length(p),p;
+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| length(p) | p |
+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| 4 | ({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1}) |
| 8 | ({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1}) |
| 8 | ({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1}) |
| 4 | ({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1}) |
| 8 | ({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1}) |
| 8 | ({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1}) |
| 4 | ({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1}) |
| 8 | ({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1}) |
| 8 | ({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1}) |
| 6 | ({id: 1})-[:E]->({id: 4})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 4})-[:E]->({id: 1}) |
| 4 | ({id: 2})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 2}) |
| 8 | ({id: 2})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 2}) |
| 8 | ({id: 2})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 2}) |
| 8 | ({id: 3})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 3}) |
| 4 | ({id: 3})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 3}) |
| 8 | ({id: 3})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 3}) |
| 8 | ({id: 4})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 4}) |
| 8 | ({id: 4})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 4}) |
| 4 | ({id: 4})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 4}) |
| 6 | ({id: 4})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 4}) |
| 6 | ({id: 4})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 4}) |
+-------------------------------------------------------------------------------------------------------------------------------------------------------+

21 rows available after 31 ms, consumed after another 3 ms
neo4j@neo4j> match p1=(v1)-[e*1..2]->(v2) match p2=(v2)-[e*2..4]->(v3) return length(p1)+length(p2),p1,p2;
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| length(p1)+length(p2) | p1 | p2 |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 4 | ({id: 1})-[:E]->({id: 2})-[:E]->({id: 1}) | ({id: 1})-[:E]->({id: 2})-[:E]->({id: 1}) |
| 8 | ({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1}) | ({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1}) |
| 8 | ({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1}) | ({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1}) |
| 4 | ({id: 1})-[:E]->({id: 3})-[:E]->({id: 1}) | ({id: 1})-[:E]->({id: 3})-[:E]->({id: 1}) |
| 8 | ({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1}) | ({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1}) |
| 8 | ({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1}) | ({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1}) |
| 4 | ({id: 1})-[:E]->({id: 4})-[:E]->({id: 1}) | ({id: 1})-[:E]->({id: 4})-[:E]->({id: 1}) |
| 8 | ({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1}) | ({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1}) |
| 8 | ({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1}) | ({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1}) |
| 6 | ({id: 1})-[:E]->({id: 4})-[:E]->({id: 4})-[:E]->({id: 1}) | ({id: 1})-[:E]->({id: 4})-[:E]->({id: 4})-[:E]->({id: 1}) |
| 4 | ({id: 2})-[:E]->({id: 1})-[:E]->({id: 2}) | ({id: 2})-[:E]->({id: 1})-[:E]->({id: 2}) |
| 8 | ({id: 2})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 2}) | ({id: 2})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 2}) |
| 8 | ({id: 2})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 2}) | ({id: 2})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 2}) |
| 8 | ({id: 3})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 3}) | ({id: 3})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 3}) |
| 4 | ({id: 3})-[:E]->({id: 1})-[:E]->({id: 3}) | ({id: 3})-[:E]->({id: 1})-[:E]->({id: 3}) |
| 8 | ({id: 3})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 3}) | ({id: 3})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 3}) |
| 8 | ({id: 4})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 4}) | ({id: 4})-[:E]->({id: 1})-[:E]->({id: 2})-[:E]->({id: 1})-[:E]->({id: 4}) |
| 8 | ({id: 4})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 4}) | ({id: 4})-[:E]->({id: 1})-[:E]->({id: 3})-[:E]->({id: 1})-[:E]->({id: 4}) |
| 4 | ({id: 4})-[:E]->({id: 1})-[:E]->({id: 4}) | ({id: 4})-[:E]->({id: 1})-[:E]->({id: 4}) |
| 6 | ({id: 4})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 4}) | ({id: 4})-[:E]->({id: 4})-[:E]->({id: 1})-[:E]->({id: 4}) |
| 6 | ({id: 4})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 4}) | ({id: 4})-[:E]->({id: 1})-[:E]->({id: 4})-[:E]->({id: 4}) |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

21 rows available after 2 ms, consumed after another 7 ms

 

 


My question 4 is that are the above two statements semantically equivalent?
IMHO, the semantics of the last statement is clear and follows `relationship isomorphism` exactly.

 

0 REPLIES 0
Nodes 2022
Nodes
NODES 2022, Neo4j Online Education Summit

All the sessions of the conference are now available online