skip to Main Content

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


  1. Quoting from the MATCH clause documentation in Apache AGE:

    The MATCH clause allows you to specify the patterns Cypher will search for in the database. This is the primary way of getting data into the current set of bindings. It is worth reading up more on the specification of the patterns themselves in Patterns.

    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.

    Login or Signup to reply.
  2. 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).

    Login or Signup to reply.
  3. Since both Student and Department have name property, and the query does not specify a direction or a label, your

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

    Can 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

    MATCH (a:Student)-[e]-(b:Department)
    RETURN a.name, e.since, b.name
    

    You will get the result you wanted.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search