在 AQL 中使用 IF THEN 的正确方法是什么?
What is the proper way to use IF THEN in AQL?
我正在尝试使用 IF THEN 样式的 AQL,但我在 AQL 文档中找到的唯一相关运算符是三元运算符。我尝试将 IF THEN 语法添加到我已经工作的 AQL,但无论我尝试什么,它都会给出语法错误。
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
给出以下错误信息:
stacktrace: ArangoError: AQL: syntax error, unexpected identifier near 'doc == null || now - doc.last >=...' at position 1:51 (while parsing)
三元运算符不能像 if/else 结构那样使用,以供尝试。它适用于您用来计算 mult
的条件(子)表达式。它不能单独存在,如果你把它写成一个 if 表达式,它就不能被返回或赋值。
此外,它需要大括号,但实际问题是正文包含 LET
、UPSERT
和 RETURN
等操作。这些是不能在表达式内部使用的语言结构。
如果我没理解错的话,你想要:
- 如果集合
xb
中不存在具有键 a-b
的文档,则插入一个新文档
- 如果确实存在,则更新它,但前提是最后一次更新是在 45 秒或更长时间之前
以下查询是否适合您?
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
我将 _key
添加到 INSERT
,否则文档将获得一个自动生成的密钥,这似乎不是预期的。使用 FOR
循环和 FILTER
就像一个 IF 结构(没有 ELSE)。因为这是一个数据修改查询,所以没有必要显式 RETURN
任何内容,并且在您的原始查询中您 RETURN null
无论如何都是 ELSE 情况。虽然你的结果是 [ null ]
,但如果你尝试快速连续执行查询并且没有更新或插入任何内容,我的结果将是 [ ]
(真正的空结果)。
请注意,需要使用PARSE_IDENTIFIER()
从文档ID字符串中获取密钥并执行INSERT { _key: key }
。使用 INSERT { _key: doc._key }
你会 运行 在插入案例中出现 无效文档键 错误,因为如果没有文档 xp/a-b
,DOCUMENT()
returns null
和 doc._key
因此也是 null
,导致 _key: null
- 这是无效的。
我正在尝试使用 IF THEN 样式的 AQL,但我在 AQL 文档中找到的唯一相关运算符是三元运算符。我尝试将 IF THEN 语法添加到我已经工作的 AQL,但无论我尝试什么,它都会给出语法错误。
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
给出以下错误信息:
stacktrace: ArangoError: AQL: syntax error, unexpected identifier near 'doc == null || now - doc.last >=...' at position 1:51 (while parsing)
三元运算符不能像 if/else 结构那样使用,以供尝试。它适用于您用来计算 mult
的条件(子)表达式。它不能单独存在,如果你把它写成一个 if 表达式,它就不能被返回或赋值。
此外,它需要大括号,但实际问题是正文包含 LET
、UPSERT
和 RETURN
等操作。这些是不能在表达式内部使用的语言结构。
如果我没理解错的话,你想要:
- 如果集合
xb
中不存在具有键 - 如果确实存在,则更新它,但前提是最后一次更新是在 45 秒或更长时间之前
a-b
的文档,则插入一个新文档
以下查询是否适合您?
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
我将 _key
添加到 INSERT
,否则文档将获得一个自动生成的密钥,这似乎不是预期的。使用 FOR
循环和 FILTER
就像一个 IF 结构(没有 ELSE)。因为这是一个数据修改查询,所以没有必要显式 RETURN
任何内容,并且在您的原始查询中您 RETURN null
无论如何都是 ELSE 情况。虽然你的结果是 [ null ]
,但如果你尝试快速连续执行查询并且没有更新或插入任何内容,我的结果将是 [ ]
(真正的空结果)。
请注意,需要使用PARSE_IDENTIFIER()
从文档ID字符串中获取密钥并执行INSERT { _key: key }
。使用 INSERT { _key: doc._key }
你会 运行 在插入案例中出现 无效文档键 错误,因为如果没有文档 xp/a-b
,DOCUMENT()
returns null
和 doc._key
因此也是 null
,导致 _key: null
- 这是无效的。