I have problems with parameter in cypher in Neo4J from Java. I run the the database embedded.
The code should be like this (GraphDB.cypher goes directly to the ExecutionEngine)
HashMap<String, Object> parameter = new HashMap<>();
parameter.put("theLabel1", "Group");
parameter.put("theRelation", "isMemberOf");
parameter.put("theLabel2", "Person");
GraphDB.cypher("MATCH (n1:{theLabel1})-[r:{theRelation}]->(n2:{theLabel2}) RETURN n1, r, n2", parameter);
but it ends in this exception
Exception in thread "main" Invalid input '{': expected whitespace or a label name (line 1, column 11)
"MATCH (n1:{theLabel1})-[r:{theRelation}]->(n2:{theLabel2}) RETURN n1, r, n2"
The documentation (and tutorial) tells to use the { } to cover the parameters, BUT this is also used as the cypher json notation for properties. @See http://docs.neo4j.org/chunked/milestone/tutorials-cypher-parameters-java.html
Is there another way to solve this issue rather than building the query string like this (or with other template methods)
GraphDB.cypher("MATCH (n:" + labelName + ")-[r:" + relationName + "]->...
This is needed because the target label can change and I want to reuse the code completly.
Thanks in advance.
[[EDITED AFTER GETTING A (sigh) NO AS ANSWER]]
Since this form of parameter is currently (2014.6) not supported, I will run a little replacer right before sending the query.
HashMap<String, Object> parameter = new HashMap<>();
parameter.put("theLabel1", "Group");
parameter.put("theRelation", "isMemberOf");
parameter.put("theLabel2", "Person");
parameter.put("aName", "Donald Duck");
GraphDB.cypher("MATCH (n1:#theLabel1#)-[r:#theRelation#]->(n2:#theLabel2#) WHERE n2.Name = {aName} RETURN n1, r, n2", parameter);
... with ...
public static ExecutionResult cypher(String query, Map<String, Object> params) {
for (String key : params.keySet()) {
query = query.replaceAll("#" + key + "#", String.valueOf(params.get(key)));
}
return params == null ? cypherEngine.execute(query) : cypherEngine.execute(query, params);
}
There can be a more readble
label
withparameter
"dynamically". But when considered as simply a place holder to be replaced by the match inparameter
, it does achieve passinglabel
dynamically. Not sure if there is any standard solution coming, but it is quite an interesting mitigation. – Causality