如何使用 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()
以强制刷新会话。
我尝试用 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()
以强制刷新会话。