【发布时间】:2016-06-05 22:04:32
【问题描述】:
在我的TransactionEventHandler.beforeCommit() 中,我试图在成功添加节点后从空间索引中删除它。但是该节点仍保留在索引中,我仍然能够使用空间密码查询找到它。
这是我的代码的摘录:
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。
我找到了解决方案(解决方法):
William Lyon 阐明了一些情况:
当使用空间索引将节点添加到空间索引时 IndexProvider 接口它创建一个代理节点并将该节点添加到 空间索引,保持原始节点与 图内 RTree 索引。
我发现,代理节点总是包含一个“id”属性。它指向原始节点。我们甚至不需要手动添加它(正如 William 所提议的那样)。使用它我们可以找到代理节点以便手动删除它。
有时我们的图表可能如下所示:
有时它可能会变得有点复杂:
在图片上:
- 空间根(带有“ReferenceNode”标签的节点)标记为“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只是一个字符串“位置”;而CONFIG就是SpatialIndexProvider.SIMPLE_POINT_CONFIG。 -
@WilliamLyon 我在问题中添加了信息。请看一下。我相信,这可能有助于更好地了解我的情况。提前致谢。
-
现在找到解决方案(解决方法)。它在我的问题下进行了描述。
标签: neo4j spatial spatial-index