在Spring Boot中将neo4j节点与最近的邻居一起加载

时间:2018-07-21 15:06:22

标签: spring spring-boot neo4j spring-data-neo4j

在我的项目中,对象User具有Item个项目的集合,与它们之间存在一对多的“ OWNS”关系。每一个项目 通过一对一的“ OWNED_BY”关系与用户相关。 我的(缩短的)班级是这样的:

@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数据文档指出,“默认情况下,加载实例 将映射该对象的简单属性及其直接相关的对象(即,深度= 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),但我仍然不知道如何使它与我自己的查询一起使用。

1 个答案:

答案 0 :(得分:2)

使用自定义查询时,您无法真正从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节点。