MATCH (a:Person) where a.Name="Max"
MATCH (b:Person) where b.Name="Sam"
MATCH (c:Person) where c.Name="Nil"
CREATE (a)-[:KNOWS]->(b)
CREATE (a)-[:KNOWS]->(c)
//Graph now looks like this:
(Sam)<-[KNOWS]-(Max)-[KNOWS]->(Nil)
//Run query:
MATCH (p1:Person)<--(:Person)-->(p2:Person)
RETURN p1.Name, p2.Name
//Results I get
p1.Name p2.Name
"Nil" "Sam"
"Sam" "Nil"
While desired results would be:
p1.Name p2.Name
"Nil" "Sam"
or
p1.Name p2.Name
"Sam" "Nil"
How do I instruct Cypher to traverse this symmetric path only once and return one row in results instead of two.
You could add a where clause to compare the two nodes and only return one when a property is higher than the other - either by property, internal id or just simply:
That one works, tried:
MATCH (p1:Person)<--(:Person)-->(p2:Person)
WHERE id(p1) > id(p2)
RETURN p1.Name, p2.Name
Returns:
p1.Name
p2.Name
"Nil"
"Sam"
Are there any more "natural" way to get desired results similar to what "distinct" clause does but on a path level?
At the same time, running this query:
MATCH (p1:Person)<--(:Person)-->(p2:Person)
WHERE p1 > p2
RETURN p1.Name, p2.Name
Returns Error:
Type mismatch: expected Float, Integer, Point, String, Date, Time, LocalTime, LocalDateTime or DateTime but was Node (line 2, column 7 (offset: 50))
"WHERE p1 > p2"
The recommended approach shared is the best way at this point.
Order of nodes matters in a path, and so having two symmetrical path results, where only the order is different, means the paths are distinct from each other already.
That said, this is a fairly common restriction in queries, and a keyword or more concise means to express this restriction sounds reasonable.