skip to Main Content

In the below example I create a one-direction relation between two vertices (from b to a), is there a way I can create a relation from (a to b) at the same time?

SELECT *
FROM cypher('test_graph', $$
    MATCH (a:Person), (b:Person) WHERE a.name = 'hossam' AND b.name = 'omar'
    CREATE (b)-[r:REL {name: b.name+'->'+a.name}]->(a) RETURN r
$$) as (v agtype);

I tried remove the arrow symbol > before (a) like: CREATE (b)-[r:REL {name: b.name+'->'+a.name}]-(a) but it results with a syntax error.

3

Answers


  1. As of right now i believe the most straightforward way to achieve bidirectional relations is to set it as a property, you can’t just remove the direction at the moment of creation. For example:

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

    this will return as you said the error

    ERROR:  only directed relationships are allowed in CREATE
    LINE 4: CREATE (a)-[e:FRIENDS]-(b)
    

    and the same thing will happen if you use bidirectional edge

    SELECT * FROM cypher ('graph', $$
    MATCH (a:Person), (b:Person)
    WHERE a.name = "hossam" AND b.name = "omar"
    CREATE (a)<-[e:FRIENDS]->(b)
    RETURN e
    $$) as (e agtype);
    ERROR:  syntax error at or near ">"
    LINE 4: CREATE (a)<-[e:BORDERS_WITH]->(b)
    

    You need to try something like this:

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

    by assigning the "<->" as properties you can search search all the bidirectional relations in your graph using:

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

    Since the feature of bidirectional relations isn’t yet supported I believe this is one way to get around that.

    Login or Signup to reply.
  2. No, there is no way to create bidirectional relationships in Apache AGE.
    There is no way to create bidirectional relationships in Neo4j either as written in the answers to this question. The reasoning being since you are allowed to make non-directional queries, bidirectional relationships become essentially same as disregarding the direction altogether.

    On a more technical level:-

    The edges are stored with a vertex start_id and an end_id in the edges table. Having bidirectional relationship means that both the start_id and the end_id need to have 2 values.

    You have 2 alternatives:-

    1.) Make another relationship in the opposite direction (however it takes more space).

    2.) Make non-directional queries.

    Login or Signup to reply.
  3. Create two relations in one go:

    SELECT *                                                                      
    FROM cypher('test', $$
        MATCH (a:Person), (b:Person) WHERE a.name = 'hossam' AND b.name = 'omar'
        CREATE br =
        (b)-[r:REL {name: b.name+'->'+a.name}]->(a)<-[r:REL {name: b.name+'<-'+a.name}]-(b)
        RETURN br
    $$) as (v agtype);
    

    AGE ensures your graphs have a bi-directional relationship in terms of Edges.

    Try the following query to check:

    SELECT * FROM cypher('test_graph', $$ MATCH (a)-[r]->(b) RETURN r $$) as (v agtype);
    

    Returns:

     {"id": 9570149208162308, "label": "REL", "end_id": 9851624184872964, "start_id": 9851624184872963, "pro
    perties": {"name": "omar->hossam"}}::edge
    

    The query for the opposite relation match

    SELECT * FROM cypher('test_graph', $$ MATCH (b)-[r]->(a) RETURN r $$) as (v agtype);
    

    Returns:

     {"id": 9570149208162308, "label": "REL", "end_id": 9851624184872964, "start_id": 9851624184872963, "pro
    perties": {"name": "omar->hossam"}}::edge
    

    If however you need the relation to be in the form of hossam->omar. You’ll need to define another relation, preferably from (a)-[r]->(b). And it will show up as another edge.

    OR,

    A better approach is to just imply the relation as the following b.name+'<->'+a.name

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