分享方式:


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

若要篩選 Azure AI 搜尋服務上的集合欄位,您可使用 anyall 運算子搭配 Lambda 運算式。 Lambda 運算式是套用至集合中每個元素的子篩選。

並非所有篩選條件運算式的功能都可以在 Lambda 運算式內使用。 哪些功能可用會根據您想要篩選的集合欄位資料類型而有所不同。 如果您嘗試在該內容中不支援的 Lambda 運算式中使用功能,這可能會導致錯誤。 如果您在嘗試對集合欄位撰寫複雜篩選時遇到這類錯誤,本文可協助您針對問題進行疑難排解。

常見的集合篩選錯誤

下表列出嘗試執行集合篩選時可能會遇到的錯誤。 當您使用 Lambda 運算式內不支援的篩選運算式功能時,就會發生這些錯誤。 每個錯誤都會提供一些指導,說明如何重寫篩選,以避免發生錯誤。 下表也包含本文相關章節的連結,提供如何避免該錯誤的詳細資訊。

錯誤訊息 情況 詳細資料
函式 ismatch 沒有繫結至範圍變數 's' 的參數。 Lambda 運算式內僅支援繫結欄位參考 ('any' 或 'all')。 不過,您可以變更您的篩選,讓 ismatch 函式在 Lambda 運算式之外,然後再試一次。 在 Lambda 運算式內使用 search.ismatchsearch.ismatchscoring 篩選複雜集合的規則
不正確 Lambda 運算式。 找到在 Lambda 運算式中預期相等或不相等的測試,該運算式會逐一查看 Collection(Edm.String) 類型的欄位。 針對 'any',請使用 'x eq y' 或 'search.in (...)' 格式的運算式。 針對 'all',請使用 'x ne y'、'not (x eq y)' 或 'not search.in(...)' 格式的運算式。 篩選 Collection(Edm.String) 類型的欄位 篩選字串集合的規則
不正確 Lambda 運算式。 找到不受支援的複雜布林運算式形式。 針對 'any',請使用 'ORs of ANDs' 的運算式,也稱為析取範式。 例如:(a and b) or (c and d),其中 a、b、c 和 d 是比較或等式子運算式。 針對 'all',請使用 'ANDs of ORs' 的運算式,也稱為合取範式。 例如:(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 運算式。 在 Lambda 運算式中找到不支援使用 geo.distance() 或 geo.intersects(),該運算式會逐一查看 Collection(Edm.GeographyPoint) 類型的欄位。 針對 'any',請務必使用 'lt' 或 'le' 運算子來比較 geo.distance(),並且確定未否定 geo.intersects() 的任何使用方式。 針對 'all',請務必使用 'gt' 或 'ge' 運算子來比較 geo.distance(),並且確定否定 geo.intersects() 的任何使用方式。 篩選 Collection(Edm.GeographyPoint) 類型的欄位 篩選 GeographyPoint 集合的規則
不正確 Lambda 運算式。 複雜布林運算式在 Lambda 運算式中不受支援,該運算式會逐一查看 Collection(Edm.GeographyPoint) 類型的欄位。 針對 'any',請使用 'or' 聯結子運算式;不支援 'and'。 針對 'all',請使用 'and' 聯結子運算式;不支援 'or'。 篩選 Collection(Edm.String)Collection(Edm.GeographyPoint) 類型的欄位 篩選字串集合的規則

篩選 GeographyPoint 集合的規則
不正確 Lambda 運算式。 找到比較運算子 ('lt'、'le'、'gt' 或 'ge' 其中一項)。 Lambda 運算式中只允許相等運算子,其會逐一查看 Collection(Edm.String) 類型的欄位。 針對 'any',請使用 'x eq y' 格式的運算式。 針對 'all',請使用 'x ne y' 或 'not (x eq y)' 格式的運算式。 篩選 Collection(Edm.String) 類型的欄位 篩選字串集合的規則

如何撰寫有效的集合篩選

寫入有效集合篩選的規則會針對每個資料類型不同。 下列各節說明規則的方式是顯示哪些篩選功能受支援、哪些篩選功能不受支援的範例:

篩選字串集合的規則

在字串集合的 Lambda 運算式內,唯一可以使用的比較運算子是 eqne

注意

Azure AI 搜尋服務不支援字串的 lt/le/gt/ge 運算子,無論是在 Lambda 運算式內部或外部。

any 的主體只能測試是否相等,而 all 的主體只能測試不相等。

您也可以透過 any 的主體中的 or,以及透過 all 的主體中的 and,合併多個運算式。 由於 search.in 函式相當於將相等檢查與 or 合併,因此也允許在 any 的主體中。 相反地,在 all 的主體中允許 not search.in

例如,允許這些運算式:

  • 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 類型僅支援 eqne 運算子。 因此,允許合併檢查相同範圍變數的這類子句與 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 運算式類型沒有限制。 eqne 都可以在 anyall 的主體中使用。

布林集合不允許下列運算式:

  • 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.distancegeo.intersects 函式的參數使用。 geo.distance 函式必須接著使用其中一個比較運算子 ltlegtge 來比較距離值。 這些規則也適用於非集合 Edm.GeographyPoint 欄位。

就像字串集合一樣,Edm.GeographyPoint 集合對於如何使用地理空間函式,以及在不同類型的 Lambda 運算式中合併,也有一些規則:

  • 您可以搭配 geo.distance 函式使用的比較運算子取決於 Lambda 運算式的類型。 針對 any,您只能使用 ltle。 針對 all,您只能使用 gtge。 您可以否定涉及 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.Int32Edm.DateTimeOffset 的類型支援所有六個比較運算子:eqneltlegtge。 這些類型集合的 Lambda 運算式可以使用任何運算子來包含簡單運算式。 這同時適用於 anyall。 例如,允許這些篩選:

  • 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)
    • 涉及 eqltlegtge 的簡單比較運算式,可以與 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)
    • 涉及 neltlegtge 的簡單比較運算式,可以與 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 gt 5) and (r lt 7 or r ge 10))

篩選複雜集合的規則

複雜集合的 Lambda 運算式,相較於基本類型集合的 Lambda 運算式,支援更有彈性的語法。 您可以在這類 Lambda 運算式內使用可在外部使用的任何篩選建構,但是只有兩個例外狀況。

首先,Lambda 運算式內不支援 search.ismatchsearch.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.ismatchsearch.ismatchscoring 以外的一切 相同
Collection(Edm.String) 使用 eqsearch.in 的比較

結合子運算式與 or
使用 nenot search.in() 的比較

結合子運算式與 and
Collection(Edm.Boolean) 使用 eqne 的比較 相同
Collection(Edm.GeographyPoint) 使用 geo.distance 搭配 ltle

geo.intersects

結合子運算式與 or
使用 geo.distance 搭配 gtge

not geo.intersects(...)

結合子運算式與 and
Collection(Edm.DateTimeOffset), Collection(Edm.Double), Collection(Edm.Int32), Collection(Edm.Int64) 使用 eqneltgtlege 的比較

使用 or 結合與其他子運算式的比較

使用 and 結合 ne 以外的其他子運算式的比較

析取範式 (DNF) 中合併使用 andor 的運算式
使用 eqneltgtlege 的比較

使用 and 結合與其他子運算式的比較

使用 or 結合 eq 以外的其他子運算式的比較

合取範式 (CNF) 中合併使用 andor 的運算式

如需如何為每個案例建構有效篩選的範例,請參閱如何撰寫有效的集合篩選

如果您經常撰寫篩選,並了解第一個原則的規則可協助您記住,請參閱了解 Azure AI 搜尋服務中的 OData 集合篩選條件

下一步