Neo4j空间Cypher查询withinDistance不返回现有节点

3

我正在使用Neo4j 2.0的空间服务器插件,并遵循http://neo4j.github.io/spatial/上的指南,添加了一个名为Stockholm的节点。

:POST http://localhost:7475/db/data/ext/SpatialPlugin/graphdb/addSimplePointLayer
{
  "layer" : "geom",
  "lat" : "lat",
  "lon" : "lon"
}
:POST http://localhost:7475/db/data/index/node/
{
  "name" : "geom",
  "config" : {
    "provider" : "spatial",
    "geometry_type" : "point",
    "lat" : "lat",
    "lon" : "lon"
  }
}
:POST http://localhost:7475/db/data/node
{
  "lat" : 60.1,
  "lon" : 15.2,
  "name" : "Stockholm"
}
:POST http://localhost:7475/db/data/ext/SpatialPlugin/graphdb/addNodeToLayer
{
  "layer" : "geom",
  "node" : "http://localhost:7475/db/data/node/4"
}

我可以通过REST获取节点,使用以下方法:

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

但不适用于以下密码查询。为什么呢?我在这里犯了什么明显的错误吗?
START n=node:geom('withinDistance:[60.0,15.0, 100.0]') RETURN n;
2个回答

4
我刚刚发现,在Neo4j 2.1.2和Neo4j Spatial 0.13-neo4j-2.1.2中,您不需要像上面描述的那样将节点添加到索引中。
创建节点后,添加一个属性,将用户“id”属性设置为Neo4j节点id值。 Cypher空间查询现在将起作用。因此,如果您添加Cypher命令
start n=node(4) n.id = id(n)

查询将会生效。
显然,还有其他方法来形成Cypher语句。实际上,你可以通过几个批量步骤完成所有这些操作。你可以将所有节点添加到RTree图中(使用REST、Java、批量shp文件加载器等),在每个节点上创建自引用用户“id”属性,然后创建空间索引(问题帖子中的第二个REST命令)。
你看到的问题似乎来自于REST addNodeToLayer过程和Cypher“add node to index”过程之间的断开。Cypher过程创建了一个包含原始节点的几何属性(lat/lon、wkt等)的第二个节点,并将该节点添加到RTree图中。该节点具有名为“id”的用户属性,其值为原始节点的Neo4j节点ID。REST(或Java)addNodeToLayer过程直接将原始节点添加到RTree图中,而不创建副本。它也不在节点上设置名为“id”的用户属性。
如果你使用Cypher方法将节点添加到RTree图中,你会发现通过REST查询返回给你的节点是副本节点,而不是原始节点。当你使用相同的查询使用Cypher方法时,你会得到原始节点。Cypher查询中的底层代码通过使用查询找到的副本节点上的用户“id”属性获取原始节点来返回原始节点。当最初由Cypher查询找到的节点不包含可以解引用的id属性时,Cypher查询会默默地失败,并返回0个结果。
通过为RTree图中的每个数据节点添加自引用id属性,Cypher查询能够成功找到要返回的节点。
使用前面答案中描述的REST方法是可行的,但它最终会使几何存储成本增加一倍,因为它会复制原始节点上保存的几何信息。当使用该方法时,Cypher和REST查询返回的结果也不同。使用我描述的方法可以节省空间并统一Cypher和REST查询行为。

Jim,你的意思是“在创建节点并将其添加到层之后,再设置id”吗?如果我随后更改节点中的经度/纬度属性,那么搜索空间索引是否会返回正确的结果?我这样问是因为当我这样做时,看起来bbox在空间节点中没有发生改变。 - Dr Joe
1
我认为顺序并不重要。您可以在将其添加到图层之前或之后设置id属性。正如我在另一个答案的评论中提到的那样,您必须使用REST updateGeometryFromWKT方法或java EditableLayer.update方法来更改节点的几何形状。 - Jim Biard
啊!EditableLayer.update - 这就是我缺少的部分!我会尝试一下并看看会发生什么。谢谢。 - Dr Joe

2

非常感谢您的回答和易于理解的文章! - Jenny Pettersson
这篇文章已经不存在了。有新的链接吗?我想开始使用neo4j空间功能。 - Peter R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接