0

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.

Zainab Saad
  • 728
  • 1
  • 2
  • 8

3 Answers3

1

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).

cybersam
  • 63,203
  • 6
  • 53
  • 76
0

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.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • could you explain me what problem you are facing or what concept you want to clear? –  Feb 25 '23 at 19:05
  • I have specified the edge direction while creating the edge that is Student "StudiesAt" Department. This is directed edge. When I use MATCH clause to find all the edges in my database, I get an "undirected" edge between the two vertices. What is the reason for this? – Zainab Saad Feb 25 '23 at 19:07
  • Hi farakh. I doubt we can create an undirected edge in AGE. The direction must be specified when using CREATE clause. – Muhammad Taha Naveed Feb 25 '23 at 20:13
  • @MuhammadTahaNaveed Yes, you are right. I tried creating undirected edge and that resulted in an error. – Zainab Saad Feb 25 '23 at 20:18
0

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.