在Neo4J中,如何在Java的cypher查询中将标签设置为参数?

时间:2014-06-17 22:31:04

标签: java neo4j cypher

我在Java中使用Neo4J中的cypher参数时遇到问题。我运行嵌入式数据库。

代码应该是这样的(GraphDB.cypher直接转到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);

但它以此异常结束

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"

文档(和教程)告诉使用{}来覆盖参数,但这也用作属性的cypher json表示法。 @See http://docs.neo4j.org/chunked/milestone/tutorials-cypher-parameters-java.html

是否有其他方法可以解决此问题,而不是像这样构建查询字符串(或使用其他模板方法)

GraphDB.cypher("MATCH (n:" + labelName + ")-[r:" + relationName + "]->...

这是必需的,因为目标标签可以更改,我想完全重用代码。

提前致谢。

[[取得(叹气)没有作为答复后的行为]]

由于不支持这种形式的参数(2014.6),我会在发送查询之前运行一点替换。

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);
}

可以有更多的可读

2 个答案:

答案 0 :(得分:8)

我担心目前不支持此事。

这可能与本期中解释的原因完全相同:https://github.com/neo4j/neo4j/pull/1542

参数化查询背后的想法是重用(缓存)执行计划。如果节点标签或关系类型不同,则执行计划根本不会相同,从而破坏了执行计划缓存的有用性。

答案 1 :(得分:1)

不要将标签视为信息文档的最重要属性,而应将它们视为在“地图”中填充哪些属性键的架构。 (neo4j引用属性对象的可怕名称)

对于NER,根据定义,共享相同合并查询的实体共享在运行时设置的相同参数;因此,他们应该共享标签,这会使标签硬编码而不是参数化。

您仍然可以按属性查询。不会影响节点之间关系类型或属性键本身的值不应为标签。

您还可以将标签添加到现有节点,理想情况下是将新属性添加到现有节点,这是节点定义的扩展。如果要在节点之间创建关系,那么根据节点属性的分析,这是添加标签的理想时间,只要关系类型对于每个节点的标签而言都是唯一的即可。