首页 文章

Neo4J,SDN和运行Cypher空间查询

提问于
浏览
3

我是Neo4J的新手,我正在尝试为基于高可用性空间时间的查询构建概念验证 .

我有一个设置有2个独立的Neo4J Enterprise服务器和一个运行有嵌入式HA Neo4J服务器的Java应用程序 .

一切都很简单,基本查询易于设置和高效 . 此外,按预期执行从Neo4J SpatialRepository派生的查询 .

我正在努力理解的是如何使用SDN结合任何其他where子句进行空间查询 . 作为一个简单的例子我怎么能写出找到所有地方用户称为X已经在纬度/经度的Y英里内 . 因为SpatialRepository不是常规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;

错误是:

Index `location` does not exist
  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子句以执行基于空间和属性的查询的组合一样简单吗?

Added more index detail
从控制台运行 :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" ...
     ...
     ...

Update
在确定我的索引不存在之后,我应该使用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的企业-2.0.1
Neo4j的空间,0.12的Neo4j-2.0.1-服务器插件

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);
    

相关问题