Udostępnij za pośrednictwem


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

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 ltgtge/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 anyi 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 ltporównania , , legtlub 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 przypadku anyprogramu można użyć tylko lt lub le. W przypadku allprogramu można użyć tylko gt lub ge. Można negować wyrażenia obejmujące geo.distanceelement , ale musisz zmienić operator porównania (geo.distance(...) lt x staje się not (geo.distance(...) ge x) i geo.distance(...) le x staje się not (geo.distance(...) gt x)).
  • W treści allgeo.intersects obiektu funkcja musi być negowana. Z drugiej strony, w treści anyfunkcji funkcja geo.intersects nie może być negowana.
  • W treści wyrażenia anygeoprzestrzewne można łączyć za pomocą polecenia or. W treści elementu allmożna połączyć takie wyrażenia przy użyciu polecenia and.

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, lelt, 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 andor/.ge gtlelteq 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 polecenia or. 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 andor/.ge gtleltne 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 polecenia and. 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:

  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))

Pierwsze wyrażenie jest dozwolone, podczas gdy drugi formularz jest odrzucany, ponieważ details/margin nie jest powiązany ze zmienną szakresu .

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 azakresu :

  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'))

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 eqsearch.in

Łączenie wyrażeń podrzędnych z or
Porównania z lub nenot search.in()

Łączenie wyrażeń podrzędnych z and
Collection(Edm.Boolean) Porównania z lub eqne 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, , nelt, gt, lelubge

Łą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, , nelt, gt, lelubge

Łą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.

Następne kroki