【问题标题】:How to implement a bidirectional relationship in Spring Data Neo4j?如何在 Spring Data Neo4j 中实现双向关系?
【发布时间】:2023-03-31 22:49:01
【问题描述】:

我正在使用 Spring Data Neo4j 建模一个非常简单的用例:我想要通过友谊关系连接的 Persons。这是我的代码(这里省略了getter和setter):

@NodeEntity
public class Person {
    @GraphId
    private Long id;
    private String name;
    private String password;

    @RelatedTo(type = "FRIEND_OF", direction = Direction.BOTH)
    private Set<Person> friends = new HashSet<Person>();

    public Person() {};

    public Person(String name, String password) {
        this.name = name;
        this.password = password;
    }

    public void befriend(Person person) {
        this.friends.add(person);
    }

最终,我使用以下方法来使用我的 Persons:

@Transactional
private void populateTwoPersons() {
    Person person1 = new Person("Alice", "pw1");
    Person person2 = new Person("Bob", "pw2");

    List<Person> persons = Arrays.asList(person1, person2);
    personRepository.save(persons);

    person1.befriend(person2);

    personRepository.save(persons);
}

在我的理解中,友谊关系应该是双向的,这就是为什么我将它的方向设置为 (direction = Direction.BOTH)。现在,当执行 populateTwoPersons() 方法时,它会创建两个人节点,但不会在它们之间形成一条边。

我尝试过的想法是将 befriend() 函数更改为

public void befriend(Person person) {
    this.friends.add(person);
    person.getFriends().add(this);
}

或将关系的方向设置为direction = Direction.OUTGOING。然而,这会创建一个有向边,这不是我想要的。

为什么我在第一种情况下完全没有优势?有任何想法吗? :)

提前致谢, 手动

【问题讨论】:

  • 对方的空哈希集覆盖了当前的关系。将其设置为 null 或仅保存 person1。 Neo4j 中的关系始终是定向的。

标签: java neo4j spring-data relationship bidirectional


【解决方案1】:

如果您不关心方向,则可以指定direction=Relationship.UNDIRECTED,这将保证两个节点实体之间的路径可从任一侧导航。

例如,考虑两个公司之间的PARTNER_OF 关系,其中

(A)-[:PARTNER_OF]→(B) implies (B)-[:PARTNER_OF]→(A)

关系的方向无所谓;只有这两家公司之间存在PARTNER_OF 关系这一事实才很重要。因此,UNDIRECTED 关系是正确的选择,确保两个合作伙伴之间只有一个此类关系,并且可以从任一实体在它们之间导航。

来源:良好的关系:The Spring Data Neo4j Guide Book

【讨论】:

    【解决方案2】:

    所有 Neo4j 边缘都必须是定向的,并且它们不能是双向的。您可以单向创建友谊并在没有方向的情况下查询它。或者,您可以在两个朋友之间创建两条单独的边。我认为后者更灵活,因为一个人可能会将另一个人视为朋友,但反之则不然。

    【讨论】:

    • 好答案。有向边不必如此对待,您总是可以将它们视为无向的,这很好。是 2 种关系(都是定向的)还是 1 种关系?我建议这取决于元数据需求。如果关系实际上是唯一的而不是相互的(即我关注 Bob,但他不关注我),那么 2 个边。如果边缘不是唯一的,最好只拥有一个而不是使用 2 只是为了让它“双向定向”
    • 直接保存并使用“-”而不是“”进行查询,谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-23
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 2020-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多