ArangoDB AQL:更新嵌入式数组中的单个对象 [英] ArangoDB AQL: Update single object in embedded array

查看:21
本文介绍了ArangoDB AQL:更新嵌入式数组中的单个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 AQL 更新嵌入数组中的 json 文档的属性.我如何使用下面的 AQL 更新家庭"类型地址的地址线"?

I am trying to update the attribute on a json document in an embedded array using AQL. How do i update the "addressline" for "home" type address using AQL below?

{
name: "test",
address: [
      {"addressline": "1234 superway", type:"home"}, 
      {"addressline": "5678 superway", type:"work"}
     ]
}

到目前为止的 AQL 尝试

for u in users
   for a in u.address
     FILTER a.type='home'
       UPDATE u WITH {<What goes here to update addressline?>} in users

感谢您的帮助.

问候,安然

推荐答案

为此,我们必须使用临时变量.我们将在那里收集子列表并对其进行更改.我们选择了一个简单的布尔过滤条件,使查询更易于理解.

To do this we have to work with temporary variables. We will collect the sublist in there and alter it. We choose a simple boolean filter condition to make the query better comprehensible.

首先让我们用一个样本创建一个集合:

First lets create a collection with a sample:

database = db._create('complexCollection')
database.save({ 
  "topLevelAttribute" : "a", 
  "subList" : [ 
    { 
      "attributeToAlter" : "oldValue", 
      "filterByMe" : true 
    }, 
    { 
      "attributeToAlter" : "moreOldValues", 
      "filterByMe" : true 
    }, 
    { 
      "attributeToAlter" : "unchangedValue", 
      "filterByMe" : false 
    } 
  ] 
})

这是将 subList 保留在 alteredList 上以便稍后更新的查询:

Heres the Query which keeps the subList on alteredList to update it later:

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

虽然查询现在可以正常运行:

While the query as it is is now functional:

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" 
      } 
    ] 
  } 
]

此查询可能很快就会成为性能瓶颈,因为它修改集合中的所有文档无论值是否更改.因此,如果我们真的改变了它们的值,我们只想UPDATE 文档.因此我们使用第二个 FOR 来测试 subList 是否会被改变:

This query will probably be soonish a performance bottleneck, since it modifies all documents in the collection regardless whether the values change or not. Therefore we want to only UPDATE the documents if we really change their value. Therefore we employ a second FOR to test whether subList will be altered or not:

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 AQL:更新嵌入式数组中的单个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆