繁体   English   中英

arango Foxx中的AQL模板不适用于数组

[英]AQL template in arango Foxx does not work correctly with array

如果使用数组,以下查询将不起作用,但如果使用字符串来构造代码段,则以下查询将正常工作。 我是否在某个地方犯了错误,或者这是与arango相关的错误?

var array=["1","2"]
//Make a snippet depend on array.
var snippet=aql.literal(`FILTER u.id IN "${array}"`)

//Main query. Result is incorrect even though it runs
var query=db._query(aql`
For u in Collection
{$snippet}
RETURN u
`
)

使用字符串进行正确查询的示例

var string="1"
var snippet=aql.literal(`FILTER u.id == "${array}"`)

FILTER u.id IN "${array}"产生FILTER u.id IN "1,2" 请注意, IN右侧是一个字符串,不再是字符串数组。

发生的情况是字符串插值(反引号)使用array.toString()的结果,即1,2 周围的引号实际上是被接管的,这可能不是您想要的。 请参阅有关ArangoJSQueries文档末尾的示例

即使数组表示形式为["1","2"] ,这些引号也会导致"["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'

但是,这不是很优雅,从ArangoJS v6.7.0开始,它实际上支持嵌套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
`)

您也可以通过ArangoDB v3.4在Arangosh / Foxx( db._query() )中使用它。

另请参阅: ArangoJS Changelog

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM