針對 Azure AI 搜尋服務中的 OData 集合篩選條件進行疑難排解

注意

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 篩選運算式:

  1. stores/any(s: s/amenities/any(a: a eq 'parking')) and details/margin gt 0.5
  2. stores/any(s: s/amenities/any(a: a eq 'parking' and details/margin gt 0.5))

允許第一個運算式,但是拒絕第二個形式,因為 details/margin 未繫結至範圍變數 s。

此規則也延伸適用於在外部範圍中繫結變數的運算式。 這類變數在出現範圍方面是自由的。 例如,允許第一個運算式,但是不允許第二個對等運算式,因為 s/name 在範圍變數 a 的範圍方面是自由的:

  1. stores/any(s: s/amenities/any(a: a eq 'parking') and s/name ne 'Flagship')
  2. 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 集合篩選條件。

下一步