Как реализовать двунаправленную связь в 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.