0

I'm using Neo4j 3.2 with the Neo4j Spatial plugin 0.24-neo4j-3.1.1 After adding layers, I tried to create node and add it to the index with spatial.addNode

CALL spatial.addPointLayer('geom');

CREATE (n:Node {latitude:60.1,longitude:15.2})
WITH n
CALL spatial.addNode('geom',n) YIELD node
RETURN node;

I also tried create a new one and add to the index later

CREATE (n:Node {latitude:60.1,longitude:55.2});

MATCH (n:Node {latitude:60.1,longitude:55.2})
WITH n
CALL spatial.addNode('geom',n) YIELD node
RETURN node;

Later on when I tried to call

CALL spatial.removeLayer("geom");

The procedure delete all nodes including those created by

CREATE (n:Node {latitude:60.1,longitude:55.2});

Is it a by-design behavior?

If it is, can you suggest any other way to update/delete the indexes without deleting the location node? There is a proposed solution here but it seems hacky and error-prone when it comes to updating the index information when the location node change the lat/long value neo4j-spatial: What is the official way to delete a node from a spatial index?

LxL
  • 1,878
  • 2
  • 20
  • 39

1 Answers1

1

I have looked into the source code of the neo4j spatial package to see how the addNode and removeLayer procedures implemented.

When you call addNode, the node itself will be directly added into the RTree, which means it will serve as a leaf node in the RTree.

When you call removeLayer, everything in the RTree will be removed from neo4j, including all the nodes and all the edges in this RTree.

Since I have not found one method to remove the RTree information without touching the leaf nodes, I would suggest the following way:

When you want to add a node into the RTree, you can create a new node with the same location (replicate the original node) and create an edge from the original node to this new one. By doing so, when you call removeLayer, only the nodes replicated by you will be deleted. Your original nodes will not be influenced. The cost is you need to spend more storage.

ps. When you want to call removeLayer in this case, you need to delete the edges you create before calling removeLayer. The reason is a node cannot be deleted if there is any edge connected to it.

Yuhan Sun
  • 102
  • 5
  • I was thinking about this approach but it comes with the drawback that when I need to update a original node I need to make sure it's in sync with the RTree node. My original problem comes from the need of updating the RTree when the node changes. And because neo4j spatial don't allow it, I thought I could just remove the whole layer and run the indexing again. I'll leave this bounty open for the next 6 days to extract more people. If there is no more answer I will award it to you. – LxL Jul 01 '17 at 03:44
  • Have you tried this procedure:¦ "spatial.updateFromWKT" ¦ "Internal procedure, updates the geometry node with the given id with a new WKT string" – Yuhan Sun Jul 01 '17 at 20:53
  • Can you please point me to the example of that procedure? It wasn't clear to me how that procedure works – LxL Jul 02 '17 at 06:55
  • From this link: https://github.com/neo4j-contrib/spatial/blob/c2030cac0faa9cd4d70c02fdb060ad7f5a1683ed/src/main/java/org/neo4j/gis/spatial/procedures/SpatialProcedures.java, you can see that this proc takes three parameters. The first parameter is the layername, second is a string that follows the wkt format. For wkt format , you may refer to this link: https://en.wikipedia.org/wiki/Well-known_text. The third parameter is the node id to be updated. – Yuhan Sun Jul 05 '17 at 01:21
  • If you achieve the function successfully, could you please share your example here? Since there is few related information online. Thanks. – Yuhan Sun Jul 06 '17 at 02:56
  • Currently, I haven't tried that procedure yet. I'll update the question once I successfully tried it. – LxL Jul 08 '17 at 18:54