Bruno Peres
Bruno Peres

Reputation: 16375

Why neo4j don't allows not directed or bidirectional relationships at creation time?

I know that Neo4j requires a relationship direction at creation time, but allows ignore this direction in query time. By this way I can query my graph ignoring the relationship direction.

I also know that there are some workarounds for cases when the relationships are naturally bidirectional or not directed, like described here.

My question is: Why is it implemented that way? Has a good reason to not allow not directed or bidirectional relationships at creation time? Is it a limitation of the database architecture?

The Cypher statements like below are not allowed:

CREATE ()-[:KNOWS]-()
CREATE ()<-[:KNOWS]->()

I searched the web for an answer, but I did not find much. For example, this github issue.

Is strange to have to define a relationship direction to one that don't have it. It seems to me that i'm hurting the semantic of my graph.

EDIT 1:

To clarify my standpoint about a "semantic problem" (maybe the term is wrong):

Suppose that I run this simple CREATE statement:

CREATE (a:Person {name:'a'})-[:KNOWS]->(b:Person {name:'b'})

As result i have this very simple graph:

Simple graph

The :KNOWS relationship has a direction only because Neo4j requires a relationship direction at creation time. In my domain a knows b and b knows a.

Now, a new team member will query my graph with this Cypher query:

MATCH path = (a:Person {name:'a'})-[:KNOWS]-(b:Person {name:'b'})
return path

This new team member don't know that when I created this graph I considered that :KNOWS relationship is not directed. The result that he will see is the same:

Simple graph

By the result this new team member can think that only Person a consider knows Person b. It seems to me bad. Not for you? This make any sense?

Upvotes: 6

Views: 4261

Answers (3)

kwah
kwah

Reputation: 1149

Fundamentally, it boils down to the internals of how the data is stored on disk in Neo4j -- note Chapter 6 of the O'Reilly Neo4j e-book.

In the data structure of a relationship they have a "firstNode" and a "secondNode", where each is either the left or the right hand side of the relationship.

To flag a relationship as uni/bi-directional would require an additional bit per node, where I would argue it is better to retain the direction in the data store and just ignore direction during querying.

Upvotes: 8

Michael Hunger
Michael Hunger

Reputation: 41706

In Neo4j relationships are always directed.

But if you don't care about the direction, you can ignore the direction when querying.

MATCH (p1:Person {name:"me"})-[:KNOWS]-(p2)
RETURN p2;

And with MERGE you can also leave off the direction when creating.

MATCH (p1:Person {name:"me"})
MATCH (p2:Person {name:"you"})
MERGE (p1)-[:KNOWS]-(p2);

You only need 2 relationships if they really convey a different meaning, e.g. :FOLLOWS on Twitter.

Upvotes: 2

Leon
Leon

Reputation: 32504

It seems to me that i'm hurting the semantic of my graph.

I can't see why a < or > symbol used during creation of a relationship hurts the semantics of your graph if you are going to not use that symbol during matching (and thus treating that relationship as undirected/bidirectional).

Suppose that the syntax proposed by you is supported. Now how will you connect with an undirected relationship two nodes a and b? You still have two options:

  1. CREATE (a)-[:KNOWS]-(b)
  2. CREATE (b)-[:KNOWS]-(a)

The pair (a, b) is always ordered by appearance even if not by semantics. So even if we remove the < or > symbol from the relationship declaration, the problem with the order of nodes in it cannot be eliminated. Therefore simply don't treat it is a problem.

Upvotes: 0

Related Questions