我无法在ArangoDB的FOR循环中多次更新同一文档

时间:2019-06-29 21:57:59

标签: arangodb

我有一个集合或用户,我需要循环更新两次属性“ cuantity”。例如,在更新数组中,我需要将其增加1,然后将其增加2,因此,如果实际值为1,则结果值必须为4,但这种方式不会发生。 ArangoDB接缝将采取update数组循环中的最后一个更新对象,并取消循环中先前的更新对象。

这是我的收藏(用于简化测试):

{"_key": "1", "name":"ivan", "cuantity":1}
{"_key": "2", "name":"juan", "cuantity":1}
{"_key": "3", "name":"carl", "cuantity":1}

这是我的查询和更新数组

let updateData = [
  { user_key: "1", cuantity: 1},
  { user_key: "1", cuantity: 2},
  { user_key: "2", cuantity: 1},
  { user_key: "2", cuantity: 3}
  ]

FOR e IN updateData
  LET doc = DOCUMENT(CONCAT("test1/",e.user_key))
  UPDATE doc WITH { cuantity: doc.cuantity + e.cuantity }
  IN test1
  LET updated = NEW
RETURN updated

这是结果

[
  {
    "_key": "1", "_id": "test1/1",
    "name": "ivan",
    "cuantity": 2
  },
  {
    "_key": "1", "_id": "test1/1",
    "name": "ivan",
    "cuantity": 3
  },
  {
    "_key": "2", "_id": "test1/2",
    "name": "sergio",
    "cuantity": 2
  },
  {
    "_key": "2", "_id": "test1/2",
    "name": "sergio",
    "cuantity": 4
  }
]

该操作的结果必须是具有“ _key”:“ 1”的用户具有“ cuantity”:4,因为在第一次迭代中它增加了1,在第二次迭代中增加了2。问题似乎是ArangoDB无法在同一循环中基于先前的更新来更新文档。 ¿是否有实现此目的的配置? 我正在使用RocksDB引擎。

1 个答案:

答案 0 :(得分:0)

Arango 3.4似乎总是在循环执行更新时更新原始值。我只是直接在webGUI上在我的机器上运行了此

let myData = [
{ user_key: "1", cuantity: 1},
{ user_key: "1", cuantity: 2},
{ user_key: "2", cuantity: 1},
{ user_key: "2", cuantity: 3},
{ user_key: "3", cuantity: 2}
]

For entry in myData
  LET doc = DOCUMENT(CONCAT("test4/",entry.user_key))
  UPDATE doc WITH { cuantity: doc.cuantity + entry.cuantity }
  IN test4
  LET updated = NEW
RETURN updated

假设user_key的更新次数在更新之前为1,我最终得到的错误值为3而不是更新结束时的4。

话虽如此,我认为您可能希望在进行更新之前汇总数据。例如,如果在批处理中将user_key = 1的值更新了100次,则您可能不想运行更新100次,因为这可能会导致性能问题。如果进行预汇总,则只需在末尾更新一次记录即可。因此,例如,您可以执行以下操作:

let myData = [
{ user_key: "1", cuantity: 1},
{ user_key: "1", cuantity: 2},
{ user_key: "2", cuantity: 1},
{ user_key: "2", cuantity: 3},
{ user_key: "3", cuantity: 2}
]


 LET aggData = ( FOR entry IN myData
  COLLECT theKey = entry.user_key 
  AGGREGATE addedCuantity = sum(entry.cuantity)
  RETURN {theKey, addedCuantity}
  )

  FOR aggEntry IN aggData
  LET doc = DOCUMENT(CONCAT("test4/",aggEntry.theKey))
  UPDATE doc WITH { cuantity: doc.cuantity + aggEntry.addedCuantity }
  IN test4
  LET updated = NEW
  RETURN updated