Reputation: 7750
I expected to run both upsert
for i in [1,2]
upsert { _key: i } insert {v:i} update{} in Test
upsert { _key: i*100 } insert {v:i*100} update{} in Test
But I got
Query: variable '$OLD' is assigned multiple times (while parsing)
Version: 3.1.14
EDIT
In real query , what I want to do is something like this
FOR n IN MyData
FILTER n.person
FOR p IN n.person
UPSERT { _key: p.id } INSERT { _key:p.id, name:p.name} UPDATE {} IN Person
UPSERT { _from:CONCAT('Person/',p.id),_to:CONCAT('Other/',n.id) }
INSERT { _from:CONCAT('Person/',p.id),_to:CONCAT('Other/',n.id), type: n.type }
UPDATE {} IN PersonRelation
Have ever arangodb consider there will be multi upsert ?
Currently, I have to run query one by one, the dataset is big, so, it's very slow to just run one upsert a time. Maybe I should use INSERT
and ignoreErrors
.
Upvotes: 2
Views: 1627
Reputation: 2349
I'm pretty sure this error is happening because you are writing to the collection twice and the query optimizer won't let you do it.
Another solution is to write the same content, still using an UPSERT
command, but shuffle it around a bit so you are only writing once.
This example works:
LET new_documents = FLATTEN(FOR i IN [1,2] RETURN [{_key: TO_STRING(i), v:i},{ _key: TO_STRING(i*100), v:i*100 } ])
FOR doc IN new_documents
UPSERT { _key: doc._key } INSERT { _key: doc._key, v: doc.v } UPDATE{} IN Test
RETURN {
new_entries: NEW,
old_entries: OLD
}
A few notes:
new_documents
variable is created and it contains the records you want to add.new_documents
goes through FLATTEN
to turn it into a flat array of objects._key
of each document is converted to a string, as a _key must be a stringUPSERT
on each member of arrayNEW
and OLD
which are free output variables from the UPSERT
command. The NEW
variable can be very useful if you were inserting new records and the _key
value was being generated automatically. By looking at the NEW
variable you can fetch the _key
s of all the new documents you just added, if you added them at all.
To support your updated question, you can still perform multiple UPSERT
s by isolating them in a variable definition, like this:
FOR n IN myData
FILTER n.v
LET test = (UPSERT { _key: n.v } INSERT { _key: n.v, v: n.v } UPDATE {} IN Test)
LET test2 = (UPSERT { _key: n.v } INSERT { _key: n.v, v: n.v } UPDATE {} IN Test2)
RETURN {
done: true
}
This query reads documents from myData
and then based on that performs UPSERT
commands into the collections Test
and Test2
.
That should help you with your data model, just make sure the value you use as the _key
for the new documents is a string.
Upvotes: 2