【问题标题】:Neo4j Spatial return only one nodeNeo4j Spatial 只返回一个节点
【发布时间】:2014-07-29 14:02:41
【问题描述】:

我在 neo4j 中创建了一个空间索引,但是在搜索附近的地方时,我只得到一个结果。

我的查询是:

START n=node:geom('withinDistance:[63.36, 10.35, 50.0]') RETURN n

我在空间索引中有 3 个节点,这些节点具有以下坐标:

  • 节点 1 纬度、经度:63.3654、10.3578
  • 节点 2 纬度、经度:63.3654、10.3577
  • 节点 3 纬度、经度:63.3654、10.3578(同一节点 1)

理论上这三个节点在同一个区域。

有什么想法吗?

更新

我执行了这些步骤来使用空间(全部从 neo4j 浏览器执行 -> rest api)

1) 索引创建

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

2) 节点创建(都以相同的方式)

:POST /db/data/node
{
    "name":"Franciscatos Pizza",
    "lat": 63.3654,
    "lon": 10.3578
}

3) 节点到空间索引

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

4) 节点到层

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

任何 API 响应都正常,所有被索引的节点都包含 :RTREE_REFERENCE 关系。

根据查询中的距离参数,这会返回不同的节点,但总是一个...

【问题讨论】:

  • 你能提供更多细节吗?如果您可以发布用于创建空间索引和节点的代码,则可能会知道发生了什么。

标签: neo4j neo4j-spatial


【解决方案1】:

达里奥斯,

首先,不要执行第 3 步)。步骤 3) 和 4) 有点多余,但步骤 3) 在节点中复制几何信息并创建存储到层中的第二个节点。相反,请执行此新步骤 3)。

START n = NODE(8)
SET n.id = ID(n)

此 Cypher 代码在包含 Neo4j 节点号的节点上添加了一个“id”参数。完成此操作后,您可以使用 Cypher 空间索引查询。请注意,第一行每次都会有不同的节点号。这个“id”属性是自引用的。

或者,执行步骤 3),但不要执行步骤 4)。但是,如果您执行 REST 几何查询,您将不会得到您期望的结果。

看看你的结果是否有所改善。

恩典与和平,

吉姆

PS。

迈克尔,

目前实际上有两种相互竞争的空间方法在发挥作用。如果您使用 addNodeToLayer 将节点添加到图层(如步骤 4 中所示),则该节点将直接链接到 RTree 图中,并且 Cypher 查询将找不到该节点。如果您使用 Java,这也是正确的。您可以使用 findGeometriesWithinDistance 和 findGeometriesInBBox 通过 REST 进行查询。

如果您使用“将节点添加到空间索引”方法将节点添加到图层(如步骤 3 中所示),它实际上不会将您的节点添加到图层。创建一个新节点,其中包含原始节点上的几何属性的副本和包含原始节点的 Neo4j 节点编号的“id”属性,并将此复制节点添加到 RTree 图中。 “空间索引”实际上并不包含节点列表。它是空间扩展代码的访问点。当您执行 Cypher 空间查询时,空间扩展会找到满足查询的副本节点,然后取消引用每个节点的“id”属性以构建原始节点的返回列表。

如果您仅使用步骤 4) 将节点添加到图层,则缺少取消引用的 'id' 属性会导致 Cypher 空间索引查询失败。通过添加 'id' 属性,取消引用成功,您可以从查询中获得结果。

shapefile 导入器将节点直接链接到 RTree,如果您希望能够进行 Cypher 空间索引查询,则需要按照我的描述将“id”属性添加到每个节点。 OSM 导入器构建相关的“域”和几何节点,但我认为它不会使基于 Cypher 的查询可以访问它们。如果您将“id”属性添加到每个几何节点,那么它们将是。

我可能错过了,但我还没有看到有人指出,如果您使用“将节点添加到空间索引”方法,您只是将拥有的节点数量增加了一倍,并且将节点数增加了一倍存储在数据库中的几何属性的数量。由于原始节点和复制节点之间没有建立关系,因此无法访问复制节点中的几何属性,因此无法真正从原始节点中删除几何属性。

因此,我发现将我的节点直接添加到 RTree 图中并通过添加自引用“id”属性使它们可通过 Cypher 空间索引查询(可查询?)更可取。

关于删除节点,没有 REST SpatialPlugin 方法可以从层中删除节点。如果使用 REST 空间索引方法将节点添加到 RTree 图中,则 REST 调用

:DELETE /db/data/index/node/geom/{ID}

将从 RTree 中删除节点,但有一个问题。您必须获取复制节点的 Neo4j 节点号才能使其正常工作!你不能以任何直接的方式。如果你设法获得了复制节点的节点号,它将从RTree中删除,但复制节点不会被删除。

有点讽刺的是,如果您使用 addNodeToLayer 将节点添加到 RTree 并且不添加“id”属性,则从索引中删除节点的调用会从 RTree 中删除节点。如果您添加自引用“id”属性,然后从索引中删除该节点,则该节点将被删除。所以每一种方法都是有缺陷的。

【讨论】:

  • 如果你只是做一个索引密码查询,实际上离开第 3 步。我不认为修改几何节点(当它有效时)是一个好主意。这个想法是将几何与域节点解耦,这就是为什么它使用地理信息创建一个单独的节点。另外,您将如何再次删除节点(仅从索引中)?
  • 我遇到了同样的问题并遵循了这个答案。一些肤浅的测试已经证实这种方法有效,我现在对密码查询和 REST 调用都得到了相同的结果。不过我不太明白后果。现在删除的正确方法是什么?
  • 如果您将“id”属性添加到节点,如果您真的想删除节点,请执行我的回答中提到的 REST DELETE 调用。这将从 RTree 中删除节点并将其删除。如果您只想从 RTree 中删除节点,请获取节点,删除“id”属性,然后执行 REST DELETE 调用。那应该从 RTree 中删除节点而不删除它(我认为)。
【解决方案2】:

我正在使用 neo4j 2.3,发现步骤 3) 没用,但步骤 4) 没有用,如果你不克隆 id 作为属性,来自密码的查询不再起作用(不返回结果)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多