我知道这可能是被问了一百次而且相信我,我已经在网上读过太多了。但是,我绝对不会这样做,所以我在这里急需帮助。
我想要做的是使用cypher和事务端点在neo4j db中创建一个带有标签和属性的节点 - 使用来自json的属性。
到目前为止,这是我的代码:
/**
*
* @description creates a node in the graph
* @param json object
* @param label
*
*/
private String createNodeObjectTransactional(JSONObject nodeObject, GraphNodeTypes label){
String nodeLocation=null;
try{
dbServerUrl = "http://localhost:7474"
transactionUrl = dbServerUrl + "/db/data" + "/transaction";
String finalUrl = transactionUrl;
String payload = "{\"statements\": [ {\"statement\": \"CREATE\" (p:"+ label.toString() +" "+ nodeObject.toString() + ") } ] }";
logger.trace("sending cypher {} to endpoint {}", payload, finalUrl);
WebResource resource = Client.create().resource( finalUrl );
ClientResponse response = resource
.accept( MediaType.APPLICATION_JSON )
.type( MediaType.APPLICATION_JSON )
.entity( payload )
.post( ClientResponse.class );
nodeLocation = response.getLocation().toString();
String responseString = response.getEntity(String.class);
logger.debug("POST to {} returned status code {}, returned data: {}",
finalUrl, response.getStatus(),
responseString);
// first check if the http code was ok
HttpStatusCodes httpStatusCodes = HttpStatusCodes.getHttpStatusCode(response.getStatus());
if (!httpStatusCodes.isOk()){
if (httpStatusCodes == HttpStatusCodes.FORBIDDEN){
logger.error(HttpErrorMessages.getHttpErrorText(httpStatusCodes.getErrorCode()));
} else {
logger.error("Error {} sending data to {}: {} ", response.getStatus(), finalUrl, HttpErrorMessages.getHttpErrorText(httpStatusCodes.getErrorCode()));
}
} else {
// now do the check on json details within the returned JSON object
JSONParser reponseParser = new JSONParser();
Object responseObj = reponseParser.parse(responseString);
JSONObject jsonResponseObj = responseObj instanceof JSONObject ?(JSONObject) responseObj : null;
if(jsonResponseObj == null)
throw new ParseException(0, "returned json object is null");
// this is the location to commit the transaction if node creation was successfull
String commit = (String) jsonResponseObj.get("commit").toString();
// this contains an error object (actually an array) in case the creation was NOT successfull
String error = (String) jsonResponseObj.get("errors").toString();
// doknow what that is
String result = (String) jsonResponseObj.get("results").toString();
final URI location = response.getLocation();
if (error.isEmpty()) {
logger.info("new node created at location {}", location);
logger.trace("returned result json is {}", result.toString());
logger.debug("committing transaction at location {}", commit);
resource = Client.create().resource( commit );
response = resource
.accept( MediaType.APPLICATION_JSON )
.type( MediaType.APPLICATION_JSON )
.post( ClientResponse.class );
logger.debug("COMMIT returned status code {}, returned data: {}",
response.getStatus(),
response.getEntity(String.class));
} else {
logger.error("ERROR :: {} - could not create node at location {}", error.substring(13), location);
logger.trace("returned error json is {}", error.toString());
}
}
response.close();
} catch(Exception e) {
logger.error("EXCEPTION :: failed to create node - {}", e.getMessage());
e.printStackTrace();
}
return nodeLocation;
}
这是服务器的回复:
ERROR :: Unable to deserialize request: Unexpected character ('(' (code 40)): was expecting comma to separate OBJECT entries\n at [Source: org.eclipse.jetty.server.HttpConnection$Input@44382113{HttpChannelOverHttp@41038962{r=6,a=DISPATCHED,uri=\/db\/data\/transaction},HttpConnection@4f30a246{FILLING},g=HttpGenerator{s=START},p=HttpParser{s=END,275 of 275}}; line: 1, column: 42]","code":"Neo.ClientError.Request.InvalidFormat"}] - could not create node at location http://localhost:7474/db/data/transaction/121
真正困扰我的是,在neo4j网站上给出的示例中,他们确实放入(用于封装标签和json对象的字符,但服务器不喜欢该字符。如答案中所述:
Unexpected character ('(' (code 40)): was expecting comma to separate OBJECT
我不知道,服务器在这个位置添加逗号意味着什么。它不在物体的儿子之内,而是先于物体。
这是tracelog:
INFO Neo4JPersistence - creating a Twitter node object to store in the graph
DEBUG Neo4JPersistence - creating node transactional
TRACE Neo4JPersistence - sending cypher payload {"statements": [ {"statement": "CREATE" (p:POST {"id":"534621287264817153","subject":"daily....","teaser":"daily...","lang":"de","sn_id":"TW"}) } ] } to endpoint http://localhost:7474/db/data/transaction
DEBUG Neo4JPersistence - POST to http://localhost:7474/db/data/transaction returned status code 201, returned data: {"commit":"http://localhost:7474/db/data/transaction/121/commit","results":[],"transaction":{"expires":"Tue, 18 Nov 2014 08:19:55 +0000"},"errors":[{"code":"Neo.ClientError.Request.InvalidFormat","message":"Unable to deserialize request: Unexpected character ('(' (code 40)): was expecting comma to separate OBJECT entries\n at [Source: org.eclipse.jetty.server.HttpConnection$Input@44382113{HttpChannelOverHttp@41038962{r=6,a=DISPATCHED,uri=/db/data/transaction},HttpConnection@4f30a246{FILLING},g=HttpGenerator{s=START},p=HttpParser{s=END,275 of 275}}; line: 1, column: 42]"}]}
ERROR Neo4JPersistence - ERROR :: Unable to deserialize request: Unexpected character ('(' (code 40)): was expecting comma to separate OBJECT entries\n at [Source: org.eclipse.jetty.server.HttpConnection$Input@44382113{HttpChannelOverHttp@41038962{r=6,a=DISPATCHED,uri=\/db\/data\/transaction},HttpConnection@4f30a246{FILLING},g=HttpGenerator{s=START},p=HttpParser{s=END,275 of 275}}; line: 1, column: 42]","code":"Neo.ClientError.Request.InvalidFormat"}] - could not create node at location http://localhost:7474/db/data/transaction/121
TRACE Neo4JPersistence - returned error json is [{"message":"Unable to deserialize request: Unexpected character ('(' (code 40)): was expecting comma to separate OBJECT entries\n at [Source: org.eclipse.jetty.server.HttpConnection$Input@44382113{HttpChannelOverHttp@41038962{r=6,a=DISPATCHED,uri=\/db\/data\/transaction},HttpConnection@4f30a246{FILLING},g=HttpGenerator{s=START},p=HttpParser{s=END,275 of 275}}; line: 1, column: 42]","code":"Neo.ClientError.Request.InvalidFormat"}]
请拜托,
任何人都可以帮助我吗?
提前致谢,
克里斯
答案 0 :(得分:2)
正如错误告诉你的那样,你正在传递格式错误的json
... "CREATE" (p:POST ...
Json应如此处所述
{
"statements" : [ {
"statement" : "CREATE (n {props}) RETURN n",
"parameters" : {
"props" : {
"name" : "My Node"
}
}
} ]
}
(详见docs)
在你的情况下:
String payload = "{\"statements\":
[ {\"statement\": \"CREATE (p:"+ label.toString() +" " {props}) \",
\"parameters\":" + nodeObject.toString() + " } ] }";