通过JAVA API的Neo4j Spatial over REST(对我而言)

时间:2014-10-28 07:01:14

标签: neo4j geotools neo4j-spatial

我正在使用Grails应用程序而不是Neo4J,我也希望将其导出为GIS数据库。

查看如何在GeoServer / uDig中使用neo4j的示例,似乎Spatial集成仅通过嵌入式neo4j数据库。

有没有人知道是否有可能进行设置以便我的Neo4J可通过REST使用,以便我可以从各种地方与它进行交互?

乍一看似乎应该是可能的:

// Works with this embedded database
//def graphDb = new GraphDatabaseFactory().newEmbeddedDatabase("/tmp/foo.db");

// Doesn't work with this REST database
graphDb = new RestGraphDatabase("http://localhost:7474/db/data");

Transaction tx = graphDb.beginTx()

SpatialDatabaseService spatialService = new SpatialDatabaseService(graphDb)
SimplePointLayer layer = spatialService.createSimplePointLayer("points")

使用嵌入式数据库,可以很好地创建空间索引。 但是,使用REST数据库,我只得到一个空指针:

Caused by NullPointerException: null
->>  149 | createCompiler in org.neo4j.cypher.ExecutionEngine
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|     48 | <init>    in     ''
|     59 | createInnerEngine in org.neo4j.cypher.javacompat.ExecutionEngine
|     43 | <init>    in     ''
|     41 | getReferenceNode in org.neo4j.gis.spatial.utilities.ReferenceNodes
|     78 | getSpatialRoot in org.neo4j.gis.spatial.SpatialDatabaseService
|    114 | getLayer  in     ''
|    259 | containsLayer in     ''
|    303 | createLayer in     ''
|    287 | createSimplePointLayer in     ''
|    267 | createSimplePointLayer in     ''
|     37 | <init>    in net.foo.db.neo4j.Neo4JService

SpatialDatabaseService采用GraphDatabaseService,所以我很困惑为什么它不适用于REST。

这是一个错误还是一个功能(或者我的误解?)

我当然可以使用create index API创建空间索引:

graphDb.index().forNodes( "points", ["provider": "spatial", "geometry_type": "point", "lat": "lat", "lon":"lon"])

这样可行,但我无法以这种方式创建新图层。

2 个答案:

答案 0 :(得分:1)

RestGraphDatabase是一个假数据库,不提供所有功能。 它可以在理论上工作,但是非常浪费,因为每个可能的嵌入式操作都会像http请求一样通过网络传输。

将Spatial as Plugin安装到您的服务器,然后通过插件REST方法访问它。

请参阅:http://neo4j-contrib.github.io/spatial/#spatial-server-plugin

答案 1 :(得分:0)

虽然我真的不明白你在使用这个Grail应用程序做了什么,但是从你的例外看来,看起来你正试图做这样的事情:

ExecutionEngine executionEngine = new ExecutionEngine(graphDatabaseService);
  

其中ExecutionEngine来自cypher.javacompat和   GraphDatabaseService指向RestGraphDatabase。

ExecutionEngine构建于我们的内部内核API之上,它只能从嵌入式数据库中获取。

要在RestGraphDatabase上运行Cypher查询,您需要从getRestAPI获取其RestAPI,并对其使用查询方法。

此Google论坛上的帖子解释了这一点: https://groups.google.com/forum/#!topic/neo4j/Q6lsOakSgyA

下面是我制作的示例程序,它使用RestGraphDatabase创建和执行查询。希望这会有所帮助。

package rash.experiments.neo4j;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.Transaction;
import org.neo4j.rest.graphdb.RestGraphDatabase;
import org.neo4j.rest.graphdb.query.RestCypherQueryEngine;
import org.neo4j.rest.graphdb.util.QueryResult;

public class Neo4JRestTest
{
    private static enum RelType implements RelationshipType
    {
        KNOWS
    }

    public static void main(String args[])
    {
        RestGraphDatabase graphDatabaseService = new RestGraphDatabase("http://10.20.230.12:7474/db/data/");
        RestCypherQueryEngine executionEngine = new RestCypherQueryEngine(graphDatabaseService.getRestAPI());

        try(Transaction transaction = graphDatabaseService.beginTx())
        {
            Node rash = graphDatabaseService.createNode();
            rash.setProperty("userId", 4);
            rash.setProperty("username", "rash");
            rash.setProperty("name", "Rahul Chaudhary");

            Node honey = graphDatabaseService.createNode();
            honey.setProperty("userId", 5);
            honey.setProperty("username", "honey");
            honey.setProperty("name", "Honey Anant");

            Relationship knowsRelationship = rash.createRelationshipTo(honey, RelType.KNOWS);
            knowsRelationship.setProperty("since", 2011);

            transaction.success();
        }

        try(Transaction transaction = graphDatabaseService.beginTx())
        {
            QueryResult<Map<String,Object>> executionResult = executionEngine.query("match (node) return node", null);
            Iterator<Map<String, Object>> resourceIterator = executionResult.iterator();

            while(resourceIterator.hasNext())
            {
                Set<Entry<String, Object>> map = resourceIterator.next().entrySet();
                for(Entry<String, Object> entry : map)
                {
                    Node node = (Node) entry.getValue();
                    System.out.println("UserId: " + node.getProperty("userId"));
                    System.out.println("Username: " + node.getProperty("username"));
                    System.out.println();
                }

                System.out.println("--------------------------\n");
            }

            transaction.success();
        }
    }
}