、 $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 字母、數位或底線。 字母可以是大寫或小寫。
標識元可以參考欄位的名稱,或參考篩選中集合表示式 (any
或all
) 內容中的範圍變數。 範圍變數就像迴圈變數,代表集合的目前專案。 對於複雜的集合,該變數代表物件,這就是為什麼您可以使用欄位路徑來參考變數的子欄位。 這類似於許多程式設計語言中的點表示法。
下表顯示欄位路徑的範例:
欄位路徑 | 描述 |
---|---|
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 |
只能參考 可 篩選的欄位 |
搜尋 | search 當 queryType 為 full |
只能參考 可 搜尋的欄位 |
搜尋 | 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.2e7 、 NaN 、 INF 、 -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
欄位,您甚至可以撰寫一個除了該欄位路徑外沒有的篩選條件。 常數 true
和 false
同樣是有效的篩選。
不過,您大部分時間都需要更複雜的表達式,這些表達式會參考多個字段和常數。 根據 參數,這些表達式會以不同的方式建置。
下列 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
,例如 、lt
、 gt
等等,以及和 等all
any
集合運算元。 or
and
下列 文章會更詳細地探索$filter、 $orderby和 $select 參數: