Neo4J Data Model
我是Neo4J的新手,我对下面描述的问题领域的最合适的数据模型有疑问。Neo4J Data Model
背景据我所知,在每个Neo4j的关系有各种各样,传出,传入或无向的方向。我读到,新手在“双向”关系中犯的一个常见错误是,他们可能会在两个方向上建立关系模型,实际上一个无向关系可以很好地满足目标。我也明白,不管在查询时可能忽略它并根据关系的任何一方进行查询的方向。
问题域
这有点老生常谈,但我坚持下来,在一个图形,其中“人”可以彼此就觉得很想型号连接,作为一个无向关系。但是,也许在我的问题域中,我想将元数据存储在关系边而不是任何人节点上。例如。时间戳的时间,然后连接或类型的关系(朋友,家人,雇主等)。也许这是使用spring-data-neo4j库的“副作用”,但似乎如果我希望在边缘而不是在节点处数据元数据,我必须创建一个注释为@RelationshipEntity
而非@NodeEntity
的类。这就需要一个@StartNode
和@EndNode
然后似乎一个方向暗示我,否则无向关系......
现在,事实证明,因为也许毕竟原来有这个可能不是在我的情况是坏事(例如,我想知道是谁发起了这种关系,以便目标节点(人)必须接受成为朋友的邀请)。
现在想象一下,每个人都可以将“关系”置于“朋友,家人,同事”之类的“群体”中,我觉得现在我需要实际上有两个明显的边缘指向任何一个方向,特定于给定方向的元数据具有自然居住的地方。但这似乎被描述为一种新手反模式。
问题
我有两个问题:
1)我应该使用两个单独的独特关系的边缘,基本上无论哪种方式点作为一个双向的关系,如果我需要存储元数据特定于方向。例如Person A <--> Person B
,但是人A将人B放在朋友组中,而人B将A放入同事组中。 2)鉴于下面的Java数据模型,我不清楚@Relationship
注释Person
应该是什么方向属性。如果我没有指定,则默认为OUTGOING
。但是,由于它是反射关系,取决于你关注哪个人的实例可能是传出或传入,例如,如果人员A添加人员B,则两个人员都是个人实例,但是人员A实例上的方向是传出的,而人员B实例上的传入方向是传出的。由于我使用的是@RelationshipEntity
,所以注释应该完全省略?
Java数据模型
@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;
}
1)拇指行之有效的规则是回答一个问题 - 如果从A到B的关系存在,可以从B到A相互之间的关系仍然被创建,用不同的元数据你能否独立于另一方删除关系的一个方向?
如果答案是肯定的,他们会选择两个定向关系,否则以UNDIRECTED
保留,并创建initiatedBy=userId
属性或类似属性。
对于你的情况,你把连接分组 - - 事情是,你真的从另一个人的观点分类的人,也许这是一个完全不同的事实独立于CONNECTED_TO
关系?
你可以例如创建一组节点和链接,业主和所有的人在一组,与下面的模式:
(:Person)-[:OWNS]-(:Group)-[:CATEGORIZED]-(:Person)
2)保持@Relationship(type = "CONNECTION_OF", direction = UNDIRECTED)
。对于给定的人X,connections
集合将具有来自= X的用于传出边缘的元素以及用于传入的元素必须= X的元素。所有这些将混合在一个集合中。
对于你的第一个问题,我的回答是肯定的,你可以这样做。它仅取决于你的域名。如果您的域名要求您在相同节点之间使用相同类型和特定元数据的分离关系,那好。如果不是,也可以!当我们在相同的节点之间创建不需要的关系来存储相同的属性和相同的语义时,就会出现问题。不幸的是,我无法回答你的第二个问题。 –