I'm new to Neo4J and I have a question about the most appropriate data model for a the problem domain described below.
Background
As I understand it, in Neo4J every relationship has a direction of sorts, outgoing, incoming or undirected. I read that a common mistake newbies make in "bi-directional" relationships is that they might model the relationship in both directions where in reality one undirected relationship would serve the purpose well. I also understand that irrespective of the direction it is possible at query time to ignore it and query based on either side of the relationship.
Problem Domain
This is a bit cliché, but stick with me, in a graph where "People" can connect with one another I felt tempted to model that as an undirected relationship. However, perhaps in my problem domain I want to store meta data on the relationship edge rather than at either of the People nodes. E.g. timestamp of when then connected or type of relationship (friend, family, employer etc...). Perhaps this is a "side effect" of using the spring-data-neo4j libraries but it seems that if I wish to data meta data on the edge rather than at the node I must create a class which is annotated as @RelationshipEntity
rather than @NodeEntity
. This necessitates a @StartNode
and @EndNode
which then seems to imply a direction to my otherwise undirected relationship...
Now, as it turns out this might not be a bad thing in my case because perhaps after all it turns out there is something useful about this additional directed context (e.g. perhaps I want to know who initiated the relationship so that the target node (person) must accept the invitation to be friends).
Now imagine that each person can place the "relationship" into a "group" like "friends, family, colleagues" etc I feel like I'd now need to actually have two distinct edges that point in either direction so that the meta data specific to the given direction has a natural place to reside. But this seems to have been described as a newbie anti-pattern.
Questions
I have two questions:
1) Should I use two separate distinct relationship edges that essentially point either way as a bi-directional relationship if I need to store meta data that is specific to the direction. e.g. Person A <--> Person B
but person A placed Person B in the friends group whereas Person B placed A in the colleagues group.
2) Given the Java data model below, I am unclear what the direction attribute on the @Relationship
annotation of Person
should be. If I specify nothing it default to OUTGOING
. But since it's a reflective relationship depending on which person instance you look at the relationship could be either outgoing or incoming, e.g. if person A adds person B, both are Person instances, but the direction is outgoing on the person A instance and incoming on the person B instance. Should the annotation be omitted altogether since I'm using a @RelationshipEntity
?
Java Data Model
@NodeEntity
@EqualsAndHashCode(of = {"id"})
@NoArgsConstructor
public abstract class Person {
@GraphId
private Long id;
... other attributes
@Relationship(type = "CONNECTION_OF", direction = UNDIRECTED)
private Set<Connection> connections;
}
@Data
@RelationshipEntity(type = "CONNECTION_OF")
public class Connection {
@GraphId
private Long relationshipId;
... other meta-data
@StartNode
private Person from;
@EndNode
private Person to;
}