2014-03-13 78 views
3

我正在使用Neo4j 2.0的空间服务器插件,并按照指南http://neo4j.github.io/spatial/添加名为Stockholm的节点。Neo4j空间密码查询withinDistance不返回现有节点

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

但不与下面的CYPHER查询。这是为什么?我在这里做了什么明显的错误?

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

回答

2

为了使用暗号来查询你需要在每个节点添加到索引:

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

我写的越来越开始Neo4j的空间最近覆盖此博客文章:http://lyonwj.com/mapping-the-worlds-airports-with-neo4j-spatial-and-openflights-part-1/

+0

非常感谢您的回答和一个很好理解的文章! –

+0

文章不见了。任何新的链接?试图开始使用neo4j spatial –

4

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

创建节点后,添加一个设置为用户“id”属性为Neo4j节点ID值的属性。密码空间查询现在可以工作。因此,如果您添加密码指令

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

该查询将起作用。

显然还有其他方式可以形成Cypher声明。事实上,你可以在几个大步骤中完成所有这些。您可以将所有节点添加到RTree图(使用REST,Java,bulk shp文件加载器等),在每个节点上创建自引用用户“id”属性,然后创建空间索引(问题中的第二个REST命令后)。

您看到的问题似乎来自REST addNodeToLayer进程与Cypher“添加节点到索引”进程之间的断开连接。 Cypher进程创建第二个节点,该节点仅包含来自原始节点的几何属性(经纬度,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查询行为。

+0

Jim,你的意思是“在创建节点**并将其添加到图层**之后,然后设置ID”?如果我随后更改节点中的lon/lat属性会发生什么情况;搜索空间索引是否返回正确的结果?我问,因为当我这样做时,它看不到空间节点中的bbox变化。 –

+1

我不相信订单很重要。您可以在将其添加到图层之前或之后设置id属性。正如我在对不同答案的评论中所述,您必须使用REST updateGeometryFromWKT方法或java EditableLayer.update方法更改节点的几何。 –

+0

啊! EditableLayer.update - 这是我失踪的一点!我会和你一起玩,看看会发生什么。谢谢。 –