注意
Azure AI 搜尋服務 可透過 Azure 入口網站、REST API 及 Azure SDK 取得。 它同時也是 Foundry IQ 的基礎,這是一個管理式知識層,能將企業內容轉化為可重複使用、權限感知的知識庫,供 Microsoft Foundry 入口網站中的代理使用。
若要篩選 Azure AI 搜尋服務上的集合欄位,您可使用 any 和 all 運算子搭配 Lambda 運算式。 Lambda 運算式是套用到集合中每個元素的子篩選。
並非所有篩選條件運算式的功能都可以在 Lambda 運算式內使用。 有哪些功能可用,取決於你想篩選的收藏欄位的資料類型。 如果你嘗試在 lambda 表達式中使用該情境下不支援的功能,這個限制可能會導致錯誤。 如果你在嘗試撰寫複雜篩選器時遇到此類錯誤,本文能協助你排除相關問題。
常見的集合篩選錯誤
下表列出嘗試執行集合篩選時可能會遇到的錯誤。 當您使用 Lambda 運算式內不支援的篩選運算式功能時,就會發生這些錯誤。 每個錯誤都會提供一些指導,說明如何重寫篩選,以避免發生錯誤。 下表也包含本文相關章節的連結,提供如何避免該錯誤的詳細資訊。
| 錯誤訊息 | 情況 | 詳細資料 |
|---|---|---|
函式 ismatch 沒有繫結至範圍變數 's' 的參數。 Lambda 運算式內僅支援繫結欄位參考 (any 或 all)。 不過,您可以變更您的篩選,讓 ismatch 函式在 Lambda 運算式之外,然後再試一次。 |
在 Lambda 運算式內使用 search.ismatch 或 search.ismatchscoring |
篩選複雜集合的規則 |
| Lambda 運算式無效。 在對 Collection(Edm.String) 類型欄位進行逐一查看的 lambda 運算式中,發現本應相反的相等或不相等測試。 針對 'any',請使用 'x eq y' 或 'search.in (...)' 格式的運算式。 對於 all,請使用 x ne y、not (x eq y) 或 not search.in(...) 形式的運算式。 | 針對類型Collection(Edm.String)的欄位進行篩選 |
篩選字串集合的規則 |
Lambda 運算式無效。 找到不受支援的複雜布林運算式形式。 對於 any,請使用「AND 的 OR」形式的運算式,也就是析取正規形。 例如:(a and b) or (c and d),其中 a、b、c 和 d 是比較或等式子運算式。 對於 all,請使用「OR 的 AND」形式的運算式,也就是合取正規形。 例如:(a or b) and (c or d),其中 a、b、c 和 d 是比較或不等式的子運算式。 比較運算式的範例:'x gt 5'、'x le 2'。 相等運算式的範例:'x eq 5'。 不等式表達式的範例:'x ne 5'。 |
篩選 Collection(Edm.DateTimeOffset)、Collection(Edm.Double)、Collection(Edm.Int32) 或 Collection(Edm.Int64) 類型的欄位 |
篩選可比較集合的規則 |
| Lambda 運算式無效。 在對 Collection(Edm.GeographyPoint) 類型欄位進行逐一查看的 lambda 運算式中,發現不支援的 geo.distance() 或 geo.intersects() 用法。 對於 any,請確定您使用 lt 或 le 運算子來比較 geo.distance(),並確定對 geo.intersects() 的任何使用都未被否定。 對於 all,請確定您使用 gt 或 ge 運算子來比較 geo.distance(),並確定對 geo.intersects() 的任何使用都是否定形式。 | 針對類型Collection(Edm.GeographyPoint)的欄位進行篩選 |
篩選 GeographyPoint 集合的規則 |
| Lambda 運算式無效。 在逐一查看 Collection(Edm.GeographyPoint) 類型欄位的 lambda 運算式中,不支援複雜布林運算式。 對於 any,請使用 or 連接子運算式;不支援 and。 針對 'all',請使用 'and' 連接所有子運算式;不支援 'or'。 | 篩選 Collection(Edm.String) 或 Collection(Edm.GeographyPoint) 類型的欄位 |
篩選字串集合的規則 篩選 GeographyPoint 集合的規則 |
| Lambda 運算式無效。 找到比較運算子 ('lt'、'le'、'gt' 或 'ge' 其中一項)。 在 lambda 運算式中,只有相等運算子允許用於對 Collection(Edm.String) 類型欄位的反覆運算。 對於「任意」,使用「x eq y」這樣的表達式。 針對所有情況,請使用 'x ne y' 或 'not (x eq y)' 格式的運算式。 | 針對類型Collection(Edm.String)的欄位進行篩選 |
篩選字串集合的規則 |
如何撰寫有效的集合篩選
寫入有效集合篩選的規則會針對每個資料類型不同。 下列各節說明規則的方式是顯示哪些篩選功能受支援、哪些篩選功能不受支援的範例:
篩選字串集合的規則
在字串集合的 Lambda 運算式內,唯一可以使用的比較運算子是 eq 和 ne。
注意
Azure AI 搜尋服務不支援字串的 lt/le/gt/ge 運算子,無論是在 Lambda 運算式內部或外部。
any 的主體只能測試是否相等,而 all 的主體只能測試不相等。
在 or 的主體中可以透過 any,而在 and 的主體中可以透過 all,來合併多個表達式。 由於 search.in 函式相當於將相等檢查與 or 合併,因此也允許在 any 的主體中。 相反地,not search.in 可用於 all 的主體中。
例如,這些運算式是被允許的:
tags/any(t: t eq 'books')tags/any(t: search.in(t, 'books, games, toys'))tags/all(t: t ne 'books')tags/all(t: not (t eq 'books'))tags/all(t: not search.in(t, 'books, games, toys'))tags/any(t: t eq 'books' or t eq 'games')tags/all(t: t ne 'books' and not (t eq 'games'))
雖然不允許下列這些運算式:
tags/any(t: t ne 'books')tags/any(t: not search.in(t, 'books, games, toys'))tags/all(t: t eq 'books')tags/all(t: search.in(t, 'books, games, toys'))tags/any(t: t eq 'books' and t ne 'games')tags/all(t: t ne 'books' or not (t eq 'games'))
篩選布林集合的規則
Edm.Boolean 類型僅支援 eq 和 ne 運算子。 因此,若允許使用 and/or 組合檢查同一個範圍變數的這類子句,就沒有太大意義,因為那樣會導致恆真式或矛盾式。
以下是允許之布林集合的一些篩選範例:
flags/any(f: f)flags/all(f: f)flags/any(f: f eq true)flags/any(f: f ne true)flags/all(f: not f)flags/all(f: not (f eq true))
不同於字串集合,布林集合對哪些運算子可以用於哪一種 Lambda 運算式類型沒有限制。
eq 和 ne 都可以在 any 或 all 的主體中使用。
不允許在布林值集合中使用以下運算式:
flags/any(f: f or not f)flags/any(f: f or f)flags/all(f: f and not f)flags/all(f: f and f eq true)
篩選 GeographyPoint 集合的規則
集合中 Edm.GeographyPoint 類型的值無法彼此直接比較。 而是必須當做 geo.distance 和 geo.intersects 函式的參數使用。
geo.distance 函式必須接著使用其中一個比較運算子 lt、le、gt 或 ge 來比較距離值。 這些規則也適用於非集合 Edm.GeographyPoint 欄位。
就像字串集合一樣,Edm.GeographyPoint 集合對於如何使用地理空間函式,以及在不同類型的 Lambda 運算式中合併,也有一些規則:
- 您可以搭配
geo.distance函式使用的比較運算子取決於 Lambda 運算式的類型。 針對any,您只能使用lt或le。 針對all,您只能使用gt或ge。 您可以否定涉及geo.distance的運算式,但是您必須變更比較運算子 (geo.distance(...) lt x變成not (geo.distance(...) ge x)以及geo.distance(...) le x變成not (geo.distance(...) gt x))。 - 在
all的主體中,geo.intersects函式必須被否定。 相反地,在any的主體中,geo.intersects函式不應被否定。 - 在
any的主體中,可以使用or來結合地理空間運算式。 在all的主體中,可以使用and來結合此類運算式。
上述限制存在,原因類似字串集合的相等/不相等限制。 如需這些原因的詳細資訊,請參閱了解 Azure AI 搜尋服務中的 OData 集合篩選條件。
以下是允許之 Edm.GeographyPoint 集合的一些篩選範例:
locations/any(l: geo.distance(l, geography'POINT(-122 49)') lt 10)locations/any(l: not (geo.distance(l, geography'POINT(-122 49)') ge 10) or geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))locations/all(l: geo.distance(l, geography'POINT(-122 49)') ge 10 and not geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))
不允許在Edm.GeographyPoint集合中使用以下類似的運算式:
locations/any(l: l eq geography'POINT(-122 49)')locations/any(l: not geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))locations/all(l: geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))locations/any(l: geo.distance(l, geography'POINT(-122 49)') gt 10)locations/all(l: geo.distance(l, geography'POINT(-122 49)') lt 10)locations/any(l: geo.distance(l, geography'POINT(-122 49)') lt 10 and geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))locations/all(l: geo.distance(l, geography'POINT(-122 49)') le 10 or not geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))
篩選可比較集合的規則
本節適用於下列所有資料類型:
Collection(Edm.DateTimeOffset)Collection(Edm.Double)Collection(Edm.Int32)Collection(Edm.Int64)
例如 Edm.Int32 和 Edm.DateTimeOffset 的類型支援所有六個比較運算子:eq、ne、lt、le、gt 和 ge。 對這些類型之集合的 lambda 運算式,可以包含使用任何這些運算子的簡單運算式。 這同時適用於 any 與 all。 例如,允許這些篩選:
ratings/any(r: r ne 5)dates/any(d: d gt 2017-08-24T00:00:00Z)not margins/all(m: m eq 3.5)
不過,在 Lambda 運算式內,這類比較運算式如何合併成更複雜的運算式有一些限制:
-
any的規則:簡單不相等運算式無法與其他任何運算式搭配使用。 例如,允許此運算式:
ratings/any(r: r ne 5)
但此表達式不是:
ratings/any(r: r ne 5 and r gt 2)
雖然允許此運算式,但是因為條件重疊,所以並不實用:
ratings/any(r: r ne 5 or r gt 7)
涉及
eq、lt、le、gt或ge的簡單比較運算式,可以與and/or合併。 例如:ratings/any(r: r gt 2 and r le 5)ratings/any(r: r le 5 or r gt 7)
使用
and(連接詞) 合併的比較表達式可以使用or進一步進行合併。 這個形式在布林邏輯中稱為「析取範式」(DNF)。 例如:ratings/any(r: (r gt 2 and r le 5) or (r gt 7 and r lt 10))
-
all的規則:簡單相等運算式無法與其他任何運算式搭配使用。 例如,允許此運算式:
ratings/all(r: r eq 5)
但此表達式不是:
ratings/all(r: r eq 5 or r le 2)
雖然允許此運算式,但是因為條件重疊,所以並不實用:
ratings/all(r: r eq 5 and r le 7)
涉及
ne、lt、le、gt或ge的簡單比較運算式,可以與and/or合併。 例如:ratings/all(r: r gt 2 and r le 5)ratings/all(r: r le 5 or r gt 7)
以
or組合的比較運算式 (析取),可進一步使用and組合。 這個形式在布林邏輯中稱為「合取範式」(CNF)。 例如:ratings/all(r: (r le 2 or r gt 5) and (r lt 7 or r ge 10))
篩選複雜集合的規則
複雜集合的 Lambda 運算式,相較於基本類型集合的 Lambda 運算式,支援更有彈性的語法。 您可以在這類 Lambda 運算式內使用可在外部使用的任何篩選建構,但是只有兩個例外狀況。
首先,Lambda 運算式內不支援 search.ismatch 和 search.ismatchscoring 函式。 如需詳細資訊,請參閱了解 Azure AI 搜尋服務中的 OData 集合篩選條件。
其次,不允許參考未繫結至範圍變數 (所謂的自由變數) 的欄位。 例如,請考慮下列兩個對等的 OData 篩選運算式:
stores/any(s: s/amenities/any(a: a eq 'parking')) and details/margin gt 0.5stores/any(s: s/amenities/any(a: a eq 'parking' and details/margin gt 0.5))
允許第一個運算式,但是拒絕第二個形式,因為 details/margin 未繫結至範圍變數 s。
此規則也延伸適用於在外部範圍中繫結變數的運算式。 這類變數在出現範圍方面是自由的。 例如,允許第一個運算式,但是不允許第二個對等運算式,因為 s/name 在範圍變數 a 的範圍方面是自由的:
stores/any(s: s/amenities/any(a: a eq 'parking') and s/name ne 'Flagship')stores/any(s: s/amenities/any(a: a eq 'parking' and s/name ne 'Flagship'))
這項限制不應該是實務上的問題,因為一律可以建構篩選,讓 Lambda 運算式只包含繫結變數。
資料集篩選規則的速查表
下表摘要說明針對每個集合資料類型建構有效篩選的規則。
| 資料類型 | 使用 any 的 Lambda 運算式所允許的功能 |
使用 all 的 Lambda 運算式所允許的功能 |
|---|---|---|
Collection(Edm.ComplexType) |
search.ismatch 和 search.ismatchscoring 以外的一切 |
相同 |
Collection(Edm.String) |
使用 eq 或 search.in 的比較 將子運算式結合起來使用 or |
使用 ne 或 not search.in() 的比較 將子運算式結合起來使用 and |
Collection(Edm.Boolean) |
使用 eq 或 ne 的比較 |
相同 |
Collection(Edm.GeographyPoint) |
使用 geo.distance 搭配 lt 或 le geo.intersects 將子運算式結合起來使用 or |
使用 geo.distance 搭配 gt 或 ge not geo.intersects(...) 將子運算式結合起來使用 and |
Collection(Edm.DateTimeOffset)、Collection(Edm.Double)、Collection(Edm.Int32)、Collection(Edm.Int64) |
使用 eq、ne、lt、gt、le 或 ge 的比較 使用 or 將比較與其他子運算式組合 使用 ne 將比較 (除 and 以外) 與其他子運算式組合 以 and 和 or 組合的運算式,採用析取正規形式 (DNF) |
使用 eq、ne、lt、gt、le 或 ge 的比較 使用 and 將比較與其他子運算式組合 使用 eq 將比較 (除 or 以外) 與其他子運算式組合 以 and 和 or 組合的運算式,採用合取正規形式 (CNF) |
如需如何為每個案例建構有效篩選的範例,請參閱如何撰寫有效的集合篩選。
如果您經常撰寫篩選條件,比起單純記憶,了解基本原理的規則會對您更有幫助,請參閱了解 Azure AI 搜尋服務中的 OData 集合篩選條件。