如何在 Spring Data Neo4j 中实现双向关系?
How to implement a bidirectional relationship in Spring Data Neo4j?
我正在为一个非常简单的用例建模,使用 Spring Data Neo4j:我想要通过友谊关系连接的人。这是我的代码(这里省略了getters和setters):
@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。然而,这会创建一个 有向边 ,这不是我想要的。
为什么我在第一种情况下完全没有优势?有任何想法吗? :)
提前致谢,
马努
所有 Neo4j 边都必须是有向的,不能是双向的。您可以单向建立友谊并无方向地查询它。或者您可以在两个朋友之间创建两条单独的边。我认为后者更灵活,因为一个人可能会把另一个人当成朋友,但反之则不然。
如果你不关心方向那么你可以指定direction=Relationship.UNDIRECTED
这将保证两个节点实体之间的路径可以从任一侧导航。
例如,考虑两家公司之间的 PARTNER_OF
关系,其中
(A)-[:PARTNER_OF]→(B) implies (B)-[:PARTNER_OF]→(A)
关系的方向并不重要;只有这两家公司之间存在 PARTNER_OF
关系才重要。因此,UNDIRECTED
关系是正确的选择,确保两个伙伴之间只有一个这种类型的关系,并且可以从任一实体在它们之间导航。
资料来源:良好的人际关系:The Spring Data Neo4j Guide Book。
我正在为一个非常简单的用例建模,使用 Spring Data Neo4j:我想要通过友谊关系连接的人。这是我的代码(这里省略了getters和setters):
@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。然而,这会创建一个 有向边 ,这不是我想要的。
为什么我在第一种情况下完全没有优势?有任何想法吗? :)
提前致谢, 马努
所有 Neo4j 边都必须是有向的,不能是双向的。您可以单向建立友谊并无方向地查询它。或者您可以在两个朋友之间创建两条单独的边。我认为后者更灵活,因为一个人可能会把另一个人当成朋友,但反之则不然。
如果你不关心方向那么你可以指定direction=Relationship.UNDIRECTED
这将保证两个节点实体之间的路径可以从任一侧导航。
例如,考虑两家公司之间的 PARTNER_OF
关系,其中
(A)-[:PARTNER_OF]→(B) implies (B)-[:PARTNER_OF]→(A)
关系的方向并不重要;只有这两家公司之间存在 PARTNER_OF
关系才重要。因此,UNDIRECTED
关系是正确的选择,确保两个伙伴之间只有一个这种类型的关系,并且可以从任一实体在它们之间导航。
资料来源:良好的人际关系:The Spring Data Neo4j Guide Book。