apache / age

Graph database optimized for fast analysis and real-time data processing. It is provided as an extension to PostgreSQL.
https://age.apache.org
Apache License 2.0
3.03k stars 406 forks source link

Where Union of Labels #1714

Open jtomek opened 6 months ago

jtomek commented 6 months ago

Hi, how do I run this?

SELECT * FROM cypher('playground', $$
MATCH (n:Movie|Person)
RETURN n
$$) AS (v agtype)

I get

Query 1 ERROR at Line 31: : ERROR:  syntax error at or near "|"
LINE 2: MATCH (n:Movie|Person)
                      ^

Is this the only way to get what I want?

SELECT * FROM cypher('playground', $$
MATCH (n)
WHERE label(n) = 'Movie' or label(n) = 'Person'
RETURN n
$$) AS (v agtype)
rafsun42 commented 6 months ago

@jtomek There is a PR (#1452) for this feature. It is based on PG15.

diangamichael commented 5 months ago

It seems you're trying to execute Cypher queries within a PostgreSQL environment using the cypher function. The error you're encountering is due to the incorrect usage of the '|' symbol in the label definition within your MATCH clause. In Cypher, '|' is not used to denote multiple labels for a node. Instead, you should use the IN keyword.

Here's the corrected version of your first query:

sql Copy code SELECT * FROM cypher('playground', $$ MATCH (n) WHERE n:Movie OR n:Person RETURN n $$) AS (v agtype); This query will match nodes that have either the label 'Movie' or 'Person'.

Alternatively, you can use your second query as you provided:

sql Copy code SELECT * FROM cypher('playground', $$ MATCH (n) WHERE label(n) = 'Movie' OR label(n) = 'Person' RETURN n $$) AS (v agtype);

Both queries should achieve the same result, with the second one explicitly checking the labels of nodes. Choose whichever you find more readable or preferable for your use case.

rafsun42 commented 5 months ago

@diangamichael

In Cypher, '|' is not used to denote multiple labels for a node.

This is not correct. According to the openCypher specification, the pipe operator '|' is a valid way to define union of multiple labels.

github-actions[bot] commented 4 months ago

This issue is stale because it has been open 45 days with no activity. Remove "Abondoned" label or comment or this will be closed in 7 days.

github-actions[bot] commented 2 months ago

This issue is stale because it has been open 60 days with no activity. Remove "Abondoned" label or comment or this will be closed in 14 days.

alexgraul commented 3 weeks ago

WHERE label(n) = 'Movie' OR label(n) = 'Person' works but is fairly ungainly. Per the openCypher spec (:Foo|Bar) should be supported.

jrgemignani commented 3 weeks ago

Apache AGE does not support multiple labels, yet. There is a PR in review that could add this in the future. However, it is a large PR and needs to be thoroughly reviewed.

alexgraul commented 3 weeks ago

Hey @jrgemignani thankyou for chiming in, aware of the multi-label PR but this is a separate issue with querying that's needed even with single-label support.

What should be possible is being able to OR between labels in a query which is relevant for single labels, not ANDing for situations where you want to match on multiple labels on a query (which I believe in openCypher terms is expressed as [:Foo:Bar]). So if you have the following in your db:

(:City)-[:AirRoute]-(:City)
(:City)-[:SeaRoute]-(:City)

Being able to run a query and say 'Give me any Air OR Sea route between these two cities', which should be possible (in openCypher terms) via

(:City { name: 'London' })-[:SeaRoute|AirRoute]-(:City { name: :'Rotterdam' })

You can do it today via a WHERE clause as shown above but the syntax is super clunky.

rafsun42 commented 1 week ago

Hi @alexgraul Although the PR refers it as 'multi-label', it does support the | operator for combining multiple single labels in MATCH queries. For now you can look at the regression test file to see what kind of multi-label queries are supported.

alexgraul commented 1 week ago

ohhh nice! Awesome, thankyou for clarifying!