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.
3
Answers
Quoting from the
MATCH
clause documentation in Apache AGE:When you create an edge between two vertices without specifying a direction AGE automatically creates an undirected edge meaning the edge can be traversed in either direction.
In your first query you did not specify any label for the vertices, and AGE did not have any information on direction of edge.
Then when you use
MATCH
to find all edges AGE treated the edges as undirected and returned both incoming and outing vertices.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):Therefore, that query would return every relationship in your DB twice (but with
a
andb
having opposite values).Since both Student and Department have
name
property, and the query does not specify a direction or a label, yourCan go either way. It could be Student-[relationship]-Department or Department-[relationship]-Student.
So both the returned results are totally valid given the ambiguous nature of your query.
If you modify your query to
You will get the result you wanted.