如何使用Spring Data Neo4j在查询中指定深度?

时间:2017-02-02 17:04:10

标签: java spring neo4j lazy-loading spring-data-neo4j

我尝试使用Neo4j和Spring Data(spring-data-neo4j 4.2.0.RELEASE)进行目录结构。

我有一个目录bean:

@NodeEntity
public class Directory {
    @GraphId private Long id;
    private String name;

    @Relationship(type = "HAS_CHILD_CONTENT", direction = Relationship.OUTGOING)
    public Set<Directory> subDirectories;

    public void hasChildContent(Directory subDir) {
        if (subDirectories == null) {
            subDirectories = new HashSet<>();
        }
    subDirectories.add(subDir);
}

和我的存储库:

public interface DirectoryRepository extends GraphRepository<Directory> {
    @Query("MATCH (a:Directory) WHERE NOT ()-[:HAS_CHILD_CONTENT]->(a) RETURN a ORDER BY a.name ASC")
    List<Directory> findAllRoots();

    Directory findOneByName(String name, @Depth int depth);
}

我的问题是目录有一个他的子目录列表,我不想在获取根目录时获取数据库中的所有目录。

目前,如果我创建此数据样本:

Directory root = new Directory("root");
Directory rootLevel1 = new Directory("rootLevel1");
Directory rootLevel2 = new Directory("rootLevel2");
root.hasChildContent(rootLevel1);
rootLevel1.hasChildContent(rootLevel2);
directoryRepository.save(root);

然后选择根节点:

directoryRepository.findAllRoots();

我得到根目录,将rootLevel1作为subDir,将rootLevel2作为subDir。

我想获取root,其中rootLevel1为null(作为subDir)。所以我不会获取数据库的整个目录。

我尝试了@Depth param,但是电话:

directoryRepository.findOneByName("root", 0);

获取根目录,将rootLevel1作为subDir,将rootLevel2作为subDir。好像没有考虑到深度。

我怎样才能选择只有他的子目录的节点,而不是选择子目录子目录的子目录的子目录??

感谢。

[编辑]

我发现在集成测试中删除Transactional注释会影响SDN的fecthing系统。

使用Transactional注释,SDN急切地获取所有子目录并从Neo4J加载整个目录结构。

没有Transactional注释,SDN懒惰地获取,我的Directory bean作为“subDirectories”属性为null。

这解决了我的问题,但没有回答背后的问题:如何设置自定义深度以获取。

2 个答案:

答案 0 :(得分:3)

这可能是因为您共享相同的基础会话供您编写和阅读。

当您阅读实体时,SDN / OGM会检测到它们已经在会话中(基于ID)。它会在会话中返回它们,完全填充。

当您删除@Transactional时,每个数据库访问都会在新的新会话中执行,从而产生预期的结果。

如果您在写入后需要以任何理由阅读,您可能需要注入一个OGM会话来调用session.clear()以强制进行会话刷新。

答案 1 :(得分:0)

您可以考虑

MATCH p=(n:Directory)-[]-m where length(p)=1 return m limit 25

match p=(n)-[]-(m) with m, reduce(status ='', q IN nodes(p)| status + 'x') AS c where length(c)=1 return m, c