ArangoDB AQL:更新嵌入式数组中的单个对象
ArangoDB AQL: Update single object in embedded array
我正在尝试使用 AQL 更新嵌入式数组中 json 文档的属性。我如何使用下面的 AQL 为 "home" 类型地址更新 "addressline"?
用户:
{
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
感谢您的帮助。
此致,
安然
为此,我们必须使用临时变量。我们将在那里收集子列表并对其进行更改。我们选择一个简单的布尔过滤条件,使查询更好理解。
首先让我们创建一个样本集合:
database = db._create('complexCollection')
database.save({
"topLevelAttribute" : "a",
"subList" : [
{
"attributeToAlter" : "oldValue",
"filterByMe" : true
},
{
"attributeToAlter" : "moreOldValues",
"filterByMe" : true
},
{
"attributeToAlter" : "unchangedValue",
"filterByMe" : false
}
]
})
这是将 subList 保留在 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"
}
]
}
]
这个查询可能很快就会成为性能瓶颈,因为它修改集合中的所有文档无论值是否改变 .因此,如果我们真的改变了文档的值,我们只想 UPDATE 文档。因此,我们使用第二个 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
ArangoDB 现在支持子集索引。以下查询基于 dothebart 的回答:
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
注意:不要忘记在subList[*].filterByMe
上创建一个hash
索引:
db._collection('complexCollection')
.ensureIndex({type:'hash',fields:['subList[*].filterByMe']});
我正在尝试使用 AQL 更新嵌入式数组中 json 文档的属性。我如何使用下面的 AQL 为 "home" 类型地址更新 "addressline"?
用户:
{
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
感谢您的帮助。
此致, 安然
为此,我们必须使用临时变量。我们将在那里收集子列表并对其进行更改。我们选择一个简单的布尔过滤条件,使查询更好理解。
首先让我们创建一个样本集合:
database = db._create('complexCollection')
database.save({
"topLevelAttribute" : "a",
"subList" : [
{
"attributeToAlter" : "oldValue",
"filterByMe" : true
},
{
"attributeToAlter" : "moreOldValues",
"filterByMe" : true
},
{
"attributeToAlter" : "unchangedValue",
"filterByMe" : false
}
]
})
这是将 subList 保留在 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"
}
]
}
]
这个查询可能很快就会成为性能瓶颈,因为它修改集合中的所有文档无论值是否改变 .因此,如果我们真的改变了文档的值,我们只想 UPDATE 文档。因此,我们使用第二个 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
ArangoDB 现在支持子集索引。以下查询基于 dothebart 的回答:
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
注意:不要忘记在subList[*].filterByMe
上创建一个hash
索引:
db._collection('complexCollection')
.ensureIndex({type:'hash',fields:['subList[*].filterByMe']});