当REST调用返回数据时,Neo4j Spatial“WithinDistance”Cypher查询返回空

时间:2013-07-31 09:34:43

标签: neo4j spatial

我有一个看似正确配置的空间图层和索引,并且可以使用findGeometriesWithinDistance REST API调用成功查询节点。

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

然而,当使用cypher进行查询时,我没有得到任何结果(我试图在没有运气的情况下颠倒60.0和15.0的顺序):

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

Cyper返回:

==> +---+
==> | 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调用重现: 创建图层:

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"}

(作为回应,检查“self”并找到nodeid)

索引节点:

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

查找

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

2 个答案:

答案 0 :(得分:7)

我对此进行了调查,这与我们已经看过几次的问题有关。空间库的设计存在不一致,因为有两种方法可以将节点添加到空间索引中。一个是将它添加到Layer(使用addNodeToLayer REST调用),这使用底层Java API,它直接将节点连接到RTree作为同一个图的一部分。另一种方法是在索引图中创建一个代理节点,这样您的域图就不会连接到索引图。第二种方法仅由IndexProvider接口(使用/ db / data / index / node / geom REST调用)进行。

如果同时调用这两种方法,则会将节点添加两次,一次直接添加,一次添加一次。问题是Cypher withinDistance索引查询仅访问IndexProvider接口,并且只返回未连接到索引的节点。因此,如果以两种方式添加节点,则不会返回该节点。

所以你只需要添加两种方式中的一种。我没有在你的原始电子邮件中看到任何addNodeToLayer的提及,所以我怀疑SDN可能正在调用addNodeToLayer(也许Michael可以评论),在这种情况下你不能使用密码调用。

在我测试期间,我能够使用Cypher手动删除一个索引关系:

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

将数字13065替换为原始节点的节点ID。

我在neo4j浏览器中进行了以下操作(在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"}

这创建了一个图表,节点不直接连接到索引。在这种情况下,REST调用“findGeometriesWithinDistance'不起作用(使用标准的Java API),而密码则在“距离”内。确实有效。我用这个命令测试了:

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

请注意,遗憾的是,此API将订单设置为lat,lon,而不是更标准的lon,lat。

然后我也添加到图层(即直接添加到索引图):

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

现在,当我使用cypher命令搜索时,我仍然得到相同的正确答案,但是当我使用REST命令搜索时:

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

我发现这会返回代理节点而不是原始节点。

答案 1 :(得分:4)

这是一个错误,如果需要,请参阅https://github.com/neo4j/spatial/issues/106,随时调查,似乎是SpatialRecordHits.java中的迭代!

同时,确保在通过索引查询之前将节点添加到索引,因为这会创建正确的节点结构。