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

How to specify depth in queries with 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);

和select根节点:

directoryRepository.findAllRoots();

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

我只想获取具有 null 的 rootLevel1 的根目录(作为 subDir)。所以我不获取数据库的整个目录。

我尝试了@Depth 参数,但是调用:

directoryRepository.findOneByName("root", 0);

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

我如何 select 一个只有他的子目录的节点,而不是...的子目录的子目录的子目录?

谢谢。

[编辑]

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

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

没有事务注释,SDN 延迟获取并且我的目录 bean 具有 null 作为 "subDirectories" 属性。

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

您可以考虑

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

这可能是因为您为写入和读取共享相同的底层会话。

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

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

如果您出于任何原因需要在写入后立即读取,您可能需要注入一个 OGM 会话来调用 session.clear() 以强制刷新会话。