我试图使用AQL更新嵌入式数组中的json文档的属性.如何使用下面的AQL更新"home"类型地址的"地址线"?
{
name: "test",
address: [
{"addressline": "1234 superway", type:"home"},
{"addressline": "5678 superway", type:"work"}
]
}
Run Code Online (Sandbox Code Playgroud)
for u in users
for a in u.address
FILTER a.type='home'
UPDATE u WITH {<What goes here to update addressline?>} in users
Run Code Online (Sandbox Code Playgroud)
感谢您的帮助.
此致,Anjan
为此,我们必须使用临时变量.我们将在那里收集子列表并进行更改.我们选择一个简单的布尔过滤条件来使查询更易于理解.
首先,我们使用示例创建一个集合:
database = db._create('complexCollection')
database.save({
"topLevelAttribute" : "a",
"subList" : [
{
"attributeToAlter" : "oldValue",
"filterByMe" : true
},
{
"attributeToAlter" : "moreOldValues",
"filterByMe" : true
},
{
"attributeToAlter" : "unchangedValue",
"filterByMe" : false
}
]
})
Run Code Online (Sandbox Code Playgroud)
其继承人保持查询子列表上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
Run Code Online (Sandbox Code Playgroud)
虽然现在的查询功能正常:
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"
}
]
}
]
Run Code Online (Sandbox Code Playgroud)
此查询可能很快就会成为性能瓶颈,因为无论值是否发生变化,它都会修改集合中的所有文档.因此,如果我们确实更改了它们的值,我们只想更新文档.因此,我们使用第二个FOR来测试subList是否会被更改:
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
Run Code Online (Sandbox Code Playgroud)
ArangoDB现在支持子集索引。以下查询基于dothebart的答案:
FOR document IN complexCollection
FILTER document.subList[*].filterByMe == true LIMIT 1
LET alteredList = (
FOR element IN document.subList
LET newItem = (element.filterByMe == true
? MERGE(element, { attributeToAlter: "the shiniest value"}))
: element
RETURN newItem)
UPDATE document WITH { items:alteredList } IN complexCollection
Run Code Online (Sandbox Code Playgroud)
注意:不要忘记在上创建hash索引subList[*].filterByMe:
db._collection('complexCollection')
.ensureIndex({type:'hash',fields:['subList[*].filterByMe']});
Run Code Online (Sandbox Code Playgroud)