Azure AI 搜尋服務中 $filter
、$orderby
和 $select
的 OData 語言概觀
本文提供 $filter
、$order-by
和 $select
運算式 (用於在 Azure AI 搜尋服務中針對數值和字串 (非向量) 欄位進行關鍵字搜尋) 中使用的 OData 運算式語言概觀。
語言會以「由下而上」呈現,開頭為最基本的元素。 您可在查詢要求中建構的 OData 運算式範圍可從簡單到高度複雜,但這些運算式皆共用通用元素。 共用元素包含:
- 欄位路徑,其會參考索引的特定欄位。
- 常數,其是特定資料類型的常值。
了解這些常見概念之後,您可繼續進行每個運算式的最上層語法:
- $filter 在進行查詢剖析、將搜尋限定於特定欄位,或在索引掃描期間新增比對準則時,會評估篩選運算式。
- $orderby 運算式會套用作為結果集的後續處理步驟以排序傳回的文件。
- $select 運算式會決定結果集中包含的文件欄位。
這些運算式的語法與搜尋參數中使用的簡單或完整查詢語法不同,即使參考欄位的語法有某些重疊。
如需其他語言的範例,例如 Python 或 C#,請參閱 azure-search-vector-samples 存放庫中的範例。
注意
Azure AI 搜尋服務的詞彙與 OData 標準的詞彙有一些不同的地方。 Azure AI 搜尋服務中稱為欄位,在 OData 中則稱為屬性;同理,欄位路徑與屬性路徑亦是如此。 在 Azure AI 搜尋服務中包含文件的索引,在 OData 中通常稱為包含實體的實體集。 此參考會使用 Azure AI 搜尋服務的詞彙。
欄位路徑
下列 EBNF (延伸的巴克斯格式) 會定義欄位路徑的語法。
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 |
指的是索引中複雜集合欄位 Address 子欄位的 Country 子欄位;在此範例中,Stores 屬於類型 Collection(Edm.ComplexType) ,Address 屬於類型 Edm.ComplexType |
room/Type |
指的是 room 範圍變數的 Type 子欄位,例如篩選條件運算式為 Rooms/any(room: room/Type eq 'deluxe') |
store/Address/Country |
指的是 store 範圍變數 Address 子欄位的 Country 子欄位,例如篩選條件運算式為 Stores/any(store: store/Address/Country eq 'Canada') |
欄位路徑的亦亦會根據內容而有所不同。 在篩選條件中,欄位路徑指的是目前文件中欄位單一執行個體的值。 在其他內容 (例如 $orderby、$select) 或在完整 Lucene 語法的欄位搜尋中,欄位路徑指的是欄位本身。 此差異對於如何在篩選條件中使用欄位路徑會有某些結果。
考量欄位路徑 Address/City
。 在篩選條件中,這指的是目前文件的單一城市,例如「舊金山」。 相反地,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 時的 search |
僅可參考可搜尋欄位 |
Search | facet |
僅可參考可面向化欄位 |
Search | highlight |
僅可參考可搜尋欄位 |
Search | searchFields |
僅可參考可搜尋欄位 |
建議和自動完成 | searchFields |
僅可參考屬於建議工具的欄位 |
搜尋、建議和自動完成 | $filter |
僅可參考可篩選欄位 |
搜尋和建議 | $orderby |
僅可參考可排序欄位 |
搜尋、建議和查閱 | $select |
僅可參考可擷取欄位 |
常數
OData 中的常數是指定實體資料模型 (EDM) 類型的常值。 如需 Azure AI 搜尋服務中支援類型的清單,請參閱支援的資料類型。 不支援集合類型的常數。
下表顯示支援 OData 運算式的每個非向量資料類型的常數範例:
資料類型 | 範例常數 |
---|---|
Edm.Boolean |
% |
Edm.DateTimeOffset |
2019-05-06T12:30:05.451Z |
Edm.Double |
|
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 |
% |
Edm.Int64 |
283032927235 |
Edm.String |
'hello' |
逸出字串常數中的特殊字元
OData 中的字串常數會以單引號分隔。 若您必須以可能自身包含單引號的字串常數來建構查詢,您可使用雙引號來逸出內嵌的引號。
例如,含未格式化單引號 (例如 "Alice's car") 的片語會在 OData 中以字串常數 'Alice''s car'
呈現。
常數語法
下列 EBNF (延伸的巴克斯格式) 會定義上表中顯示的大部分常數文法。 您可在 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 參數僅是欄位路徑的逗點分隔清單,而相較於 $select,$orderby 較不複雜。 若在索引中有類型 Edm.Boolean
的欄位,您甚至可僅撰寫該欄位路徑的篩選條件。 常數 true
和 false
同是有效篩選條件。
不過,參考多個欄位和常數的複雜運算式比較常見。 這些運算式會根據參數,以不同方式來建置。
下列 EBNF (延伸的巴克斯格式) 會定義 $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 參數是布林運算式,其中包含較簡單的子運算式。 這些子運算式會使用下列運算子進行合併:邏輯運算子 (例如 and
、or
和 not
)、比較運算子 (例如 eq
、lt
、gt
等) 和集合運算子 (例如 any
和 all
)。
下列文章會更詳細探索 $filter、$orderby 和 $select 參數: