針對 Azure AI 搜尋中的 OData 集合篩選進行疑難解答
若要 篩選 Azure AI 搜尋中的集合欄位,您可以使用 any
和 all
運算元 搭配 Lambda 運算式。 Lambda 運算式是套用至集合每個元素的子篩選。
並非所有篩選表達式的功能都可以在 Lambda 運算式內使用。 根據您想要篩選的集合欄位數據類型,有哪些功能可用。 如果您嘗試在該內容中不支援的 Lambda 運算式中使用功能,這可能會導致錯誤。 如果您在嘗試在集合欄位上撰寫複雜的篩選時遇到這類錯誤,本文將協助您針對問題進行疑難解答。
常見的集合篩選錯誤
下表列出您嘗試執行集合篩選時可能會遇到的錯誤。 當您使用 Lambda 運算式內不支援的篩選表示式功能時,就會發生這些錯誤。 每個錯誤都會提供一些指引,說明如何重寫篩選,以避免發生錯誤。 此數據表也包含本文相關區段的連結,提供有關如何避免該錯誤的詳細資訊。
錯誤訊息 | 情況 | 詳細資料 |
---|---|---|
函式 ismatch 沒有係結至範圍變數 's' 的參數。 Lambda 運算式內僅支持系結字段參考('any' 或 'all')。 不過,您可以變更篩選條件,讓函 ismatch 式位於 Lambda 表達式之外,然後再試一次。 |
在 Lambda 運算式內使用 search.ismatch 或search.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 運算式內,唯一可以使用的比較運算符是 eq
和 ne
。
注意
Azure AI 搜尋不支援lt
le
/gt
ge
//字串的運算符,無論是在 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 表達式。 eq
和 ne
都可以在 或all
的any
主體中使用。
布林集合不允許如下的運算式:
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.intersects
函geo.distance
式的參數使用。 函 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)
涉及 、、、
le
或的簡單比較表示式可以與and
/or
結合。eq
ge
gt
lt
例如: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
結合。ne
ge
gt
lt
例如: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 篩選表示式:
stores/any(s: s/amenities/any(a: a eq 'parking')) and details/margin gt 0.5
stores/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 表達式只包含系結變數。
收集篩選規則的速查表
下表摘要說明針對每個集合數據類型建構有效篩選的規則。
資料類型 | Lambda 運算式中允許的功能 any |
Lambda 運算式中允許的功能 all |
---|---|---|
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) |
搭配 lt 或使用geo.distance le geo.intersects 結合子表達式與 or |
搭配 gt 或使用geo.distance 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 使用與 or 分離法線形式組合的and 表示式 (DNF) |
使用eq 、、ne 、lt gt 、 le 或的比較ge 使用 結合與其他子表達式的比較 and 使用 與其他子表達式結合比較除外 eq or 使用 與 or 結合法型組合and 的表示式 (CNF) |
如需如何為每個案例建構有效篩選的範例,請參閱 如何撰寫有效的集合篩選。
如果您經常撰寫篩選,並了解來自第一個原則的規則,可協助您不只是記住它們,請參閱 瞭解 Azure AI 搜尋中的 OData 集合篩選器。