Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
05-27-2019 12:16 PM
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
05-27-2019 11:18 PM
Although not completely obvious when looking at my data i guess this has to do with the "uniqueness" principles ..
05-29-2019 03:17 PM
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.
05-30-2019 01:02 AM
Thanks Andrew, thats clear. Regards Koen.
All the sessions of the conference are now available online