在距离内的Neo4j空间密码查询不会返回现有节点

时间:2014-03-13 14:51:32

标签: neo4j neo4j-spatial

我正在使用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 个答案:

答案 0 :(得分:4)

我刚刚发现你不必如上所述将节点添加到索引中,至少不是Neo4j 2.1.2和Neo4j Spatial 0.13-neo4j-2.1.2。

创建节点后,添加一个设置为user" id"的属性。属性为Neo4j节点id值。密码空间查询现在可以工作。所以,如果你添加了cypher命令

start n=node(4) n.id = id(n)

查询将有效。

显然,有其他方式可以形成Cypher声明。实际上,您可以通过几个批量步骤完成所有这些操作。您可以将所有节点添加到RTree图(使用REST,Java,批量shp文件加载器等),创建自引用用户" id"每个节点上的属性,然后创建空间索引(问题帖子中的第二个REST命令)。

您看到的问题似乎来自REST addNodeToLayer进程与Cypher之间的脱节"将节点添加到索引"处理。 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查询行为。

答案 1 :(得分:2)

为了使用Cypher进行查询,您需要将每个节点添加到索引中:

    :POST http://localhost:7474/db/data/index/node/geom
    {
      'value': 'dummy', 
      'key': 'dummy', 
      'uri': 'http://localhost:7474/db/data/node/NODE_ID_HERE'
    }

我写了一篇关于最近开始使用Neo4j Spatial的博文,内容涵盖了这一点:http://lyonwj.com/mapping-the-worlds-airports-with-neo4j-spatial-and-openflights-part-1/