Rozwiązywanie problemów z filtrami kolekcji OData w usłudze Azure AI Search
Aby filtrować pola kolekcji w usłudze Azure AI Search, można używaćany
operatorów i all
wraz z wyrażeniami lambda. Wyrażenie lambda to filtr podrzędny stosowany do każdego elementu kolekcji.
Nie każda funkcja wyrażeń filtru jest dostępna wewnątrz wyrażenia lambda. Dostępne funkcje różnią się w zależności od typu danych pola kolekcji, które chcesz filtrować. Może to spowodować błąd, jeśli spróbujesz użyć funkcji w wyrażeniu lambda, które nie jest obsługiwane w tym kontekście. Jeśli występują takie błędy podczas próby zapisania złożonego filtru w polach kolekcji, ten artykuł pomoże Ci rozwiązać problem.
Typowe błędy filtru kolekcji
W poniższej tabeli wymieniono błędy, które mogą wystąpić podczas próby wykonania filtru kolekcji. Te błędy występują, gdy używasz funkcji wyrażeń filtru, które nie są obsługiwane w wyrażeniu lambda. Każdy błąd zawiera wskazówki dotyczące sposobu ponownego zapisywania filtru, aby uniknąć błędu. Tabela zawiera również link do odpowiedniej sekcji tego artykułu, która zawiera więcej informacji na temat tego, jak uniknąć tego błędu.
Komunikat o błędzie | Sytuacja | Szczegóły |
---|---|---|
Funkcja ismatch nie ma parametrów powiązanych ze zmienną zakresu "s". Tylko odwołania do pól powiązanych są obsługiwane wewnątrz wyrażeń lambda ("any" lub "all"). Można jednak zmienić filtr tak, aby ismatch funkcja wykraczała poza wyrażenie lambda i spróbuj ponownie. |
Używanie search.ismatch wyrażenia lambda lub search.ismatchscoring wewnątrz niej |
Reguły filtrowania złożonych kolekcji |
Nieprawidłowe wyrażenie lambda. Znaleziono test równości lub nierówności, w którym oczekiwano przeciwieństwa w wyrażeniu lambda, które iteruje nad polem typu Collection(Edm.String). W przypadku elementu "any" użyj wyrażeń formularza "x eq y" lub "search.in(...)". W przypadku elementu "all" użyj wyrażeń formularza "x ne y", "nie (x eq y)" lub "nie search.in(...)". | Filtrowanie według pola typu Collection(Edm.String) |
Reguły filtrowania kolekcji ciągów |
Nieprawidłowe wyrażenie lambda. Znaleziono nieobsługiwaną formę złożonego wyrażenia logicznego. W przypadku elementu "any" należy użyć wyrażeń, które są "regułami ściągnięcia anD", nazywanymi również formą normalną odciętą. Na przykład: (a and b) or (c and d) gdzie wartości a, b, c i d to porównanie lub podwyrażenia równości. W przypadku elementu "all" użyj wyrażeń, które są "anDs of ORs", nazywane również formą normalną conjunctive. Na przykład: (a or b) and (c or d) gdzie wartości a, b, c i d są porównywane lub podwyrażenia nierówności. Przykłady wyrażeń porównania: "x gt 5", "x le 2". Przykład wyrażenia równości: "x eq 5". Przykład wyrażenia nierówności: "x ne 5". |
Filtrowanie pól typu Collection(Edm.DateTimeOffset) , Collection(Edm.Double) , Collection(Edm.Int32) lub Collection(Edm.Int64) |
Reguły filtrowania porównywalnych kolekcji |
Nieprawidłowe wyrażenie lambda. Znaleziono nieobsługiwane użycie obiektu geo.distance() lub geo.intersects() w wyrażeniu lambda, które iteruje nad polem typu Collection(Edm.GeographyPoint). W przypadku elementu "any" upewnij się, że porównasz operatory geo.distance() przy użyciu operatorów "lt" lub "le" i upewnij się, że użycie obiektu geo.intersects() nie jest negowane. W przypadku parametru "all" upewnij się, że porównasz operatory geo.distance() przy użyciu operatorów "gt" lub "ge" i upewnij się, że dowolne użycie obiektu geo.intersects() jest negowane. | Filtrowanie według pola typu Collection(Edm.GeographyPoint) |
Reguły filtrowania kolekcji GeographyPoint |
Nieprawidłowe wyrażenie lambda. Wyrażenia logiczne złożone nie są obsługiwane w wyrażeniach lambda, które iterują pola typu Collection(Edm.GeographyPoint). W przypadku elementu "any" sprzężenia podrzędne z wyrazem "or"; Polecenie "i" nie jest obsługiwane. W przypadku elementu "all" dołącz podexpressions z wyrazem "and"; Opcja "lub" nie jest obsługiwana. | Filtrowanie pól typu Collection(Edm.String) lub Collection(Edm.GeographyPoint) |
Reguły filtrowania kolekcji ciągów Reguły filtrowania kolekcji GeographyPoint |
Nieprawidłowe wyrażenie lambda. Znaleziono operator porównania (jeden z "lt", "le", "gt" lub "ge"). Tylko operatory równości są dozwolone w wyrażeniach lambda, które iterują pola typu Collection(Edm.String). W przypadku "any" wyrażenia se formularza "x eq y". W przypadku elementu "all" użyj wyrażeń formularza "x ne y" lub "nie (x eq y)". | Filtrowanie według pola typu Collection(Edm.String) |
Reguły filtrowania kolekcji ciągów |
Jak napisać prawidłowe filtry kolekcji
Reguły pisania prawidłowych filtrów kolekcji są różne dla każdego typu danych. W poniższych sekcjach opisano reguły, pokazując przykłady obsługiwanych funkcji filtru i które nie są:
- Reguły filtrowania kolekcji ciągów
- Reguły filtrowania kolekcji logicznych
- Reguły filtrowania kolekcji GeographyPoint
- Reguły filtrowania porównywalnych kolekcji
- Reguły filtrowania złożonych kolekcji
Reguły filtrowania kolekcji ciągów
Wewnątrz wyrażeń lambda dla kolekcji ciągów jedynymi operatorami porównania, których można użyć, są eq
i ne
.
Uwaga
Usługa Azure AI Search nie obsługuje lt
gt
ge
/le
//operatorów dla ciągów, zarówno wewnątrz, jak i poza wyrażeniem lambda.
Treść obiektu any
może testować tylko pod kątem równości, podczas gdy treść obiektu może testować tylko pod kątem all
nierówności.
Istnieje również możliwość połączenia wielu wyrażeń za pomocą w or
treści elementu any
i w and
treści obiektu all
. Ponieważ funkcja jest równoważna search.in
połączeniu kontroli równości z elementem or
, jest również dozwolona w treści elementu any
. Z drugiej strony, not search.in
jest dozwolony w treści obiektu all
.
Na przykład te wyrażenia są dozwolone:
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'))
Chociaż te wyrażenia nie są dozwolone:
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'))
Reguły filtrowania kolekcji logicznych
Typ Edm.Boolean
obsługuje tylko operatory eq
i ne
. W związku z tym nie ma sensu, aby umożliwić łączenie takich klauzul, które sprawdzają tę samą zmienną zakresu, and
/or
ponieważ zawsze prowadziłoby to do tautologii lub sprzeczności.
Oto kilka przykładów filtrów dla kolekcji logicznych, które są dozwolone:
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))
W przeciwieństwie do kolekcji ciągów kolekcje logiczne nie mają limitów, dla których operator może być używany w jakim typie wyrażenia lambda. Oba eq
elementy i ne
mogą być używane w treści obiektu any
lub all
.
Wyrażenia, takie jak następujące, nie są dozwolone dla kolekcji logicznych:
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)
Reguły filtrowania kolekcji GeographyPoint
Wartości typu Edm.GeographyPoint
w kolekcji nie mogą być porównywane bezpośrednio ze sobą. Zamiast tego należy ich używać jako parametrów funkcji geo.distance
i geo.intersects
. Funkcja geo.distance
z kolei musi być porównywana z wartością odległości przy użyciu jednego z operatorów lt
porównania , , le
gt
lub ge
. Te reguły dotyczą również pól Edm.GeographyPoint.
Podobnie jak kolekcje ciągów, Edm.GeographyPoint
kolekcje mają pewne reguły dotyczące sposobu użycia i łączenia funkcji geoprzestrzeniowych w różnych typach wyrażeń lambda:
- Których operatorów porównania można używać z funkcją
geo.distance
, zależy od typu wyrażenia lambda. W przypadkuany
programu można użyć tylkolt
luble
. W przypadkuall
programu można użyć tylkogt
lubge
. Można negować wyrażenia obejmującegeo.distance
element , ale musisz zmienić operator porównania (geo.distance(...) lt x
staje sięnot (geo.distance(...) ge x)
igeo.distance(...) le x
staje sięnot (geo.distance(...) gt x)
). - W treści
all
geo.intersects
obiektu funkcja musi być negowana. Z drugiej strony, w treściany
funkcji funkcjageo.intersects
nie może być negowana. - W treści wyrażenia
any
geoprzestrzewne można łączyć za pomocą poleceniaor
. W treści elementuall
można połączyć takie wyrażenia przy użyciu poleceniaand
.
Powyższe ograniczenia istnieją z podobnych powodów, jak ograniczenie równości/nierówności w kolekcjach ciągów. Zobacz Understanding OData collection filters in Azure AI Search (Omówienie filtrów kolekcji OData w usłudze Azure AI Search ), aby dowiedzieć się więcej na ten temat.
Oto kilka przykładów filtrów Edm.GeographyPoint
dla kolekcji, które są dozwolone:
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))'))
Wyrażenia, takie jak następujące, nie są dozwolone dla Edm.GeographyPoint
kolekcji:
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))'))
Reguły filtrowania porównywalnych kolekcji
Ta sekcja dotyczy wszystkich następujących typów danych:
Collection(Edm.DateTimeOffset)
Collection(Edm.Double)
Collection(Edm.Int32)
Collection(Edm.Int64)
Typy, takie jak Edm.Int32
i obsługują wszystkie sześć operatorów porównania: eq
, , ne
, le
lt
, gt
, i ge
.Edm.DateTimeOffset
Wyrażenia lambda dla kolekcji tych typów mogą zawierać proste wyrażenia przy użyciu dowolnego z tych operatorów. Dotyczy to zarówno elementów , jak any
i all
. Na przykład te filtry są dozwolone:
ratings/any(r: r ne 5)
dates/any(d: d gt 2017-08-24T00:00:00Z)
not margins/all(m: m eq 3.5)
Istnieją jednak ograniczenia dotyczące sposobu łączenia takich wyrażeń porównania w bardziej złożone wyrażenia wewnątrz wyrażenia lambda:
- Reguły dla elementu
any
:Proste wyrażenia nierówności nie mogą być przydatne w połączeniu z innymi wyrażeniami. Na przykład to wyrażenie jest dozwolone:
ratings/any(r: r ne 5)
ale to wyrażenie nie jest następujące:
ratings/any(r: r ne 5 and r gt 2)
i chociaż to wyrażenie jest dozwolone, nie jest przydatne, ponieważ warunki nakładają się na siebie:
ratings/any(r: r ne 5 or r gt 7)
Proste wyrażenia porównania obejmujące , , , lub mogą być łączone z
and
or
/.ge
gt
le
lt
eq
Na przykład:ratings/any(r: r gt 2 and r le 5)
ratings/any(r: r le 5 or r gt 7)
Wyrażenia porównania połączone z
and
(połączeniami) można dodatkowo łączyć przy użyciu poleceniaor
. Ten formularz jest znany w logice logicznej jako "Disjunctive Normal Form" (DNF). Na przykład:ratings/any(r: (r gt 2 and r le 5) or (r gt 7 and r lt 10))
- Reguły dla elementu
all
:Proste wyrażenia równości nie mogą być przydatne w połączeniu z innymi wyrażeniami. Na przykład to wyrażenie jest dozwolone:
ratings/all(r: r eq 5)
ale to wyrażenie nie jest następujące:
ratings/all(r: r eq 5 or r le 2)
i chociaż to wyrażenie jest dozwolone, nie jest przydatne, ponieważ warunki nakładają się na siebie:
ratings/all(r: r eq 5 and r le 7)
Proste wyrażenia porównania obejmujące , , , lub mogą być łączone z
and
or
/.ge
gt
le
lt
ne
Na przykład:ratings/all(r: r gt 2 and r le 5)
ratings/all(r: r le 5 or r gt 7)
Wyrażenia porównania połączone z
or
(dysjunctions) można dodatkowo łączyć przy użyciu poleceniaand
. Ten formularz jest znany w logice logicznej jako "Conjunctive Normal Form" (CNF). Na przykład:ratings/all(r: (r le 2 or gt 5) and (r lt 7 or r ge 10))
Reguły filtrowania złożonych kolekcji
Wyrażenia lambda w złożonych kolekcjach obsługują znacznie bardziej elastyczną składnię niż wyrażenia lambda w kolekcjach typów pierwotnych. Można użyć dowolnej konstrukcji filtru wewnątrz takiego wyrażenia lambda, którego można użyć poza jednym, z tylko dwoma wyjątkami.
Najpierw funkcje search.ismatch
i search.ismatchscoring
nie są obsługiwane wewnątrz wyrażeń lambda. Aby uzyskać więcej informacji, zobacz Understanding OData collection filters in Azure AI Search (Omówienie filtrów kolekcji OData w usłudze Azure AI Search).
Po drugie, odwoływanie się do pól, które nie są powiązane ze zmienną zakresu (tzw . zmiennych wolnych) nie jest dozwolone. Rozważmy na przykład następujące dwa równoważne wyrażenia filtru 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))
Pierwsze wyrażenie jest dozwolone, podczas gdy drugi formularz jest odrzucany, ponieważ details/margin
nie jest powiązany ze zmienną s
zakresu .
Ta reguła rozszerza się również na wyrażenia, które mają zmienne powiązane w zakresie zewnętrznym. Takie zmienne są wolne w odniesieniu do zakresu, w którym się pojawiają. Na przykład pierwsze wyrażenie jest dozwolone, podczas gdy drugie równoważne wyrażenie jest niedozwolone, ponieważ s/name
jest wolne w odniesieniu do zakresu zmiennej a
zakresu :
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'))
To ograniczenie nie powinno być problemem w praktyce, ponieważ zawsze jest możliwe konstruowanie filtrów, tak aby wyrażenia lambda zawierały tylko zmienne powiązane.
Ściągawka dotycząca reguł filtrowania kolekcji
Poniższa tabela zawiera podsumowanie reguł konstruowania prawidłowych filtrów dla każdego typu danych kolekcji.
Typ danych | Funkcje dozwolone w wyrażeniach lambda z any |
Funkcje dozwolone w wyrażeniach lambda z all |
---|---|---|
Collection(Edm.ComplexType) |
Wszystko z wyjątkiem search.ismatch i search.ismatchscoring |
To samo |
Collection(Edm.String) |
Porównania z lub eq search.in Łączenie wyrażeń podrzędnych z or |
Porównania z lub ne not search.in() Łączenie wyrażeń podrzędnych z and |
Collection(Edm.Boolean) |
Porównania z lub eq ne |
To samo |
Collection(Edm.GeographyPoint) |
Używanie z geo.distance programem lt lub le geo.intersects Łączenie wyrażeń podrzędnych z or |
Używanie z geo.distance programem gt lub ge not geo.intersects(...) Łączenie wyrażeń podrzędnych z and |
Collection(Edm.DateTimeOffset) , , Collection(Edm.Double) , , Collection(Edm.Int32) Collection(Edm.Int64) |
Porównania przy użyciu poleceń eq , , ne lt , gt , le lubge Łączenie porównań z innymi wyrażeniami podrzędnymi przy użyciu or Łączenie porównań z wyjątkiem ne innych wyrażeń podrzędnych przy użyciu and Wyrażenia używające kombinacji and i or w postaci normalnej odsuwanej (DNF) |
Porównania przy użyciu poleceń eq , , ne lt , gt , le lubge Łączenie porównań z innymi wyrażeniami podrzędnymi przy użyciu and Łączenie porównań z wyjątkiem eq innych wyrażeń podrzędnych przy użyciu or Wyrażenia używające kombinacji and i or w postaci normalnej conjunctive (CNF) |
Przykłady tworzenia prawidłowych filtrów dla każdego przypadku można znaleźć w temacie How to write valid collection filters (Jak pisać prawidłowe filtry kolekcji).
Jeśli często piszesz filtry i rozumiesz reguły z pierwszych zasad, zobacz Omówienie filtrów kolekcji OData w usłudze Azure AI Search.