2
votes

We recently upgraded from Neo4j 1.9 to 2.1 and are now receiving an error when an existing object is updated with a spatial index.

We are using the following:

Spring Data NEO4J 3.1 Neo4j 2.1.2 server with the spatial plugin

I have narrowed the problem down to a REST call of the following:

http://localhost:7474/db/data/index/node/<index name>

JSON Post:
{
    "value" : "POINT(-87.626451 41.870515)",
    "uri" : "http://localhost:7474/db/data/node/113",
    "key" : "wkt"
}

I am getting the following response:

{
  "message" : "GeometryNode not indexed in this RTree: 114",
  "exception" : "RuntimeException",
  "fullname" : "java.lang.RuntimeException",
  "stacktrace" : [ "org.neo4j.gis.spatial.rtree.RTreeIndex.findLeafContainingGeometryNode(RTreeIndex.java:812)", "org.neo4j.gis.spatial.rtree.RTreeIndex.remove(RTreeIndex.java:111)", "org.neo4j.gis.spatial.rtree.RTreeIndex.remove(RTreeIndex.java:100)", "org.neo4j.gis.spatial.EditableLayerImpl.update(EditableLayerImpl.java:56)", "org.neo4j.gis.spatial.indexprovider.LayerNodeIndex.add(LayerNodeIndex.java:143)", "org.neo4j.gis.spatial.indexprovider.LayerNodeIndex.add(LayerNodeIndex.java:41)", "org.neo4j.server.rest.web.DatabaseActions.addToNodeIndex(DatabaseActions.java:686)", "org.neo4j.server.rest.web.RestfulGraphDatabase.addToNodeIndex(RestfulGraphDatabase.java:1022)", "java.lang.reflect.Method.invoke(Unknown Source)", "org.neo4j.server.rest.transactional.TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:139)", "java.lang.Thread.run(Unknown Source)" ]
}

EDIT

After doing some additional research I found that the error is being thrown because the root node of the geometry relationship (952) does not equal the root node of the index root (2308).

Here are the relationships and node properties for the associated geometry node and the index root:

114<-[RTREE_REFERENCE]-6<-[RTREE_CHILD]-952<-[RTREE_CHILD]-(null)

114
id  113
bbox [-87.626451,41.870515,-87.626451,41.870515]
wkt POINT (-87.626451 41.870515)
gtype   1

6
bbox [-88.459688,41.711991,-86.856991,42.153793]

952
bbox [-118.823745,0,0,44.591593]


2307-[RTREE_ROOT]->[2308]

2307
layer_class   org.neo4j.gis.spatial.EditableLayerImpl
layer         dib_location
geomencoder   org.neo4j.gis.spatial.WKTGeometryEncoder
geomencoder_config   wkt
ctime  1404877913340

2308
layer_class org.neo4j.gis.spatial.EditableLayerImpl
layer   dib_location
geomencoder org.neo4j.gis.spatial.WKTGeometryEncoder
geomencoder_config  wkt
ctime   1404877913340
2

2 Answers

1
votes

I've not worked with older versions of Neo4j Spatial, but in the current version (0.13 for Neo4j 2.1.2) the command to add a node to a spatial index is described as

POST http://localhost:7474/db/data/index/node/<index name> {"key":"dummy", "value":"dummy", "uri":"http://localhost:7474/db/data/node/113"}

with the wkt property already set on the node itself. If you look at the LayerNodeIndex.java source file, you will see that the key and value arguments are ignored. So use Cypher or REST to add the wkt property to the node, then add the node to the spatial index, and it should work fine for Cypher queries.

If you want to do REST queries, you will discover that the method of adding nodes to the spatial index that you are using doesn't add the node to the RTree graph. It creates a new node, puts the geometry property or properties from the original on the new node, puts the node number of the original node into a user 'id' propery, and puts this new node into the RTree graph. So, when you do a REST spatial query, you get back this 'copy' node. To get your original node, you must get the node by its node number using the value stored in the 'id' property in the copy node. If you won't be using Cypher, use the REST addNodeToLayer. If you would like to do both without involving copy nodes, create a self-referential user 'id' property on the original node that contains its Neo4j node number before adding it to the layer with the addNodeToLayer call. If you do this, there is no need to use the REST add to index call at all and all methods will work.

By the way, the Neo4j spatial index (the one accessed by the path /db/data/index/node/) does not actually have any contents. It is an access point stub for the spatial plugin.

In answer to the further question in your comment, look at my answer to this other question to see a detailed example of the REST calls to make.

0
votes

In Neo4j 2.x we had to change the way works as there is no default root node anymore. You should be able to label your root node (node 0)) as :ReferenceNode. Then it should work again.