【问题标题】:Neo4J Data ModelNeo4J 数据模型
【发布时间】:2017-05-03 21:59:49
【问题描述】:

我是 Neo4J 的新手,我对以下描述的问题域最合适的数据模型有疑问。

背景

据我了解,在 Neo4J 中,每个关系都有一个方向,传出、传入或无向。我读到新手在“双向”关系中犯的一个常见错误是,他们可能会在两个方向上对关系进行建模,而实际上一个无向的关系可以很好地达到目的。我也明白,无论方向如何,在查询时都可以忽略它并根据关系的任一方进行查询。

问题域

这有点陈词滥调,但请坚持我,在“人”可以相互联系的图表中,我很想将其建模为无向关系。但是,也许在我的问题域中,我想将元数据存储在关系边缘而不是任何一个 People 节点上。例如。连接时间或关系类型(朋友、家人、雇主等)的时间戳。也许这是使用 spring-data-neo4j 库的“副作用”,但似乎如果我希望在边缘而不是节点上数据元数据,我必须创建一个注释为 @RelationshipEntity 而不是@NodeEntity。这需要@StartNode@EndNode,这似乎暗示了我原本无方向的关系的方向......

现在,事实证明这对我来说可能不是一件坏事,因为也许毕竟这个额外的定向上下文有一些有用的东西(例如,也许我想知道是谁发起了这种关系,以便目标节点(人)必须接受邀请成为好友)。

现在假设每个人都可以将“关系”放入“朋友、家人、同事”等“群体”中,我觉得我现在需要实际上有两个指向任一方向的不同边缘,以便特定于给定方向的元数据有一个自然的位置。但这似乎被描述为一种新手反模式。

问题

我有两个问题:

1) 如果我需要存储特定于方向的元数据,我是否应该使用两个独立的不同关系边缘,它们本质上指向任一方向作为双向关系。例如Person A <--> Person B 但 A 将 B 放入朋友组,而 B 将 A 放入同事组。

2) 鉴于下面的 Java 数据模型,我不清楚 Person@Relationship 注释上的方向属性应该是什么。如果我什么都不指定,则默认为OUTGOING。但是由于它是一种反射关系,具体取决于您查看的关系可能是传出的或传入的,例如如果 A 人添加 B 人,两者都是 Person 实例,但方向是 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;
}

【问题讨论】:

  • 对于你的第一个问题,我的回答是肯定的,你可以做到。它仅取决于您的域。如果您的域要求您在相同节点之间使用具有相同类型和特定元数据的分离关系,那很好。如果没有,也可以!当我们在相同节点之间创建不必要的关系以存储相同的属性和相同的语义时,就会出现问题。很遗憾,我无法回答您的第二个问题。

标签: neo4j data-modeling graph-databases spring-data-neo4j


【解决方案1】:

1) 行之有效的经验法则是回答一个问题 - 如果存在从 A 到 B 的关系,是否仍然可以使用不同的元数据创建从 B 到 A 的另一个关系?你能独立删除一个方向的关系吗?

如果答案是肯定的,他们会选择两个定向关系,否则留在 UNDIRECTED,并创建 initiatedBy=userId 属性或类似属性。

对于您将连接分组的情况 - 问题是您确实从另一个人的角度对人进行分类,也许这是一个完全不同的事实,独立于 CONNECTED_TO 关系?

你可以例如创建一个组节点并将其链接到组中的所有者和所有人,具有以下架构:

(:Person)-[:OWNS]-(:Group)-[:CATEGORIZED]-(:Person)

2) 保留@Relationship(type = "CONNECTION_OF", direction = UNDIRECTED)。对于给定的人 X,connections 集合将具有 from=X 用于传出边缘的元素与必须 =X 用于传入的元素混合。所有这些都将混合在一个集合中。

【讨论】:

    猜你喜欢
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-18
    相关资源
    最近更新 更多