Внутри моего 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». Он указывает на исходный узел. Нам даже не нужно добавлять его вручную (как было предложено Уильямом). Используя его, мы можем найти прокси-узел, чтобы удалить его вручную.
Иногда наш график может выглядеть следующим образом:
И иногда это может стать немного более сложным:
На изображениях:
- Пространственный корень (узел с «ReferenceNode» l Авель) отмечен как «1»
- Узел прокси выбран
Таким образом, мы можем использовать следующий 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);
}
Можете ли вы поделиться кодом, который используете, чтобы добавить узел в индекс? Как и значения для 'INDEX_NAME' и' CONFIG'? –
@WilliamLyon Вы уже смотрите на этот код: я добавляю узел к индексу в следующей строке: 'index.add (node, null, null);' 'INDEX_NAME' - это просто строка« location »; и 'CONFIG' - это просто' SpatialIndexProvider.SIMPLE_POINT_CONFIG'. –
@WilliamLyon Я добавил информацию в вопрос. Пожалуйста, взгляните на это. Полагаю, это может помочь лучше понять мою ситуацию. Заранее спасибо. –