Neo4J,SDN和运行Cypher空间查询

3
我是Neo4J的新手,正在尝试构建一个基于高可用性时空查询的概念验证。我有两个独立的Neo4J企业服务器和一个带有嵌入式HA Neo4J服务器的Java应用程序的设置。一切都很简单,基本查询易于设置且有效。此外,执行从Neo4J SpatialRepository派生的查询效果符合预期。我正在努力理解如何使用SDN结合其他where子句进行空间查询。例如,如何编写查找用户X在离纬度/经度Y英里范围内的所有地点的代码。因为空间库不是常规Spring Repository类树的一部分,所以我认为没有任何命名约定可以使用,这意味着我需要执行空间查询,然后筛选结果吗?
我已经追踪代码到LegacyIndexSearcher(这个名称让我感到害怕!),并且没有看到任何扩展搜索的机制。 我还查看了GitHub上的 IndexProviderTest,它可以提供手动机制来执行对索引的查询,但我认为可能有两个索引在使用中。
如果我了解如何构建可以在@Query注释中使用的Cypher查询将会很有帮助。虽然我能够使用控制台执行简单的REST查询:
:POST /db/data/ext/SpatialPlugin/graphdb/findGeometriesWithinDistance { "layer":"location", "pointX":0.0, "pointY":51.526256, "distanceInKm":100 }
但是这个不管用:
start n=node:location('withinDistance:[51.526256,0.0,100.0]') return n;
错误信息为:
索引“location”不存在 Neo.ClientError.Schema.NoSuchIndex

这个索引(可能有点天真)是使用Spring创建的:

  @Indexed(indexType = IndexType.POINT, indexName = "location")
  String wkt;

如果我在控制台中运行index --indexes,我会发现没有名为“location”的索引,但有一个名为location__neo4j-spatial__LayerNodeIndex__internal__spatialNodeLookup__的索引。

我需要手动创建索引吗?如果是这样,请问有哪些文档可以参考?

假设只是由于无知而导致简单的Cypher查询无法运行,那么是否只需将常规的Cypher WHERE子句添加到查询中即可执行空间和基于属性的查询组合?

添加更多索引细节
在控制台中运行:GET /db/data/index/node/之后,我可以看到两个可能有用的索引(已删除其他索引):

{
  "location__neo4j-spatial__LayerNodeIndex__internal__spatialNodeLookup__": {
    "template": "/db/data/index/node/location__neo4j-spatial__LayerNodeIndex__internal__spatialNodeLookup__/{key}/{value}",
    "provider": "lucene",
    "type": "exact"
  },
  "GeoTemporalThing": {
    "template": "/db/data/index/node/GeoTemporalThing/{key}/{value}",
    "provider": "lucene",
    "type": "exact"
  }
}

因此,也许这应该是我尝试的正确查询格式:

start n=node:GeoTemporalThing('withinDistance:[51.526256,0.0,100.0]') return n;

但是它给了我这个错误(现在我正在谷歌搜索)

org.apache.lucene.queryParser.ParseException: Cannot parse 'withinDistance:[51.526256,0.0,100.0]': Encountered " "]" "] "" at line 1, column 35.
Was expecting one of:
    "TO" ...
     ...
     ...
更新
我决定创建一个索引,因为我的索引不存在。我使用REST接口创建了一个名为SDN的索引,如下所示:
:POST /db/data/index/node
{
  "name" : "location",
  "config" : {
    "provider" : "spatial",
    "geometry_type" : "point",
    "wkt" : "wkt"
  }
}
现在一切似乎都很正常。所以,我的问题是,我是否需要手动创建该索引?如果我查看org.springframework.data.neo4j.support.index.IndexType中的代码,它看起来应该使用我上面使用的完全相同的设置,但它只创建了长命名的Lucene索引:
public enum IndexType
{   
    @Deprecated
    SIMPLE   { public Map getConfig() { return LuceneIndexImplementation.EXACT_CONFIG; } },
    LABEL    { public Map getConfig() { return null; }  public boolean isLabelBased() { return true; }},
    FULLTEXT { public Map getConfig() { return LuceneIndexImplementation.FULLTEXT_CONFIG; } },
    POINT    { public Map getConfig() { return MapUtil.stringMap(
                      IndexManager.PROVIDER, "spatial", "geometry_type" , "point","wkt","wkt") ; } }
;
public abstract MapgetConfig();
public boolean isLabelBased() { return false; } }

我已经清除了系统,但行为仍然相同,我是否漏掉了一步?

软件详情:

Java:
neo4j 2.0.1
neo4j-ha 2.0.1
neo4j-spatial 0.12-neo4j-2.0.1
spring-data-neo4j 3.0.0.RELEASE

独立服务器:
neo4j-enterprise-2.0.1
neo4j-spatial-0.12-neo4j-2.0.1-server-plugin

1个回答

1
我不确定这是否是Spring Data在设置索引时的一个错误,但是使用REST索引手动创建索引可以解决问题:
:POST /db/data/index/node
{
  "name" : "location",
  "config" : {
    "provider" : "spatial",
    "geometry_type" : "point",
    "wkt" : "wkt"
  }
}
现在,我可以使用@Query注释中的Cypher轻松执行查询(显然有更多参数):
@Query(value = "start n=node:location('withinDistance:[51.526256,0.0,100.0]') MATCH user-[wa:WAS_HERE]-n WHERE wa.ts > {ts} return user"
Page findByTimeAtLocation(@Param("ts") long ts);

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