How to get MATCH ... WHERE {path_with_properties} to work in AGE

111 Views Asked by At

According to the Neo4j documentation about the WHERE clause, I should be able to filter the search using patterns with properties such as this:

SELECT *
FROM cypher('test', $$
    MATCH (n:Person)
    WHERE (n)-[:KNOWS]-({name: 'Timothy'})
    RETURN n.name, n.age
$$) AS (name agtype, age agtype);

However, I am getting an error that says:

ERROR:  syntax error at or near ":"
LINE 4: WHERE (n)-[:KNOWS]-({name: 'Timothy'})
                   ^

I'm guessing this feature has not yet been implemented in AGE but is there a way to get this to work, or is there an alternative for this to get a similar result?

8

There are 8 best solutions below

0
On BEST ANSWER

Yes, you can use exists() to find whether a path with properties exists or not as

SELECT * FROM cypher('test', $$
MATCH (n:Person)
WHERE exists((n)-[:KNOWS]-({name: 'Timothy'}))
RETURN n.name, n.age
$$) AS (name agtype, age agtype);
0
On

Apache AGE only supports directed relationships at the moment and that's the reason for the error. The updated statement will be:

SELECT *
FROM cypher('test', $$
    MATCH (n:Person)
    WHERE exists((n)-[:KNOWS]->({name: 'Timothy'}))
    RETURN n.name, n.age
$$) AS (name agtype, age agtype);
0
On

To get a similar result you can completely disregard the WHERE clause:

SELECT * FROM cypher('test', $$
MATCH (u)-[:KNOWS]-({name: 'Timothy'})
RETURN u.name, u.age $$)
AS (name agtype, age agtype);

This way you will find bidirectional relationships of nodes that have the relationship KNOWS with Timothy and vice verca.

0
On

you can simply do it with the following:

SELECT *
FROM cypher('test', $$
    MATCH (n:Person)-[:KNOWS]-({name: 'Timothy'})
    RETURN n.name, n.age
$$) AS (name agtype, age agtype);

the MATCH clause will bring all n users with the specified condition, this will work fine with AGE and I tried it myself.

I hope this solves the problem.

0
On

For retrieving in Apache age the relationships should be directed, You cannot retrieve non-directed relationships. First, create a directed relationship, and then you can use the following query to achieve similar results:

SELECT *
FROM cypher('test', $$
     MATCH (p:Person)-[:KNOWS]->(m)
     WHERE m.name = 'Timothy'
     RETURN p.name, p.age
$$) AS (name agtype, age agtype);

In the above query, we will match the relationship between m and p and then we filter the nodes based on the m's name property using the condition WHERE m.name = 'Timothy'. If matched the name and age from p are returned. We here also assume that the knows relationship exists as I have already mentioned.

0
On

We cannot retrieve undirected relationships in the Apache age as far now. You need to make directed relationships and can retrieve directed relationships only.

The query you have mentioned will give you an error because there is no direction for an edge in that query.

What we can try for this thing is as follows:

SELECT * FROM cypher ('graph', $$
MATCH (a:Emp), (b:Emp)
WHERE a.name = "hossam" AND b.name = "omar"
CREATE (a)-[e:FRIENDS{ type:"<->" }]->(b)
RETURN e
$$) as (e agtype);

Now, you have consider this as a no-direction or bidirectional edge and can retrieve this using that query.

SELECT * FROM cypher ('graph', $$
MATCH (a)-[e:FRIENDS]->(b)
WHERE e.type = "<->"
RETURN e
$$) as (e agtype);
0
On

In AGE, it is not fully implemented yet. However, there are workarounds to achieve similar results.

One option is to use the exists() function to check for paths with desired properties:

SELECT *
FROM cypher('test', $$
    MATCH (n:Person)
    WHERE exists((n)-[:KNOWS]-({name: 'Timothy'}))
    RETURN n.name, n.age
$$) AS (name agtype, age agtype);

Another approach is to directly specify the relationship pattern in the MATCH clause:

SELECT *
FROM cypher('test', $$
    MATCH (u)-[:KNOWS]-({name: 'Timothy'})
    RETURN u.name, u.age
$$) AS (name agtype, age agtype);
0
On

If utilizing the supported syntax in Apache AGE, you might need to modify your query to get a comparable result. Here is a different strategy you can try:

SELECT *
FROM cypher('test', $$
MATCH (n:Person)-[:KNOWS]-(friend)
WHERE friend.name = 'Timothy'
RETURN n.name, n.age
$$) AS (name agtype, age agtype);

Hope this is useful.