cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Efficient way of storing relations - SDN6

Hi, I am working on an application for storing family trees. From what I have read in a book about graph databases/neo4j is that the relationships should not be duplicated.

@Node("Person")
class Person(
    val firstName: String,
    val lastName: String,
   ) {
    @Id @GeneratedValue
    var personId: Long = -1

    @Relationship(type = "CHILD_OF")
    var parents: MutableSet<Person> = mutableSetOf()

    @Relationship(type = "PARTNER_OF")
    var partners: MutableSet<Person> = mutableSetOf()

    @Relationship(type = "PARENT_OF")
    var children: MutableSet<Person> = mutableSetOf()
}

For example if there exists a relation such as (a)-[PARTNER_OF]->(b) , then (b)-[PARTNER_OF]->(a) would be useless, because it can be easily queried both directions even though the relation is oriented. For example:

MATCH (p: Person) WHERE id(p) = ${personId}
OPTIONAL MATCH (p)-[rel:PARTNER_OF]-(other)
RETURN p, rel, other

Using the node mapped, I get two relations


which is not optimal.

In Spring Data Neo4j documentation I wasn't able to find any way of dealing with this.
How can I map the objects properly?

1 ACCEPTED SOLUTION

You could define the relationship again with incoming direction in the entity.

@Relationship(type = "PARTNER_OF")
var partners: MutableSet<Person> = mutableSetOf()

@Relationship(value = "PARTNER_OF", direction = Direction.INCOMING)
var partnersIncoming: MutableSet<Person> = mutableSetOf() // worst naming ever

but be aware that any changes to the relationship between two persons need to be in sync.

View solution in original post

5 REPLIES 5

You could define the relationship again with incoming direction in the entity.

@Relationship(type = "PARTNER_OF")
var partners: MutableSet<Person> = mutableSetOf()

@Relationship(value = "PARTNER_OF", direction = Direction.INCOMING)
var partnersIncoming: MutableSet<Person> = mutableSetOf() // worst naming ever

but be aware that any changes to the relationship between two persons need to be in sync.

That's clever! Thank you!

How do you propose to pass the data to the other layers of the app? Concatenating the sets might not be an efficient thing to do...

Oops! It's querying two times the PARTNER_OF relation.


It would be best if the query was:

... OPTIONAL MATCH (n)-[__sr__:`PARTNER_OF`]-(__srn__:`Person`) ...

and not:

... OPTIONAL MATCH (n)-[__sr__:`PARTNER_OF`]->(__srn__:`Person`) ...
... OPTIONAL MATCH (n)<-[__sr__:`PARTNER_OF`]-(__srn__:`Person`) ...

Can I somehow obtain the result with my own query?

Yes, you could use of course your own query.
Best would be something like MATCH (person:Person)-[partnerOfRelation:PARTNER_OF]-(partner:Person) RETURN person, collect(partnerOfRelation), collect(partner).

genealogy
Graph Buddy

You might be interested in a PlugIn being developed for genealogy. It will upload a GEDCOM into Neo4j. It also imports DNA results and has functions for genetic genealogy analytics. I'm writing the documentation now. If you send me an email, I'll communicate more about this when I get back from my current travels on Friday.

https://github.com/waigitdas/Neo4j-Genealogy-PlugIns

David A Stumpf, MD, PhD
genealogy@stumpf.org