2017-02-02 3 views
0

Neo4j 및 스프링 데이터 (spring-data-neo4j 4.2.0.RELEASE)를 사용하여 디렉토리 구조를 만들려고합니다.Spring Data Neo4j에서 쿼리의 깊이를 지정하는 방법은 무엇입니까?

@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(); 

내가 rootLevel2을 가지고 하위 디렉터리로 rootLevel1을 갖는 루트 디렉토리를 얻을 수를 subDir로.

null을 가진 rootLevel1 (subDir)을 가진 루트 만 가져 오려고합니다. 그래서 DB의 전체 디렉토리를 가져 오지 않습니다.

은 내가 @Depth의 PARAM을 시도했지만 전화 :

directoryRepository.findOneByName("root", 0); 

는 하위 디렉터리로 rootLevel2을 가지고 하위 디렉터리로 rootLevel1을 갖는 루트 디렉토리를 가져옵니다. 마치 깊이가 고려되지 않은 것처럼.

하위 디렉토리가있는 노드를 선택할 수 있지만 하위 디렉토리의 하위 디렉토리의 하위 디렉토리는 어떻게 선택할 수 있습니까?

감사합니다.

[편집]

나는 내 통합 테스트에 거래 주석을 제거하면 SDN의 fecthing 시스템에 영향을 미치는 것으로 나타났다.

트랜잭션 주석을 사용하면 SDN이 모든 하위 디렉토리를 열정적으로 가져 와서 Neo4J에서 전체 디렉토리 구조를로드합니다.

트랜잭션 주석이 없으면 SDN이 지연적으로 가져오고 내 디렉토리 bean은 "subDirectories"속성으로 null을 갖습니다.

내 문제를 해결할 수 있지만 뒤에 묻는 질문에 대답하지 않습니다. 가져올 사용자 지정 깊이를 설정하는 방법.

+0

SDN/OGM의 버그처럼 보입니다. https://github.com/neo4j/neo4j-ogm/issues/324와 관련이있을 수 있습니다. 문제를 제출해주십시오. – nmervaillie

+0

@nmervaillie 사실, 이상한 "버그"가 있습니다. 나는 테스트 클래스에서 Transactional 주석을 처음부터 가지고 있었다. 하지만 제거하면 Iall 디렉터리 빈에는 하위 디렉터리가 없습니다. 따라서 Transactional SDN은 모든 관계를 재귀 적으로 연결합니다. Transactional SDN은 게으르지 않고 관계를 가져 오지 않습니다. –

답변

2

이 아마 고려할 수 있습니다.

엔티티를 읽을 때 SDN/OGM은 해당 엔티티를 이미 읽을 수 있음을 감지합니다 (ID 기반). 세션이 진행되는 동안 완전히 채워집니다.

@Transactional을 제거하면 각 db 액세스가 새로운 세션에서 실행되어 예상 된 결과를 제공합니다.

쓰기 직후에 어떤 이유로 든 읽을 필요가있는 경우 OGM 세션을 삽입하여 session.clear()을 호출하여 강제로 세션을 새로 고침 할 수 있습니다.

+0

맞아, 그것은 트랜잭션 주석과 함께 작동하고 session.clear()는 init 코드 다음에 그냥 사용한다. 감사 ! –

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 
+0

답장을 보내 주셔서 감사합니다. 그러나 그것은 내가 원하는 것을하지 않습니다. 루트 디렉토리를 원하지만 SDN4는 "가져 오기"에 문제가 있다고 생각합니다. 그래서 요청을 가져온 후에 비어있는 subDirectories 속성을 원합니다. –