ArangoDB AQL:更新嵌入式阵列中的单个对象

ArangoDB AQL:更新嵌入式阵列中的单个对象,arangodb,Arangodb,我正在尝试使用AQL更新嵌入数组中json文档的属性。如何使用下面的AQL更新“家庭”类型地址的“地址行” 用户: AQL迄今为止的尝试 适用于用户中的u 在美国的地址 过滤器a.type='home' 在用户中使用{}更新u 谢谢你的帮助 问候,, Anjan要做到这一点,我们必须使用临时变量。我们将在那里收集子列表并对其进行更改。我们选择一个简单的布尔过滤条件,使查询更易于理解 首先,让我们使用示例创建一个集合: database = db._create('complexCollecti

我正在尝试使用AQL更新嵌入数组中json文档的属性。如何使用下面的AQL更新“家庭”类型地址的“地址行”

用户: AQL迄今为止的尝试
适用于用户中的u
在美国的地址
过滤器a.type='home'
在用户中使用{}更新u
谢谢你的帮助

问候,,
Anjan要做到这一点,我们必须使用临时变量。我们将在那里收集子列表并对其进行更改。我们选择一个简单的布尔过滤条件,使查询更易于理解

首先,让我们使用示例创建一个集合:

database = db._create('complexCollection')
database.save({ 
  "topLevelAttribute" : "a", 
  "subList" : [ 
    { 
      "attributeToAlter" : "oldValue", 
      "filterByMe" : true 
    }, 
    { 
      "attributeToAlter" : "moreOldValues", 
      "filterByMe" : true 
    }, 
    { 
      "attributeToAlter" : "unchangedValue", 
      "filterByMe" : false 
    } 
  ] 
})
以下是将子列表保留在alteredList上以便稍后更新的查询:

FOR document in complexCollection
  LET alteredList = (
    FOR element IN document.subList 
       LET newItem = (! element.filterByMe ?
                      element :
                      MERGE(element, { attributeToAlter: "shiny New Value" }))
       RETURN newItem)
  UPDATE document WITH { subList:  alteredList } IN complexCollection
虽然查询现在可以正常运行:

db.complexCollection.toArray()
[ 
  { 
    "_id" : "complexCollection/392671569467", 
    "_key" : "392671569467", 
    "_rev" : "392799430203", 
    "topLevelAttribute" : "a", 
    "subList" : [ 
      { 
        "filterByMe" : true, 
        "attributeToAlter" : "shiny New Value" 
      }, 
      { 
        "filterByMe" : true, 
        "attributeToAlter" : "shiny New Value" 
      }, 
      { 
        "filterByMe" : false, 
        "attributeToAlter" : "unchangedValue" 
      } 
    ] 
  } 
]
此查询可能会成为性能瓶颈,因为无论值是否更改,它都会修改集合中的所有文档。因此,我们只希望在真正更改文档的值时更新文档。因此,我们采用第二种方法来测试子列表是否会被更改:

FOR document in complexCollection
  LET willUpdateDocument = (
    FOR element IN document.subList 
      FILTER element.filterByMe LIMIT 1 RETURN 1)

  FILTER LENGTH(willUpdateDocument) > 0

  LET alteredList = (
    FOR element IN document.subList 
       LET newItem = (! element.filterByMe ?
                      element :
                      MERGE(element, { attributeToAlter: "shiny New Value" }))
       RETURN newItem)

  UPDATE document WITH { subList:  alteredList } IN complexCollection

ArangoDB现在支持子集索引。以下查询是基于客户的回答:

注意:别忘了在
子列表[*]上创建
哈希
索引。filterByMe

db._collection('complexCollection')
    .ensureIndex({type:'hash',fields:['subList[*].filterByMe']});

谢谢@dothebart!这太棒了!我知道整个子列表可能必须在更新/合并中传递,但正在努力设置该子列表。再次感谢。
FOR document in complexCollection
  LET willUpdateDocument = (
    FOR element IN document.subList 
      FILTER element.filterByMe LIMIT 1 RETURN 1)

  FILTER LENGTH(willUpdateDocument) > 0

  LET alteredList = (
    FOR element IN document.subList 
       LET newItem = (! element.filterByMe ?
                      element :
                      MERGE(element, { attributeToAlter: "shiny New Value" }))
       RETURN newItem)

  UPDATE document WITH { subList:  alteredList } IN complexCollection
FOR document IN complexCollection
    FILTER document.subList[*].filterByMe == true LIMIT 1
    UPDATE document WITH {
        items: (
            FOR element IN document.subList
                RETURN element.filterByMe == true
                     ? MERGE(element, { attributeToAlter: "the shiniest value"})
                     : element
        )
    } IN complexCollection
db._collection('complexCollection')
    .ensureIndex({type:'hash',fields:['subList[*].filterByMe']});