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"}
]
}
for u in users
for a in u.address
FILTER a.type='home'
UPDATE u WITH {<What goes here to update addressline?>} in users
Thank you for the help.
Regards, Anjan
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
}
]
})
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"
}
]
}
]
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 now supports subset indexes. The following query is based on dothebart s answer:
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
Note : Don't forget to create a hash
index on subList[*].filterByMe
:
db._collection('complexCollection')
.ensureIndex({type:'hash',fields:['subList[*].filterByMe']});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.