簡體   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