2
votes

Person node:

  • firstName
  • lastName
  • address
  • email
  • phoneNumber

Company node:

  • Name
  • address
  • email
  • phoneNumber

Relationships:

  • Person -[SPOUSE]-> Person
  • Person -[SIBLING]-> Person
  • Person -[FAMILY]-> Person
  • Company -[EMPLOYEE]-> Person

Person entity:

public class Person {
    @Id
    @GeneratedValue
    Long personId;

    @Builder
    public Test(Long personId, String firstName, String lastName, String address, String email, String phoneNumber) {
        this.personId = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.addresss = address;
        this.email = email;
        this.phoneNumber = phoneNumber
    }

    @NotEmpty(message = "Please provide a first name")
    String firstName;

    @NotEmpty(message = "Please provide a last name")
    String lastName;

    String address;

    String email;

    String phoneNumber;

    @Relationship(type = "SPOUSE",direction=Relationship.OUTGOING)
    public Set<Person> spouse;

    @Relationship(type = "SIBLING",direction=Relationship.OUTGOING)
    public Set<Person> sibling;

    @Relationship(type = "FAMILY",direction=Relationship.OUTGOING)
    public Set<Person> family;
}

When I create a Person for Jane I also add a sibling relationship with John.

Running person.fetchById("29d31f6c-edfe-48a2-9ab2-3baed5d5ae69") retrieves the node Jane with the corresponding sibling node John.

{
   "address":"",
   "email":"",
   "phoneNumber":"",
   "personId":"29d31f6c-edfe-48a2-9ab2-3baed5d5ae69",
   "firstName":"Jane",
   "lastName":"Smith",
   "spouse":null,
   "sibling":[
      {
         "address":"",
         "email":"",
         "phoneNumber":"",
         "personId":"f825cedd-7328-4f9d-b0fd-a33726814f25",
         "firstName":"John",
         "lastName":"smith",
         "spouse":null,
         "sibling":[],
         "family":null
      }
   ],
   "family":null
}

However, the sibling relationship should be bi-directional. Running person.fetchById("f825cedd-7328-4f9d-b0fd-a33726814f25") only retrieves the node John.

{
   "address":"",
   "email":"",
   "phoneNumber":"",
   "personId":"f825cedd-7328-4f9d-b0fd-a33726814f25",
   "firstName":"John",
   "lastName":"Smith",
   "spouse":null,
   "sibling":null,
   "family":null,
   "closeFriend":null,
   "friend":null
}

Here is where the problem lies. I could add another sibling relationship between John and Jane. But, this effectively creates a infinite loop between the two. And the output from person.fetchById ends up being garbage.

  1. Is there any way to limit the depth of nodes returned when fetching nodes?
  2. I'm new to neo4j, so I suspect my design is wrong. What is the best way to model this kind of relationship?
2

2 Answers

1
votes

You're using SDN here?

From the Spring Data Neo4j docs:

If you don’t care about the direction then you can specify direction=Relationship.UNDIRECTED which will guarantee that the path between two node entities is navigable from either side.

0
votes

As far as I know (i'm just beginning to learn Neo4j too) you can't have bi-directional relationships, it's always suggested to have two directional ones.

If you do decide to add another relationship in the other direction, you could limit the number of hops to just one:

How can Cypher Impose a Maximum Number of Hops Only Counting a Specific Type of Node?

Or if you want to see longer chains of relationships, perhaps put a condition on the results to not return the originating node in the results?