Skip to main content
 首页 » 编程设计

spring中在Spring boot中加载具有最近邻居的neo4j节点

2025年05月04日67luoye11

在我的项目中,对象User有一个Item项的集合,它通过一对多的“OWNS”关系与其相关。每一个项目 通过一对一的“OWNED_BY”关系与用户相关。 我的(缩短的)类(class)如下所示:

@NodeEntity 
public class User { 
    . . . 
    @Relationship(type="OWNS", direction = Relationship.OUTGOING) 
    private Collection<Item> items; 
    . . . 
} 
 
@NodeEntity 
public class Item { 
    . . . 
    @Relationship(type="OWNED_BY", direction = Relationship.OUTGOING) 
    public User owner; 
    . . . 
} 

我使用用户和项目存储库存储节点 (示例):

@Repository 
@Transactional 
public interface UserRepository extends Neo4jRepository<User, Long> { 
    . . . 
    @Query("MATCH (user:User) WHERE ID(user)={0} RETURN user") 
    User getById(Long id); 
    . . . 
} 

只需使用 setter 填充 Collection 并使用默认的 save() 方法保存即可。

User user = ... 
user.setItems(. . .); 
userRepository.save(user); 

一切都运转良好。数据与所有对应关系一起保留在图表中。 Spring data 文档指出“默认情况下,加载实例 将映射该对象的简单属性及其直接相关的对象(即深度 = 1)。” 这正是我想要的。 然而,当我尝试取回数据时,这种情况不会发生。

获取用户使用:

User user = userRepository.getById(id); 

确实返回正确的用户,但它与项目(集合项目)的关系为空。

作为旁注,我正在使用 Spring Boot,我的依赖项如下:

    dependencies { 
    compile('org.springframework.boot:spring-boot-starter-data-neo4j:2.0.3.RELEASE') 
    //compile('org.springframework.data:spring-data-neo4j:5.0.8.RELEASE') 
    compile('org.neo4j:neo4j:3.4.3') 
    compile('org.neo4j:neo4j-ogm-core:3.1.0') 
    runtime('org.neo4j:neo4j-ogm-http-driver:3.1.0') 
    compile('org.springframework.boot:spring-boot-starter-mail:2.0.3.RELEASE') 
    compile('org.springframework.boot:spring-boot-starter-security:2.0.3.RELEASE') 
    compile('org.springframework.boot:spring-boot-starter-thymeleaf:2.0.3.RELEASE') 
    compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity4:3.0.2.RELEASE') 
    compile('org.springframework.boot:spring-boot-starter-web:2.0.3.RELEASE') 
    testCompile('org.springframework.boot:spring-boot-starter-test') 
    testCompile('org.springframework.security:spring-security-test') 
    testCompile('org.mockito:mockito-core:2.7.22') 
    compile('junit:junit:4.12') 
    } 

为什么会发生这种情况?加载给定节点时如何获取所有直接邻居(加载深度=1,这应该是默认值)?

编辑:我已经重新使用提供的 Neo4jRepository findById(id, depth) 但我仍然不知道如何让它与我自己的查询一起工作。

请您参考如下方法:

使用自定义查询时,您无法真正添加 Spring 的深度。 相反,包括自定义查询本身的深度。 例如,假设您有一个消息链接列表:

(:Message{id:1})-[:NEXT]->(:Message{id:2})-[:NEXT]->(:Message{id:3}) 
                                          \ 
                                           \-[:ATTACHMENT]->(:Image{id:4}) 

您可以通过指定所需的根节点以及路径长度来获取最近的邻居,如下所示:

MATCH (m:Message)-[*0..0]-(a) where ID(m)=1 RETURN * 

上面将仅返回根节点。

MATCH (m:Message)-[*0..1]-(a) where ID(m)=1 RETURN * 
MATCH (m:Message)-[*0..2]-(a) where ID(m)=1 RETURN * 

以上将返回:

(:Message{id:1})-[:NEXT]->(:Message{id:2}) 

(:Message{id:1})-[:NEXT]->(:Message{id:2})-[:NEXT]->(:Message{id:3}) 
                                      \ 
                                       \-[:ATTACHMENT]->(:Image{id:4}) 

分别。

将您的查询修改为如下所示:

@Query("MATCH (user:User)-[p:OWNS*0..1]->(item:Item) WHERE user.username={0} RETURN *") 
User getByUsernameWithItems(String username); 

以上将返回用户和 Collection<Item> items将填充第一级相邻 Item 节点。