gpt4 book ai didi

java - 在 Neo4J 图上进行多次更新的正确方法是什么?

转载 作者:太空宇宙 更新时间:2023-11-04 13:21:47 26 4
gpt4 key购买 nike

我正在尝试 Neo4J。我试图了解在图数据库上同时进行多个更改的正确方法是什么。

在开始之前,让我澄清一下,由于几个原因,我必须在 Java/Scala 应用程序中使用 Neo4J 作为嵌入式数据库,而不是作为可以向其发出 REST 调用的远程服务器。此外,我必须使用 Cypher 来构造命令并使用 Neo4J 的 Java API 执行:exectureQuery

所以,这里有一段代码来举例说明我想要做的事情:

val db = new TestGraphDatabaseFactory().newImpermanentDatabase()
val query1 =
"""
|Create (d: Dish {name:"Fish Curry",from:"India"}),
|(t: Table {no: 1}),
|(d)-[r:ORDERED_FROM]->(t)
""".stripMargin
val query2 =
"""
|Match (d:Dish {name: "Fish Curry"}),
|(t: Table {no: 1}),
|(d)-[r:ORDERED_FROM]->(t)
|Delete r
""".stripMargin

val query3 =
"""
|Match (d:Dish {name: "Fish Curry"}), (t: Table {no: 1})
|Create (d)-[r:SERVED_AT]->(t)
""".stripMargin

假设我正在一家餐厅模拟一个典型的夜晚。我从菜单中选择一道特定的菜肴并下订单。此时,query1 被触发。节点和关系已创建。

val v1 = db.execute(query1).resultAsString()
// ... I consume 'v1' appropriately

过了一段时间,菜就做好了,上 table 了。现在,为了让图表反射(reflect)所发生的情况,将触发以下命令:

val v2 = db.execute(query2).resultAsString
val v3 = db.execute(query3).resultAsString

为了详细说明(无论如何,这对于这里的所有 Neo4J 专家来说可能都是显而易见的),我将切断菜肴和 table 之间的 ORDERED_FROM 关系,并通过 SERVED_AT 关系将它们联系起来。

我有两个问题:

  1. 因为我通过两个单独的 Cypher 查询进行了 2 次更新,所以我可能缺少事务保证。在删除旧关系和添加新关系之间,dish很容易受到另一个正交更新(可能是通过另一个执行线程)的影响。如果这个理解是正确的,那么我必须做什么来防止它发生?

  2. 在上面的示例中,Dish 节点的属性是硬编码的。但是,实际上,这些将是变量,它们的值在运行时分配。因此,执行查询{2,3}时可能找不到DishTable。处理这个问题的正确方法是什么?如果我正确理解 API,可能不会抛出任何异常。

我搜索了各种博客和其他网站来寻找答案,但没有找到。因此,如果我正在寻找的答案已经存在于某个地方,请向我指出。

如有任何帮助,我们将不胜感激。

最佳答案

您必须在查询执行之外启动事务。否则,Cypher 将仅为一个查询启动隐式 tx。

try (Transaction tx= db.beginTx()) {
db.execute(query1,params).close();
db.execute(query1,params).close();
tx.success();
}

注意,这使用了 try-with-resource,否则你必须手动调用 tx.close()

关于java - 在 Neo4J 图上进行多次更新的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32995849/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com