2016-06-05 10 views
0

인사이드 내 TransactionEventHandler.beforeCommit() 성공적으로 추가 된 후에 공간 인덱스에서 노드를 제거하려고합니다. 그러나 노드는 여전히 색인에 남아 있으며 공간 Cypher 쿼리를 사용하여 찾을 수 있습니다.Neo4j Spatial 인덱스에서 노드를 제거 할 수 없습니다.

Index<Node> index = getGraphDatabaseService().index().forNodes("locations", SpatialIndexProvider.SIMPLE_POINT_CONFIG); 
if (node.hasProperty("lat") && node.hasProperty("lon")) { 
    index.add(node, null, null); // it works perfectly 
} else { 
    index.remove(node); // it doesn't work 
} 

이이 Neo4j 공간에서 알려진 버그 :

이 내 코드에서 발췌 한 것입니다? 어쨌든, 어떻게 내 목표를 달성 할 수 있습니까?

추 신 : Neo4j 2.3.2 및 Neo4j Spatial 0.15-neo4j-2.3.1을 사용합니다.는 윌리엄 리 상황 되거있다

: 노드 공간 IndexProvider 인터페이스를 이용하여 공간 인덱스에 추가

그것이 만들어

내가 용액 (해결 방법)을 발견 프락시 노드를 추가하고 해당 노드를 공간 인덱스에 추가하여 원본 노드를 그래프 내의 RTree 인덱스와 분리합니다.

프록시 노드에는 항상 "id"속성이 포함되어 있습니다. 원래 노드를 가리 킵니다. 우리는 수동으로 추가 할 필요가 없습니다 (William에 의해 제안 된 것처럼). 프록시 노드를 사용하면 프록시 노드를 수동으로 삭제할 수 있습니다.

enter image description here

을 그리고 경우에 따라서는 좀 더 복잡해질 수 있습니다 :

때때로 우리의 그래프는 다음과 같이 보일 수 있습니다

enter image description here

이미지에 :

  1. 공간 루트 ("ReferenceNode"가있는 노드

    MATCH (:ReferenceNode)-[:LAYER]-()-[:RTREE_ROOT]-()-[*..]-(n {id:{id}}) MATCH (n)-[r:RTREE_REFERENCE]-() DELETE r, n 
    

    그리고 여기 : 아벨은) 우리가 찾아 프록시 노드를 삭제하기 위해 다음 사이퍼 쿼리를 사용할 수 있습니다, 프록시 노드는

그래서을 선택

  • "1"로 표시 이다 나는 현재 내에서 사용할 수있는 완벽한 솔루션 내 TransactionEventHandler :

    private static final String INDEX_NAME = "locations"; 
    private static final Map<String, String> CONFIG = SpatialIndexProvider.SIMPLE_POINT_CONFIG; 
    private static final String LAT = CONFIG.get(LayerNodeIndex.LAT_PROPERTY_KEY); 
    private static final String LON = CONFIG.get(LayerNodeIndex.LON_PROPERTY_KEY); 
    
    @Override 
    public Void beforeCommit(TransactionData data) throws Exception { 
        Index<Node> index = getGraphDatabaseService().index().forNodes(INDEX_NAME, CONFIG); 
        Node originalNode = <...>; 
        if (originalNode.hasProperty(LAT) && originalNode.hasProperty(LON)) { 
         index.add(originalNode, null, null); 
        } else { 
         deleteProxyNode(originalNode.getId()); 
        } 
        return null; 
    } 
    
    private void deleteIndexedProxyNode(long originalNodeId) { 
        String query = "" + 
          "MATCH (:ReferenceNode)-[:LAYER]-()-[:RTREE_ROOT]-()-[*..]-(n {id:{id}}) " + 
          "MATCH (n)-[r:RTREE_REFERENCE]-() " + 
          "DELETE r, n"; 
        Map<String, Object> parameters = new HashMap<>(); 
        parameters.put("id", originalNodeId); 
        getGraphDatabaseService().execute(query, parameters); 
    } 
    
  • +0

    노드를 색인에 추가하는 데 사용하는 코드를 공유 할 수 있습니까? 'INDEX_NAME'과'CONFIG'의 값뿐만 아니라? –

    +0

    @WilliamLyon 이미 다음과 같은 코드를 보았습니다 : 다음 줄에 인덱스에 노드를 추가합니다 :'index.add (node, null, null);''INDEX_NAME'은 단순히 문자열 "locations"입니다. 'CONFIG'는 단순히'SpatialIndexProvider.SIMPLE_POINT_CONFIG'입니다. –

    +0

    @WilliamLyon 질문에 정보를 추가했습니다. 제발, 한번보세요. 나는 내 상황을 더 잘 이해하는 데 도움이 될 것이라고 믿습니다. 미리 감사드립니다. –

    답변

    1

    노드가들에 추가 patial 인덱스를 사용하여 프록시 노드를 생성하고 노드를 공간 인덱스에 추가하여 원본 노드를 그래프 내 RTree 인덱스와 분리하여 유지합니다.

    이는 공간 라이브러리의 다른 인터페이스와 일치하지 않으며 혼란을 야기합니다. 좀 더 자세한 정보는 this SO post을 참조하십시오.

    색인에서 제거하려는 프록시 노드를 찾으려면 인덱스 노드에 id 특성을 추가하거나 공간 Java API를 사용하여 공간 계층에서 노드를 추가/제거하십시오 프록시 노드를 작성하지 마십시오.

    +0

    감사! 당신의 대답은 저에게 올바른 방향으로 지적했습니다. 마지막으로 프록시 노드를 삭제할 수있었습니다. 내 질문에 내 솔루션을 설명했다. 하지만 여전히'index.remove (node);가 왜 작동하지 않는지 이해할 수 없습니다. 나는 그것을'index.add (node, null, null); '과 일관되게 사용했다. 작동해야하는 것처럼 보입니다.이 동작은 버그입니다. –