是否可以从 java 执行只读密码查询?

Is it possible to execute read only cypher queries from java?

我想知道标题说的是什么。

我想要这样做的原因是允许执行受约束的 read-only 密码查询;数据结果稍后将由单独的 API 层解释和序列化。

我见过做出基本假设以试图模仿这种行为的代码,例如该代码可能会过滤掉任何包含与写入查询结构相关的某些特殊单词的 Cypher 查询(mergecreatedeleteset 等)。

虽然这种方法往往是有限的和幼稚的;如果它非常简单地查找这些标记,它会阻止像 MATCH n WHERE n.label =~ '.*create.*' RETURN n 这样的查询,即使它是 read-only 查询。

我真的不想对候选查询进行完整解析,然后通过 AST 下降试图弄清楚某些东西是否是 read-only(尽管我很乐意接受一个显示的答案如何在 java)

中轻松做到这一点

EDIT - 我知道可以通过配置 属性 read_only=true 以 read-only 模式启动整个数据库,但是这是不可取的; java API 的任何其他方面都无法更改数据库。

EDIT 2 - 我找到了另一种可能的策略,但我不确定它是否可取。欢迎对此发表评论,以及潜在的缺点:

try (Transaction ignore = graphDb.beginTx()) {
    ExecutionResult result = executionEngine.execute(query);
    // Do nifty stuff with result, then...

    // Force transaction to fail.
    ignore.failure();
}

这里的想法是,如果查询发生在事务中并且事务始终是 force-failed,那么无论结果如何,都不能将任何内容写入数据库。

直接支持(尚未)只读 Cypher。但是我可以想到两个解决方法:

1) 假设您是 运行 Neo4j 企业集群:您可以在一个实例上设置 read_only=true。然后该实例用于只读查询,而其他集群实例用于 r/w。可以在集群前面设置一个负载均衡器来将请求发送到正确的实例。

2) 如果 TransactionData 包含写入操作,则使用 TransactionEventHandler 否决事务。只是为了好玩,我花了几分钟时间来实现它,请参阅 https://github.com/sarmbruster/read-only-cypher - 感谢反馈。