2

我正在通过 Neo4J 开发 Grails 应用程序,我还想将其导出为 GIS 数据库。

查看如何在 GeoServer/uDig 中使用 neo4j 的示例,似乎空间集成仅通过嵌入式 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 indexAPI 创建空间索引:

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

这样就可以了,但是我不能那样创建新图层。

4

2 回答 2

1

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

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

见: http: //neo4j-contrib.github.io/spatial/#spatial-server-plugin

于 2014-10-30T02:54:39.823 回答
0

虽然我真的不明白你在用这个 Grail 应用程序做什么,但从你的异常的外观来看,看起来你正在尝试做这样的事情:

ExecutionEngine executionEngine = new ExecutionEngine(graphDatabaseService);

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

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

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

这个谷歌组的帖子解释了这一点: 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();
        }
    }
}
于 2015-02-25T22:09:29.563 回答