Neo4j Spatial 'WithinDistance' Cypher request returns empty while REST call returns data

I have what seems like a properly configured spatial layer and index, and can successfully query the node using the findGeometriesWithinDistance REST API call.

POST /db/data/ext/SpatialPlugin/graphdb/findGeometriesWithinDistance {"layer":"geom","pointX":15.0,"pointY":60.0,"distanceInKm":100.0} 

However, when querying using cypher, I don't get any results (I tried to reorder 60.0 and 15.0 with no luck):

 START n=node:geom('withinDistance:[60.0, 15.0, 500.0]') return n; 

Cyper returns:

 ==> +---+ ==> | n | ==> +---+ ==> +---+ ==> 0 row ==> ==> 13 ms 

REST:

 200 OK ==> [ { ==> "paged_traverse" : "http://localhost:7474/db/data/node/14472/paged/traverse/{returnType}{?pageSize,leaseTime}", ==> "outgoing_relationships" : "http://localhost:7474/db/data/node/14472/relationships/out", ==> "data" : { ==> "lon" : 15.2, ==> "bbox" : [ 15.2, 60.1, 15.2, 60.1 ], ==> "RaceName" : "Parador Es Muy Caliente", ==> "lat" : 60.1, ==> "gtype" : 1 ==> }, ==> "all_typed_relationships" : "http://localhost:7474/db/data/node/14472/relationships/all/{-list|&|types}", ==> "traverse" : "http://localhost:7474/db/data/node/14472/traverse/{returnType}", ==> "self" : "http://localhost:7474/db/data/node/14472", ==> "all_relationships" : "http://localhost:7474/db/data/node/14472/relationships/all", ==> "property" : "http://localhost:7474/db/data/node/14472/properties/{key}", ==> "properties" : "http://localhost:7474/db/data/node/14472/properties", ==> "outgoing_typed_relationships" : "http://localhost:7474/db/data/node/14472/relationships/out/{-list|&|types}", ==> "incoming_relationships" : "http://localhost:7474/db/data/node/14472/relationships/in", ==> "incoming_typed_relationships" : "http://localhost:7474/db/data/node/14472/relationships/in/{-list|&|types}", ==> "extensions" : { ==> }, ==> "create_relationship" : "http://localhost:7474/db/data/node/14472/relationships" ==> } ] 

REST Calls to play: Create a layer:

 POST /db/data/ext/SpatialPlugin/graphdb/addSimplePointLayer { "layer":"geom", "lat":"lat", "lon":"lon" } 

Create Index:

 POST /db/data/index/node/ {"name":"geom", "config":{"provider":"spatial", "geometry_type":"point","lat":"lat","lon":"lon"}} 

Create Node:

 POST /db/data/node {"lat":60.2,"lon":15.1,"RaceName":"Parador Es Muy Caliente"} 

(In response, consider "self" and look for nodeid)

Node Index:

 POST /db/data/ext/SpatialPlugin/graphdb/addNodeToLayer {"layer":"geom", "node":"http://localhost:7474/db/data/node/###NEW_NODE_ID###"} 

Search:

 POST /db/data/ext/SpatialPlugin/graphdb/findGeometriesWithinDistance {"layer":"geom","pointX":15.0,"pointY":60.0,"distanceInKm":100.0} 
+8
neo4j spatial
source share
2 answers

I researched this, and this is due to a problem that we have seen several times. There is an inconsistency in the design of the spatial library that there are two ways to add node to the spatial index. One of them is to add it to the layer (using the REST call addNodeToLayer), and it uses the basic Java API, which directly connects the node in RTree as part of the same graph. Another is to create a proxy node in the index graph so that your domain graph is not associated with the index graph. This second approach is only used by the IndexProvider interface (by calling / db / data / index / node / geom REST).

If you call both methods, node is added twice, once directly and once through the proxy. The problem is that the Cypher inDistance index request accesses the IndexProvider interface and returns only nodes that are NOT connected to the index either. Therefore, if you add a node in both directions, it will not be returned.

So, you need to add it in only one of two ways. I did not see in your original letter a mention of addNodeToLayer, so I suspect that the SDN may call addNodeToLayer (maybe Michael may comment), in which case you cannot use the cypher call.

During my testing, I was able to manually delete one index relation using Cypher as follows:

START n = node (13065) MATCH (n) <- [r: RTREE_REFERENCE] - () DELETE r

Replace the number 13065 with your id node for the original node.

I did the following in the neo4j browser (in 2.1.2):

 :POST /db/data/ext/SpatialPlugin/graphdb/addSimplePointLayer { "layer":"geom", "lat":"lat", "lon":"lon" } :POST /db/data/index/node/ {"name":"geom", "config":{"provider":"spatial", "geometry_type":"point","lat":"lat","lon":"lon"}} :POST /db/data/node {"lat":60.2,"lon":15.1,"RaceName":"Parador Es Muy Caliente"} :POST /db/data/index/node/geom {"value":"dummy","key":"dummy", "uri":"http://localhost:7474/db/data/node/13071"} 

This created a graph with node that is not directly related to the index. In this case, the REST call 'findGeometriesWithinDistance' does not work (uses the standard Java API), while the cypher 'insideDistance' works. I tested this command:

 start n = node:geom("withinDistance:[60.2,15.1,100.0]") return n 

Please note that, unfortunately, this API puts the order as lat, lon, and not the more standard lon, lat.

Then I also added to the layer (i.e. add it directly to the index graph):

 :POST /db/data/ext/SpatialPlugin/graphdb/addNodeToLayer {"layer":"geom", "node":"http://localhost:7474/db/data/node/13071"} 

Now when I search using the cypher command, I still get the same correct answer, but when I look for the REST command:

 :POST /db/data/ext/SpatialPlugin/graphdb/findGeometriesWithinDistance {"layer":"geom","pointX":15.0,"pointY":60.0,"distanceInKm":100.0} 

I believe this returns a proxy node instead of the original node.

+6
source share

this is a mistake, see https://github.com/neo4j/spatial/issues/106 , if you want, feel free to investigate, it seems like an iteration in SpatialRecordHits.java!

Meanwhile, be sure to add node to the index before querying through the index, as this creates the correct node structure.

+3
source share

All Articles