FILTER u.id IN "${array}"
производит FILTER u.id IN "1,2"
. Обратите внимание, что справа от IN
находится строка, а не массив строк.
Что происходит, так это то, что интерполяция строк (обратные кавычки) использует результат array.toString()
, который равен 1,2
. Окружающие кавычки берутся буквально, что, вероятно, не то, что вам нужно. См. пример в самом конце Запрашивает документы для ArangoJS.
Даже если бы представление массива было ["1","2"]
, эти кавычки привели бы к "["1","2"]"
, что вызвало бы синтаксическую ошибку. С экранированными внутренними кавычками, такими как "[\"1\",\"2\"]"
, вы бы проверили u.id IN "some string"
, но оператор IN
вернет false для любой строки в правой части (здесь вам нужен массив).
RETURN "1" IN "1" // false
RETURN "1" IN "[\"1\"]" // false
RETURN "1" IN ["1"] // true
Давайте попробуем по-разному использовать aql.literal
:
> aql.literal(`FILTER u.id IN ${array}`).toAQL()
'FILTER u.id IN 1,2'
Существует литерал шаблона, который оценивается и затем передается функции в качестве аргумента. Функция просто упаковывает строку, созданную литералом шаблона, а вызов toAQL() снова распаковывает ее. toAQL() обычно вызывается внутренним помощником aql
.
> aql.literal`FILTER u.id IN ${array}`.toAQL()
'FILTER u.id IN ,'
Здесь используется aql.literal
для помеченного шаблона, но это не функция для обработки строк шаблона. Вывод бесполезен.
> aql.literal('FILTER u.id IN ${array}').toAQL()
'FILTER u.id IN ${array}'
Строка в кавычках (без литерала шаблона!) передается в качестве аргумента aql.literal
. Результат идентичен вводу со знаком доллара и фигурными скобками. Это буквально то же самое, что и ввод. Это предполагаемый способ использования aql.literal()
. Он не поддерживает параметры привязки.
Вы можете положиться на JSON.stringify()
, чтобы правильно экранировать массив следующим образом:
> aql.literal('FILTER u.id IN ' + JSON.stringify(array)).toAQL()
'FILTER u.id IN ["1","2"]'
Пример использования:
> var snippet = aql.literal('FILTER u.id IN ' + JSON.stringify(array))
> aql`FOR u IN Collection ${snippet} RETURN u`.query
'FOR u IN Collection FILTER u.id IN ["1","2"] RETURN u'
Однако это не очень изящно, и, начиная с версии 6.7.0 ArangoJS, он фактически поддерживает вложенность литералов шаблона aql
:
>var snippet = aql`FILTER u.id IN ${array}`
>snippet // see what happens under the hood
{ query: 'FILTER u.id IN @value0', // a bind parameter is used!
bindVars: { value0: [ '1', '2' ] },
_source: [Function: _source] }
> aql`FOR u IN Collection ${snippet} RETURN u`
{ query: 'FOR u IN Collection FILTER u.id IN @value0 RETURN u',
bindVars: { value0: [ '1', '2' ] }, // still bind parameter with the snippet integrated!
_source: [Function: _source] }
Пример использования (для ArangoJS):
var array = [ "1", "2" ]
var snippet = aql`FILTER u.id IN ${array}`
var query = db.query(aql`
FOR u IN Collection
${snippet}
RETURN u
`)
Вы также сможете использовать его в Arangosh/Foxx (db._query()
) с ArangoDB v3.4.
См. также: Журнал изменений ArangoJS
person
CodeManX
schedule
24.10.2018