I'm trying to use IF THEN style AQL, but the only relevant operator I could find in the AQL documentation was the ternary operator. I tried to add IF THEN syntax to my already working AQL but it gives syntax errors no matter what I try.
LET doc = DOCUMENT('xp/a-b')
LET now = DATE_NOW()
doc == null || now - doc.last >= 45e3 ?
LET mult = (doc == null || now - doc.last >= 6e5 ? 1 : doc.multiplier)
LET gained = FLOOR((RAND() * 3 + 3) * mult)
UPSERT {_key: 'a-b'}
INSERT {
amount: gained,
total: gained,
multiplier: 1.1,
last: now
}
UPDATE {
amount: doc.amount + gained,
total: doc.total + gained,
multiplier: (mult < 4 ? FLOOR((mult + 0.1) * 10) / 10 : 4),
last: now
}
IN xp
RETURN NEW
:
RETURN null
Gives the following error message:
stacktrace: ArangoError: AQL: syntax error, unexpected identifier near 'doc == null || now - doc.last >=...' at position 1:51 (while parsing)
The ternary operator can not be used like an if/else construct in the way to tried. It is for conditional (sub-)expressions like you use to calculate mult
. It can not stand by itself, there is nothing it can be returned or assigned to if you write it like an if-expression.
Moreover, it would require braces, but the actual problem is that the body contains operations like LET
, UPSERT
and RETURN
. These are language constructs which can not be used inside of expressions.
If I understand correctly, you want to:
a-b
exists yet in collection xb
Does the following query work for you?
FOR id IN [ 'xp/a-b' ]
LET doc = DOCUMENT(id)
LET key = PARSE_IDENTIFIER(id).key
LET now = DATE_NOW()
FILTER doc == null || now - doc.last >= 45e3
LET mult = (doc == null || now - doc.last >= 6e5 ? 1 : doc.multiplier)
LET gained = FLOOR((RAND() * 3 + 3) * mult)
UPSERT { _key: key }
INSERT {
_key: key,
amount: gained,
total: gained,
multiplier: 1.1,
last: now
}
UPDATE {
amount: doc.amount + gained,
total: doc.total + gained,
multiplier: (mult < 4 ? FLOOR((mult + 0.1) * 10) / 10 : 4),
last: now
}
IN xp
RETURN NEW
I added _key
to INSERT
, otherwise the document will get an auto-generated key, which does not seem intended. Using a FOR
loop and a FILTER
acts like an IF construct (without ELSE). Because this is a data modification query, it is not necessary to explicitly RETURN
anything and in your original query you RETURN null
for the ELSE case anyway. While yours would result in [ null ]
, mine produces [ ]
(truly empty result) if you try execute the query in quick succession and nothing gets updated or inserted.
Note that it is necessary to use PARSE_IDENTIFIER()
to get the key from the document ID string and do INSERT { _key: key }
. With INSERT { _key: doc._key }
you would run into an invalid document key error in the insert case, because if there is no document xp/a-b
, DOCUMENT()
returns null
and doc._key
is therefore also null
, leading to _key: null
- which is invalid.