Search code examples
postgresqlcypherapache-ageopencypher

Apache AGE - MATCH clause and direction of edges


I noticed an unusual aspect while experimenting with MATCH clause. Here I have created a directed edge between the vertices as

SELECT * FROM cypher('university_graph', $$
CREATE ((n: Student {name : "John", bornIn : "USA"})-[e: 
StudiesAt {since : 2020}]->(d: Department {name : "CS"}))
RETURN n, d
$$) AS (n agtype, v agtype);

Now if I execute the following AGE query:

SELECT * FROM cypher('university_graph', $$
MATCH (a)-[e]-(b)
RETURN a.name, e.since, b.name
$$) AS (st_name agtype, st_since agtype, dept_name agtype);

I get the output as:

st_name | st_since | dept_name 
--------+----------+-----------
"John"  | 2020     | "CS"
"CS"    | 2020     | "John"
(2 rows)

But if I add the label to any of the vertices, It gives the correct edge direction. The AGE query is:

SELECT * FROM cypher('university_graph', $$
MATCH (a: Student)-[e]-(b)
RETURN a.name, e.since, b.name
$$) AS (st_name agtype, st_since agtype, dept_name agtype);

The output is:

 st_name | st_since | dept_name 
 --------+----------+-----------
 "John"  | 2020     | "CS"
 (1 row)

As I already have created directed edge going from Student type vertex to Department vertex, why does MATCH clause not take care of the direction (when label is not added to vertex) of the edge. Is it an intentional feature of MATCH clause? If yes, what is the reason of this.


Solution

  • If an undirected relationship pattern is ambiguous enough, then a MATCH will return each matching relationship twice (but with the end nodes in opposite order), since both results are equally valid.

    You first MATCH is the most generic undirected relationship pattern possible (no details are given for the end nodes, relationship, or direction):

    MATCH (a)-[e]-(b)
    

    Therefore, that query would return every relationship in your DB twice (but with a and b having opposite values).