針對 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',請使用 'OR of AND' 的表達式,也稱為「分離法線形式」。 例如: (a and b) or (c and d) 其中 a、b、c 和 d 是比較或相等子表達式。 針對 'all',請使用 'AND 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.Double)Collection(Edm.Int32)或類型的Collection(Edm.DateTimeOffset)欄位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』 格式的 se 運算式。 針對 'all',請使用 'x ne y' 或 'not(x eq y)' 格式的表達式。 篩選類型欄位 Collection(Edm.String) 篩選字串集合的規則

如何撰寫有效的集合篩選

撰寫有效集合篩選的規則對於每個數據類型都不同。 下列各節說明規則,方法是顯示支援哪些篩選功能的範例,以及哪些功能不受支援:

篩選字串集合的規則

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

注意

Azure AI 搜尋不支援ltle/gtge//字串的運算符,無論是在 Lambda 表達式內部還是外部。

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

您也可以透過 在的主體any中,以及 and 透過 在主體all中結合多個表達式or。 由於函 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 表達式。 eqne 都可以在 或allany主體中使用。

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

  • 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.intersectsgeo.distance式的參數使用。 函 geo.distance 式必須接著使用其中一個比較運算子 ltlegtge來比較距離值。 這些規則也適用於非收集區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))。
  • 在 的主體中 allgeo.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類型支援所有六個比較運算子:eq、、neltlegtge。 這些型別集合的 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)
    • 涉及 、、、 le或的簡單比較表示式可以與 and/or結合。eqgegtlt 例如:

      • 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)
    • 涉及 、、、 le或的簡單比較表示式可以與 and/or結合。negegtlt 例如:

      • 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.ismatch Lambda 運算式內不支援 和 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 表達式只包含系結變數。

收集篩選規則的速查表

下表摘要說明針對每個集合數據類型建構有效篩選的規則。

資料類型 Lambda 運算式中允許的功能 any Lambda 運算式中允許的功能 all
Collection(Edm.ComplexType) 除了和以外的所有專案search.ismatchsearch.ismatchscoring 相同
Collection(Edm.String) eq 或的比較 search.in

結合子表達式與 or
ne 或的比較 not search.in()

結合子表達式與 and
Collection(Edm.Boolean) eq 或的比較 ne 相同
Collection(Edm.GeographyPoint) 搭配 lt 或使用geo.distancele

geo.intersects

結合子表達式與 or
搭配 gt 或使用geo.distancege

not geo.intersects(...)

結合子表達式與 and
Collection(Edm.DateTimeOffset)、 、 Collection(Edm.Double)Collection(Edm.Int32)Collection(Edm.Int64) 使用eq、、neltgtle或的比較ge

使用 結合與其他子表達式的比較 or

使用 與其他子表達式結合比較除外neand

使用與 or分離法線形式組合的and表示式 (DNF)
使用eq、、neltgtle或的比較ge

使用 結合與其他子表達式的比較 and

使用 與其他子表達式結合比較除外eqor

使用 與 or結合法型組合and的表示式 (CNF)

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

如果您經常撰寫篩選,並了解來自第一個原則的規則,可協助您不只是記住它們,請參閱 瞭解 Azure AI 搜尋中的 OData 集合篩選器。

下一步