Как реализовать двунаправленную связь в Spring Data Neo4j?

Я моделирую очень простой сценарий использования Spring Data Neo4j: я хочу иметь людей, которые связаны дружескими отношениями. Вот мой код (здесь не указаны методы получения и установки):

@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);
    }

В конечном счете, я использую следующий метод для использования моих Персонов:

@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. Это, однако, создает направленный край, а это не то, что я хочу.

Почему я не получаю преимущество в первом случае вообще? Есть идеи?:)

Заранее спасибо, Ману

2 ответа

Решение

Все ребра Neo4j должны быть направлены, и они не могут быть двунаправленными. Вы можете создать дружбу в одну сторону и запросить ее без указания направления. Или вы можете создать два отдельных ребра между двумя друзьями. Я думаю, что последний более гибкий, так как один человек может считать другого другом, но не наоборот.

Если вы не заботитесь о направлении, то вы можете указать direction=Relationship.UNDIRECTED что гарантирует, что путь между двумя объектами узла будет судоходным с любой стороны.

Например, рассмотрим PARTNER_OF отношения между двумя компаниями, где

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

Направление отношений не имеет значения; только тот факт, что PARTNER_OF Отношения между этими двумя компаниями имеют важное значение. Отсюда UNDIRECTED отношения - это правильный выбор, гарантирующий, что существует только одна связь такого типа между двумя партнерами, и возможен переход между ними с любого объекта.

Источник: Хорошие отношения: Справочник Neo4j.

Другие вопросы по тегам