Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

neo4j

cypher

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?

like image 582
Bruno Peres Avatar asked May 04 '17 12:05

Bruno Peres


2 Answers

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.

like image 108
kwah Avatar answered Oct 15 '22 10:10

kwah


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.

like image 33
Michael Hunger Avatar answered Oct 15 '22 11:10

Michael Hunger