2016-06-05 8 views
0

Внутри моего TransactionEventHandler.beforeCommit() Я пытаюсь удалить узел из пространственного индекса после его успешного добавления. Но узел остается в индексе, и я все еще могу его найти, используя пространственный запрос Cypher.Невозможно удалить узел из Neo4j Пространственный индекс

Это отрывок из моего кода:

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 Spatial? В любом случае, как я могу достичь своей цели?

PS: Я использую Neo4j 2.3.2 и Neo4j Spatial 0.15-neo4j-2.3.1.

Я нашел решение (обходной путь):

Уильяма Лион пролить некоторый свет на ситуации:

Когда узел добавляется к пространственному индексу с помощью пространственного интерфейса IndexProvider он создает прокси-узла и добавляет этот узел в пространственный индекс, сохраняя исходный узел отдельно от индекса RTree в графике .

Я обнаружил, что прокси-узел всегда содержит свойство «id». Он указывает на исходный узел. Нам даже не нужно добавлять его вручную (как было предложено Уильямом). Используя его, мы можем найти прокси-узел, чтобы удалить его вручную.

Иногда наш график может выглядеть следующим образом:

enter image description here

И иногда это может стать немного более сложным:

enter image description here

На изображениях:

  1. Пространственный корень (узел с «ReferenceNode» l Авель) отмечен как «1»
  2. Узел прокси выбран

Таким образом, мы можем использовать следующий Cypher запрос для того, чтобы найти и удалить узел прокси:

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

И здесь представляет собой комплексное решение, которое я в настоящее время используют в мой 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' - это просто строка« location »; и 'CONFIG' - это просто' SpatialIndexProvider.SIMPLE_POINT_CONFIG'. –

+0

@WilliamLyon Я добавил информацию в вопрос. Пожалуйста, взгляните на это. Полагаю, это может помочь лучше понять мою ситуацию. Заранее спасибо. –

ответ

1

Когда узел добавляется к пространственный индекс, используя пространственный интерфейс IndexProvider, он создает прокси и добавляет , что узел к пространственному индексу, сохраняя исходный узел отдельно от индекса RTree в графике.

Это несовместимо с другими интерфейсами для пространственной библиотеки и вызвало некоторую путаницу. См. this SO post для получения дополнительной информации.

Вы можете добавить свойство id к узлу, который вы индексируете, чтобы найти прокси-узел, когда хотите удалить его из индекса, или использовать пространственный Java API для добавления/удаления узлов из пространственного слоя в избегайте создания прокси-узла.

+0

Спасибо! Ваш ответ указал мне в правильном направлении. Наконец, я смог удалить прокси-узел. Я описал свое решение по моему вопросу. Но я до сих пор не понимаю, почему простой 'index.remove (node);' не работает. Я использовал его последовательно с 'index.add (node, null, null);'. Похоже, он должен был работать, и это поведение является ошибкой. –

 Смежные вопросы

  • Нет связанных вопросов^_^