Neo4j Cypher结果为JSON:在使用JsonHelper.createJsonFrom()时获得JsonMappingException,但仅用于某些查询

时间:2022-03-22 15:15:32

I'm working on neo4vertx, a module that makes it possible to talk to a Neo4j database using Vert.x. Specifically, I'm working on feature called "query" which allows a Vert.x user to send a Cypher query as an eventbus message and get a JSON resultset back.

我正在研究neo4vertx,这个模块可以使用Vert.x与Neo4j数据库对话。具体地说,我正在开发一个名为“查询”的特性,它允许一个Vert。x用户将一个Cypher查询作为eventbus消息发送,并获得一个JSON resultset。

However, I seem to run into an unexpected problem when serializing to JSON using JsonHelper.createJsonFrom() with certain queries.

但是,在使用JsonHelper.createJsonFrom()序列化JSON时,我似乎遇到了一个意外的问题。

A quick example (database has stuff in it of course):

一个简单的例子(当然数据库中有一些东西):

// This Fails with JsonMappingException (see below):
String query="MATCH (n) RETURN n";

// This Succeeds:
String query="MATCH (n) RETURN n.something";

//Rest of code:
engine = new ExecutionEngine(graphDatabaseService);
ExecutionResult result;
result = engine.execute(query);

Object object = result.iterator();
String foo = JsonHelper.createJsonFrom(object);
System.out.println("DEBUG (foo): " + foo);

Does this look familiar to anyone? We essentially want to be able to send any kind of query and either return an empty json string or a json representation not unlike the result.json that you can retrieve from the web interface of neo4j!

这对任何人来说都很熟悉吗?我们实际上希望能够发送任何类型的查询,并返回一个空json字符串或一个与结果相似的json表示。可以从neo4j的web接口检索的json !

The Exception:

testQuery(org.openpcf.neo4vertx.neo4j.Neo4jGraphTest)  Time elapsed: 2.362 sec  <<< ERROR!
org.neo4j.server.rest.domain.JsonBuildRuntimeException: org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.neo4j.kernel.InternalAbstractGraphDatabase$DependencyResolverImpl and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: scala.collection.convert.MapWrapper["content"]->org.neo4j.kernel.impl.core.NodeProxy["graphDatabase"]->org.neo4j.test.["dependencyResolver"])

...

3 个解决方案

#1


0  

Although the ExecutionResult is an implementation of Iterator<Map<String,Object>> it is currently just a java wrapper around scala classes, as well as Neo4j classes (like Node, Relationship, Path).

虽然ExecutionResult是迭代器 >目前只是一个scala类的java包装器,以及Neo4j类(如节点、关系、路径)。

So you have probably to do 2 things:

所以你可能需要做两件事:

  1. recursively replace neo4j classes with appropriate maps and lists
  2. 递归地用适当的映射和列表替换neo4j类
  3. probably: recursively replace scala lists and maps with java lists and maps, e.g. new LinkedHashMap(row)
  4. 可能:用java列表和映射递归地替换scala列表和映射,例如新的LinkedHashMap(row)

I did some of that some time ago here in my cypher-websocket-experiments

不久前我在我的cypher-websocket实验中做了一些实验

#2


0  

You can serialize the ExecutionResult of Neo4J to JSON this way:

您可以这样将Neo4J的ExecutionResult序列化为JSON:

ExecutionResult result ...
CypherResultRepresentation repr = new CypherResultRepresentation(result, false, false);
OutputFormat format = new OutputFormat(new JsonFormat(), null, null);
String json = format.assemble(repr);

The next thing you have to do is to create the appropriate vert.x JsonObject objects.

接下来要做的就是创建合适的渐变。x JsonObject对象。

@Rubin: I'm currently adding this to neo4vertx ;)

@Rubin:我现在把这个加入到neo4vertx中;)

#3


0  

By using RESTAPI:

通过使用RESTAPI:

String query = "MATCH (a)-[r]-(b) RETURN a,r,b";
RestAPI restAPI = new RestAPIFacade(URI);
CypherResult result = restAPI.query(query, Collections.<String, Object>emptyMap());
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
String stringResult = gson.toJson(result.asMap());
JSONObject jsonResult = new JSONObject(stringResult);

By using Bolt

通过使用螺栓

    String query = "MATCH (a)-[r]-(b) RETURN a,r,b";
String stringConnection = "bolt://" + HOST + ":7687";
Driver driver = GraphDatabase.driver(stringConnection, AuthTokens.basic(USER, PASS));
Session session = driver.session();
StatementResult result = session.run(query);
session.close();
driver.close();
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
while (result.hasNext()) {
    Record record = result.next();
    stringResult = gson.toJson(record.asMap());
}
JSONObject jsonResult = new JSONObject(stringResult);

#1


0  

Although the ExecutionResult is an implementation of Iterator<Map<String,Object>> it is currently just a java wrapper around scala classes, as well as Neo4j classes (like Node, Relationship, Path).

虽然ExecutionResult是迭代器 >目前只是一个scala类的java包装器,以及Neo4j类(如节点、关系、路径)。

So you have probably to do 2 things:

所以你可能需要做两件事:

  1. recursively replace neo4j classes with appropriate maps and lists
  2. 递归地用适当的映射和列表替换neo4j类
  3. probably: recursively replace scala lists and maps with java lists and maps, e.g. new LinkedHashMap(row)
  4. 可能:用java列表和映射递归地替换scala列表和映射,例如新的LinkedHashMap(row)

I did some of that some time ago here in my cypher-websocket-experiments

不久前我在我的cypher-websocket实验中做了一些实验

#2


0  

You can serialize the ExecutionResult of Neo4J to JSON this way:

您可以这样将Neo4J的ExecutionResult序列化为JSON:

ExecutionResult result ...
CypherResultRepresentation repr = new CypherResultRepresentation(result, false, false);
OutputFormat format = new OutputFormat(new JsonFormat(), null, null);
String json = format.assemble(repr);

The next thing you have to do is to create the appropriate vert.x JsonObject objects.

接下来要做的就是创建合适的渐变。x JsonObject对象。

@Rubin: I'm currently adding this to neo4vertx ;)

@Rubin:我现在把这个加入到neo4vertx中;)

#3


0  

By using RESTAPI:

通过使用RESTAPI:

String query = "MATCH (a)-[r]-(b) RETURN a,r,b";
RestAPI restAPI = new RestAPIFacade(URI);
CypherResult result = restAPI.query(query, Collections.<String, Object>emptyMap());
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
String stringResult = gson.toJson(result.asMap());
JSONObject jsonResult = new JSONObject(stringResult);

By using Bolt

通过使用螺栓

    String query = "MATCH (a)-[r]-(b) RETURN a,r,b";
String stringConnection = "bolt://" + HOST + ":7687";
Driver driver = GraphDatabase.driver(stringConnection, AuthTokens.basic(USER, PASS));
Session session = driver.session();
StatementResult result = session.run(query);
session.close();
driver.close();
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
while (result.hasNext()) {
    Record record = result.next();
    stringResult = gson.toJson(record.asMap());
}
JSONObject jsonResult = new JSONObject(stringResult);