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.

Difference between match with 2 parts or 2 match statements

hi all, i was doing some neo4j querying and wondered what the difference is between the following 2 queries (which i thought are the same) but give different results
++++++++++++++++++++++++++++
MATCH path1 = (a)-[r1*]->(b),
path 2 = (b)-[r2*]->(c)
RETURN path1,path2
+++++++++++++++++++++++++++++
MATCH path1 = (a)-[r1*]->(b)
MATCH path 2 = (b)-[r2*]->(c)
RETURN path1,path2
++++++++++++++++++++++++++++++

The main difference is either one MATCH with 2 comma separated parts or 2 MATCH statements with one part each...

Does neo4j process those 2 queries differently ?

PS. this is just some sample code to illustrate my question ... thanks KOEN

3 REPLIES 3

Although not completely obvious when looking at my data i guess this has to do with the "uniqueness" principles ..

You're correct, this has to do with uniqueness of relationship traversal per path in a MATCH pattern.

Any relationships traversed per path (not per path variable, this spans both path1 and path2) cannot be reused. So if relationship with ID 123 is used as an r1 result in the first line cannot be used as r2 in the second line, as it's already been traversed.

But if you have two separate MATCHes then it can be used in both since the uniqueness is per MATCH.

Among other things, this kind of behavior safeguards any MATCH so an infinite loop is impossible, and aside from that it usually makes sense in most cases to not reuse a relationship after it's been traversed once per path.

As a more in-depth example, consider using the Movies database (from :play movies in the Neo4j browser) to find coactors of Keanu Reeves.

MATCH (:Person {name:'Keanu Reeves'})-[:ACTED_IN*2]-(coactor:Person)
RETURN coactor.name

We're using two traversals of :ACTED_IN for this, which is the equivalent of -[:ACTED_IN]-()-[:ACTED_IN]-.

You'll note in the returned results that Keanu Reeves doesn't show up as a coactor. This is because there is only one relationship between an actor and a movie they have acted in. Once we have traversed the first :ACTED_IN relationship to the movie in question, the additional traversal of :ACTED_IN to other actors in that movie cannot reuse that already traversed relationship from Keanu Reeves, so he never appears as a result.

If we break up the pattern into two separate MATCH clauses like so:

MATCH (:Person {name:'Keanu Reeves'})-[:ACTED_IN]->(movie)
MATCH (movie)<-[:ACTED_IN]-(coactor:Person)
RETURN coactor.name

Now we would see Keanu Reeves as a result for coactor. This is because the :ACTED_IN relationship traversed from Keanu to the movie is only in the paths from the first MATCH, which is separate from the paths from the second MATCH, so uniqueness restrictions don't come into play.

Thanks Andrew, thats clear. Regards Koen.