0

I stumbled uppon the same problem like in neo4j - Relationship between three nodes. I am new in Neo4J and wanted to model a relational database as a graph.

I have three types of data, A, B and C. An instance of B, B1, can belong to an instance of C, C1, and an instance of A, A1 can belong to B1 and C1, but if and only if B1 belongs to C1. The problem here is that, i can also have A1 belonging to B2 which belongs to C1 and A1 also belonging to B1 which belongs to C2. These would be three legit, separate combinations. So, in my DB, i would have a join table where in a record i would keep the combination of the three ids, expressing the relationships formed by the instances.

Now, from what i can figure, hyperedges is something like what i am searching(http://neo4j.com/docs/stable/cypher-cookbook-hyperedges.html). I was thinking, for starters, to add relationships like these:

A-[:PART_OF]->TRIPLE

B-[:PART_OF]->TRIPLE

C-[:PART_OF]->TRIPLE

1st problem/question: if a type B instance was to be deleted then the triple node would remain. I am guessing i would have to handle this in some way when deleting things?

2nd problem/question: My main question is, would it be more efficient if i added some more relationships? For example A-[:BELONGS_TO]->C. So, if i wanted all type C instances that A1 belongs to, i could have the results back with one hop. The relationship traversals would be less in number than the "triple" type nodes that would have to be visited. I think basically i am asking how Neo4j is looking for patterns internally(Where does it start, does it re-examine nodes etc). Because i am guessing(maybe wrongfully) if i want the Cs that A1 belongs to, i would write something like:

match A1-[:PART_OF]->triple<-[:PART_OF]-C return C

How would that query work? First retrieve all triples A1 is part of, then those all C types are part of and finally return the matches?

Any hints? Thanks in advance.

Community
  • 1
  • 1
0gap
  • 21
  • 7

1 Answers1

0

If I understand you correctly, you really want to represent a transitive relationship, as in:

(:A)-[:BELONGS_TO]->(:B)-[:BELONGS_TO]->(:C)

If so, there is no need to use "triplets", as neo4j can easily represent and handle transitive relationships.

Suppose your test data (as stated in your question) is created this way:

CREATE
  (a1:A {name:"a1"}),
  (b1:B {name:"b1"}), (b2:B {name:"b2"}),
  (c1:C {name:"c1"}), (c2:C {name:"c2"}),
  (a1)-[:BELONGS_TO]->(b1),
  (b1)-[:BELONGS_TO]->(c1),
  (b1)-[:BELONGS_TO]->(c2),
  (a1)-[:BELONGS_TO]->(b2),
  (b2)-[:BELONGS_TO]->(c1)

With that data, you can use the following query to get the C nodes that a specific A node indirectly belongs to. This query also returns the path that was used, since there can be multiple paths between any specific A and C pair. Here is a console that shows this working.

MATCH p=(:A { name:"a1" })-[:BELONGS_TO*2..2]->(c:C)
RETURN p, c;

If you just wanted distinct C nodes in the result, this would do that:

MATCH (:A { name:"a1" })-[:BELONGS_TO*2..2]->(c:C)
RETURN DISTINCT c;
cybersam
  • 63,203
  • 6
  • 53
  • 76
  • 1
    Sorry cybersam, maybe my example was not complete. Yes it is a transitive relationship, but that only adds to my problem. Let's say now, the triple a2,b1,c2 comes to play. how should i handle this new "RDBMS" entry in Neo4j? Because after inserting the new triple(by simply adding the a2->b1 rel), it is possible at some point i would not want a1 to belong to c2, but the relationship b1-[:BELONGS_TO]->c2 has to remain for the sake of a2. That means that the path a1->b1->c2 remains. Maybe i should keep an attribute in the relationship stating which A instances the path starts from. – 0gap Aug 21 '15 at 20:11
  • If the path `a1-[:BELONGS_TO]->b1` still remained, then transitivity should mean that `a1` also belongs to `c2`. Are you saying you want to be able to "turn off" the transitivity for certain paths? If so, keeping a collection of "transitive" (or "nontransitive", depending on which is least common) `A` names (or IDs, or whatever) in the relationship should work. – cybersam Aug 21 '15 at 20:20
  • Yes, i am guessing that must be the solution. Since i want all relationships to be present but don't want all paths formed to have meaning. – 0gap Aug 24 '15 at 09:02