$orderby$select 在 Azure AI 搜尋服務中的 OData 語言概觀$filter

本文提供 Azure AI 搜尋服務中$filter、$order及$select運算式中使用的 OData 表達式語言概觀。 語言會以最基本的元素開始呈現「由下而上」。 您可以在查詢要求中建構的 OData 運算式,範圍從簡單到高度複雜,但全都共用通用元素。 共用元素包括:

  • 欄位路徑,其會參考索引的特定欄位。
  • 常數,這是特定數據類型的常值。

一旦您了解這些常見的概念,您可以繼續每個表達式的最上層語法:

  • $filter表示式會在查詢剖析期間評估、限制搜尋至特定欄位,或新增索引掃描期間所使用的比對準則。
  • $orderby表示式會套用為結果集的後置處理步驟,以排序傳回的檔。
  • $select表示式會決定結果集中包含哪些檔欄位。

這些表達式的語法與搜尋參數中使用的簡單完整查詢語法不同,不過在參考欄位的語法中有些重疊。

注意

Azure AI 搜尋中的術語與 OData 標準 有幾種不同。 我們在 Azure AI 搜尋中呼叫的欄位稱為 OData 中的屬性,類似於欄位路徑屬性路徑。OData 中,包含檔在 Azure AI 搜尋中的索引通常稱為包含實體的實體。 此參考中會使用 Azure AI 搜尋術語。

欄位路徑

下列 EBNF (Extended Backus-Naur Form) 會定義欄位路徑的文法。

field_path ::= identifier('/'identifier)*

identifier ::= [a-zA-Z_][a-zA-Z_0-9]*

您也可以使用互動式語法圖表:

注意

如需完整的EBNF,請參閱 Azure AI 搜尋 的 OData 表達式語法參考。

欄位路徑是由一或多個 以斜線分隔的標識碼 所組成。 每個標識碼都是一連串字元,必須以 ASCII 字母或底線開頭,且只包含 ASCII 字母、數位或底線。 字母可以是大寫或小寫。

標識元可以參考欄位的名稱,或參考篩選中集合表示式anyall) 內容中的範圍變數。 範圍變數就像迴圈變數,代表集合的目前專案。 對於複雜的集合,該變數代表物件,這就是為什麼您可以使用欄位路徑來參考變數的子欄位。 這類似於許多程式設計語言中的點表示法。

下表顯示欄位路徑的範例:

欄位路徑 描述
HotelName 參考索引的最上層欄位
Address/City City參考索引中複雜欄位的子字段;Address在此範例中為 類型Edm.ComplexType
Rooms/Type Type參考索引中複雜集合欄位的子字段;Rooms在此範例中為 類型Collection(Edm.ComplexType)
Stores/Address/Country Country參考索引中複雜集合欄位之子欄位的Address子欄位;Stores類型Collection(Edm.ComplexType)Address為 ,在此範例中為類型Edm.ComplexType
room/Type Type參考範圍變數的room子欄位,例如在篩選表示式中Rooms/any(room: room/Type eq 'deluxe')
store/Address/Country Country參考範圍變量子欄位的Address子欄位store,例如在篩選表示式中Stores/any(store: store/Address/Country eq 'Canada')

欄位路徑的意義會根據內容而有所不同。 在篩選中,欄位路徑是指目前檔中欄位的單一 實例 值。 在其他內容中,例如$orderby$select或完整 Lucene 語法中的欄位搜尋中,欄位路徑會參考欄位本身。 這項差異對於您在篩選中使用字段路徑的方式有一些後果。

請考慮欄位路徑 Address/City。 在篩選條件中,這是指目前檔的單一城市,例如 「San Francisco」。。 相比之下, Rooms/Type 指的是 Type 許多房間的子字段(如第一個房間的“標準”,第二個房間的“豪華”等等)。 由於 Rooms/Type 不會參考子欄位Type的單一實例,因此無法直接在篩選中使用。 相反地,若要篩選會議室類型,您可以使用 Lambda 表達式 搭配範圍變數,如下所示:

Rooms/any(room: room/Type eq 'deluxe')

在此範例中,範圍變數 room 會出現在欄位路徑中 room/Type 。 如此一來, room/Type 會參考目前檔中目前會議室的類型。 這是子欄位的單 Type 一實例,因此可以直接在篩選中使用。

使用欄位路徑

欄位路徑用於 Azure AI 搜尋 REST API 的許多參數中。 下表列出可以使用的所有位置,以及其使用方式的任何限制:

API 參數名稱 限制
建立更新 索引 suggesters/sourceFields
建立更新 索引 scoringProfiles/text/weights 只能參考 搜尋的欄位
建立更新 索引 scoringProfiles/functions/fieldName 只能參考 篩選的欄位
搜尋 searchqueryTypefull 只能參考 搜尋的欄位
搜尋 facet 只能參考 多面向欄位
搜尋 highlight 只能參考 搜尋的欄位
搜尋 searchFields 只能參考 搜尋的欄位
建議自動完成 searchFields 只能參考屬於建議工具一部分的 欄位
搜尋建議自動完成 $filter 只能參考 篩選的欄位
搜尋建議 $orderby 只能參考 排序的欄位
搜尋建議查閱 $select 只能參考 可擷 取的欄位

常數

OData 中的常數是指定 實體數據模型 (EDM) 類型的常值。 如需 Azure AI 搜尋中支援的型別清單,請參閱 支援的數據類型 。 不支援集合類型的常數。

下表顯示 Azure AI 搜尋所支援之每個資料類型的常數範例:

資料類型 範例常數
Edm.Boolean true, false
Edm.DateTimeOffset 2019-05-06T12:30:05.451Z
Edm.Double 3.14159、、 -1.2e7NaNINF-INF
Edm.GeographyPoint geography'POINT(-122.131577 47.678581)'
Edm.GeographyPolygon geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'
Edm.Int32 123, -456
Edm.Int64 283032927235
Edm.String 'hello'

逸出字串常數中的特殊字元

OData 中的字串常數是以單引號分隔。 如果您需要使用可能包含單引號的字串常數來建構查詢,您可以將內嵌引號加倍以逸出。

例如,具有未格式化單引號的片語,如 「Alice 的 car」 會在 OData 中表示為字串常數 'Alice''s car'

重要

以程式設計方式建構篩選時,請務必記住逸出來自使用者輸入的字元串常數。 這是為了減輕插入式攻擊的可能性,特別是在使用篩選來實作安全性調整時。

常數語法

下列 EBNF (Extended Backus-Naur Form) 會定義上表所示大部分常數的文法。 您可以在 Azure AI 搜尋的 OData 地理空間函式中找到地理空間類型的文法。

constant ::=
    string_literal
    | date_time_offset_literal
    | integer_literal
    | float_literal
    | boolean_literal
    | 'null'

string_literal ::= "'"([^'] | "''")*"'"

date_time_offset_literal ::= date_part'T'time_part time_zone

date_part ::= year'-'month'-'day

time_part ::= hour':'minute(':'second('.'fractional_seconds)?)?

zero_to_fifty_nine ::= [0-5]digit

digit ::= [0-9]

year ::= digit digit digit digit

month ::= '0'[1-9] | '1'[0-2]

day ::= '0'[1-9] | [1-2]digit | '3'[0-1]

hour ::= [0-1]digit | '2'[0-3]

minute ::= zero_to_fifty_nine

second ::= zero_to_fifty_nine

fractional_seconds ::= integer_literal

time_zone ::= 'Z' | sign hour':'minute

sign ::= '+' | '-'

/* In practice integer literals are limited in length to the precision of
the corresponding EDM data type. */
integer_literal ::= digit+

float_literal ::=
    sign? whole_part fractional_part? exponent?
    | 'NaN'
    | '-INF'
    | 'INF'

whole_part ::= integer_literal

fractional_part ::= '.'integer_literal

exponent ::= 'e' sign? integer_literal

boolean_literal ::= 'true' | 'false'

您也可以使用互動式語法圖表:

注意

如需完整的EBNF,請參閱 Azure AI 搜尋 的 OData 表達式語法參考。

從欄位路徑和常數建置表達式

欄位路徑和常數是 OData 運算式中最基本的部分,但它們本身已經是完整的表達式。 事實上,Azure AI 搜尋中的$select參數只不過是字段路徑的逗號分隔清單,$orderby比$select複雜得多。 如果您碰巧在索引中有類型 Edm.Boolean 欄位,您甚至可以撰寫一個除了該欄位路徑外沒有的篩選條件。 常數 truefalse 同樣是有效的篩選。

不過,您大部分時間都需要更複雜的表達式,這些表達式會參考多個字段和常數。 根據 參數,這些表達式會以不同的方式建置。

下列 EBNF (Extended Backus-Naur Form) 會定義$filter$orderby$select參數的文法。 這些是透過參考欄位路徑和常數的較簡單運算式所建置:

filter_expression ::= boolean_expression

order_by_expression ::= order_by_clause(',' order_by_clause)*

select_expression ::= '*' | field_path(',' field_path)*

您也可以使用互動式語法圖表:

注意

如需完整的EBNF,請參閱 Azure AI 搜尋 的 OData 表達式語法參考。

下一步

$orderby和$select參數都是簡單表達式的逗號分隔清單。 $filter參數是由較簡單的子表達式所組成的布爾表達式。 這些子運算式會使用邏輯運算子結合,例如 、、 和not 、比較運算元eq,例如 、ltgt等等,以及和 等allany集合運算元。 orand

下列 文章會更詳細地探索$filter$orderby$select 參數: