Řešení potíží s filtry kolekcí OData ve službě Azure AI Search

Pokud chcete filtrovat pole kolekce ve službě Azure AI Search, můžete použít any operátory a all operátory společně s výrazy lambda. Výraz lambda je podfiltr, který se použije pro každý prvek kolekce.

Ne každá funkce výrazů filtru je k dispozici uvnitř výrazu lambda. Které funkce jsou k dispozici, se liší v závislosti na datovém typu pole kolekce, které chcete filtrovat. Výsledkem může být chyba, pokud se pokusíte použít funkci ve výrazu lambda, který není v tomto kontextu podporovaný. Pokud při pokusu o napsání složitého filtru polí kolekce dochází k takovým chybám, pomůže vám tento článek tento problém vyřešit.

Běžné chyby filtru kolekcí

Následující tabulka uvádí chyby, se kterými se můžete setkat při pokusu o spuštění filtru kolekce. K těmto chybám dochází při použití funkce výrazů filtru, které nejsou podporovány uvnitř výrazu lambda. Každá chyba obsahuje pokyny, jak můžete filtr přepsat, abyste se této chybě vyhnuli. Tabulka obsahuje také odkaz na příslušnou část tohoto článku, která obsahuje další informace o tom, jak se této chybě vyhnout.

Chybová zpráva Situace Detaily
Funkce ismatch nemá žádné parametry vázané na proměnnou rozsahu 's'. Uvnitř výrazů lambda ('any' nebo 'all') se podporují pouze odkazy na vázané pole. Filtr ale můžete změnit tak, aby ismatch byla funkce mimo výraz lambda a zkuste to znovu. Použití search.ismatch výrazu lambda nebo search.ismatchscoring uvnitř výrazu lambda Pravidla pro filtrování složitých kolekcí
Neplatný výraz lambda Zjistili jsme test rovnosti nebo nerovnosti, ve kterém byl v výrazu lambda očekávaný opak, který iteruje pole typu Collection(Edm.String). Pro "any" použijte výrazy ve tvaru "x eq y" nebo "search.in(...)". Pro "all" použijte výrazy ve tvaru x ne y, "not (x eq y)" nebo "ne search.in(...)". Filtrování podle pole typu Collection(Edm.String) Pravidla pro filtrování kolekcí řetězců
Neplatný výraz lambda Byla nalezena nepodporovaná forma komplexního logického výrazu. U výrazů any použijte výrazy, které jsou "ORS and", označované také jako disjunktivní normální formulář. Například: kde a (a and b) or (c and d) , b, c a a d jsou porovnání nebo podvýrazy rovnosti. Pro "vše" použijte výrazy, které jsou AND ORS, označované také jako konjunktivní normální formulář. Příklad: kde a (a or b) and (c or d) , b, c a d jsou porovnání nebo nerovnosti dílčí výrazy. Příklady porovnávacích výrazů: x gt 5, x le 2 Příklad výrazu rovnosti: x eq 5 Příklad výrazu nerovnosti: x ne 5 Filtrování podle polí typu Collection(Edm.DateTimeOffset), Collection(Edm.Double), Collection(Edm.Int32)nebo Collection(Edm.Int64) Pravidla pro filtrování srovnatelných kolekcí
Neplatný výraz lambda Zjistili jsme nepodporované použití geo.distance() nebo geo.intersects() ve výrazu lambda, který iteruje pole typu Collection(Edm.GeographyPoint). U operátoru any se ujistěte, že porovnáváte geo.distance() pomocí operátorů lt nebo le a ujistěte se, že jakékoli použití geo.intersects() není negované. V případě "all" se ujistěte, že porovnáváte geo.distance() pomocí operátorů "gt" nebo "ge" a ujistěte se, že je jakékoli použití geo.intersects() negované. Filtrování podle pole typu Collection(Edm.GeographyPoint) Pravidla pro filtrování kolekcí GeographyPoint
Neplatný výraz lambda Komplexní logické výrazy nejsou podporovány ve výrazech lambda, které iterují pole typu Collection(Edm.GeographyPoint). Pro 'any', join subexpressions with 'or'; "and" není podporováno. Pro 'all', spojit dílčí výrazy s 'a'; "nebo" není podporováno. Filtrování podle polí typu Collection(Edm.String) nebo Collection(Edm.GeographyPoint) Pravidla pro filtrování kolekcí řetězců

Pravidla pro filtrování kolekcí GeographyPoint
Neplatný výraz lambda Našli jsme relační operátor (jeden z "lt", "le", "gt" nebo "ge"). Ve výrazech lambda, které iterují pole typu Collection(Edm.String), jsou povoleny pouze operátory rovnosti. U výrazů "any" se výrazy formuláře "x eq y". Pro "all" použijte výrazy ve tvaru x ne y nebo "ne (x eq y)". Filtrování podle pole typu Collection(Edm.String) Pravidla pro filtrování kolekcí řetězců

Jak psát platné filtry kolekcí

Pravidla pro zápis platných filtrů kolekcí se pro každý datový typ liší. Následující části popisují pravidla zobrazením příkladů podporovaných funkcí filtru, které nejsou podporované:

Pravidla pro filtrování kolekcí řetězců

Uvnitř výrazů lambda pro kolekce řetězců jsou jedinými relačními operátory, které lze použít, a eq ne.

Poznámka:

Azure AI Search nepodporuje ltgtge/le//operátory pro řetězce bez ohledu na to, jestli uvnitř výrazu lambda nebo mimo ni.

Tělo any může testovat pouze rovnost, zatímco tělo může all testovat pouze nerovnost.

Je také možné zkombinovat více výrazů v or těle a anyv and těle .all Vzhledem k tomu, že search.in funkce je ekvivalentní kombinování kontrol rovnosti s or, je také povolena v těle objektu any. Naopak, not search.in je povoleno v těle all.

Například tyto výrazy jsou povolené:

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

I když tyto výrazy nejsou povolené:

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

Pravidla pro filtrování logických kolekcí

Edm.Boolean Typ podporuje pouze operátory eq a ne operátory. Proto nemá smysl povolit kombinování takových klauzulí, které kontrolují stejnou proměnnou and/or rozsahu, protože by to vždy vedlo k tautologiím nebo rozporům.

Tady je několik příkladů filtrů u logických kolekcí, které jsou povolené:

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

Na rozdíl od kolekcí řetězců nemají logické kolekce žádné omezení, pro který operátor lze použít, ve kterém typu výrazu lambda. Obě eq a ne mohou být použity v těle any nebo all.

Pro logické kolekce nejsou povolené výrazy, jako jsou například následující:

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

Pravidla pro filtrování kolekcí GeographyPoint

Hodnoty typu Edm.GeographyPoint v kolekci se nedají porovnat přímo s ostatními. Místo toho je nutné je použít jako parametry geo.distance pro funkce a geo.intersects funkce. Funkce geo.distance se pak musí porovnávat s hodnotou vzdálenosti pomocí jednoho z relačních operátorů lt, , le, gtnebo ge. Tato pravidla platí také pro jiná pole než Edm.GeographyPoint.

Podobně jako u kolekcí Edm.GeographyPoint řetězců mají kolekce určitá pravidla pro použití a kombinování geografických funkcí v různých typech výrazů lambda:

  • Které relační operátory můžete použít s geo.distance funkcí, závisí na typu výrazu lambda. Pro any, můžete použít pouze lt nebo le. Pro all, můžete použít pouze gt nebo ge. Můžete negovat výrazy zahrnující geo.distance, ale musíte změnit relační operátor (geo.distance(...) lt x stane not (geo.distance(...) ge x) se a geo.distance(...) le x stane not (geo.distance(...) gt x)).
  • V těle allfunkce geo.intersects musí být negatedována. Naopak v těle any, geo.intersects funkce nesmí být negovány.
  • V těle any, geoprostorové výrazy lze kombinovat pomocí or. V těle , alltakové výrazy lze kombinovat pomocí and.

Výše uvedená omezení existují z podobných důvodů jako omezení rovnosti/nerovnosti u kolekcí řetězců. V tématu Principy filtrů kolekcí OData ve službě Azure AI Search se podrobněji podívejte na tyto důvody.

Tady je několik příkladů filtrů u Edm.GeographyPoint kolekcí, které jsou povolené:

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

Pro kolekce nejsou povoleny Edm.GeographyPoint výrazy, jako jsou například následující:

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

Pravidla pro filtrování srovnatelných kolekcí

Tato část se vztahuje na všechny následující datové typy:

  • Collection(Edm.DateTimeOffset)
  • Collection(Edm.Double)
  • Collection(Edm.Int32)
  • Collection(Edm.Int64)

Typy jako Edm.Int32 Edm.DateTimeOffset a podporují všech šest operátorů porovnání: eq, ne, lt, le, gt, a ge. Výrazy lambda nad kolekcemi těchto typů můžou obsahovat jednoduché výrazy pomocí některého z těchto operátorů. To platí pro obě any i all. Například jsou povoleny tyto filtry:

  • ratings/any(r: r ne 5)
  • dates/any(d: d gt 2017-08-24T00:00:00Z)
  • not margins/all(m: m eq 3.5)

Existují však omezení, jak lze takové porovnávací výrazy kombinovat do složitějších výrazů uvnitř výrazu lambda:

  • Pravidla pro any:
    • Jednoduché výrazy nerovnosti se nedají užitečně kombinovat s žádnými dalšími výrazy. Tento výraz je například povolený:

      • ratings/any(r: r ne 5)

      ale tento výraz není:

      • ratings/any(r: r ne 5 and r gt 2)

      a i když je tento výraz povolený, není užitečný, protože se podmínky překrývají:

      • ratings/any(r: r ne 5 or r gt 7)
    • Jednoduché porovnávací výrazy zahrnující eq, , ltle, gt, nebo ge mohou být kombinovány s and/or. Příklad:

      • ratings/any(r: r gt 2 and r le 5)
      • ratings/any(r: r le 5 or r gt 7)
    • Porovnání výrazů v kombinaci s and (spojeními) lze dále kombinovat pomocí or. Tento formulář je známý v logické logice jako "Disjunktivní normální formulář" (DNF). Příklad:

      • ratings/any(r: (r gt 2 and r le 5) or (r gt 7 and r lt 10))
  • Pravidla pro all:
    • Jednoduché výrazy rovnosti nelze užitečně kombinovat s žádnými jinými výrazy. Tento výraz je například povolený:

      • ratings/all(r: r eq 5)

      ale tento výraz není:

      • ratings/all(r: r eq 5 or r le 2)

      a i když je tento výraz povolený, není užitečný, protože se podmínky překrývají:

      • ratings/all(r: r eq 5 and r le 7)
    • Jednoduché porovnávací výrazy zahrnující ne, , ltle, gt, nebo ge mohou být kombinovány s and/or. Příklad:

      • ratings/all(r: r gt 2 and r le 5)
      • ratings/all(r: r le 5 or r gt 7)
    • Porovnání výrazů v kombinaci s or (disjunkcemi) lze dále kombinovat pomocí and. Tento formulář je známý v logické logice jako "Normální formulář konjunktivy" (CNF). Příklad:

      • ratings/all(r: (r le 2 or gt 5) and (r lt 7 or r ge 10))

Pravidla pro filtrování složitých kolekcí

Výrazy lambda u složitých kolekcí podporují mnohem flexibilnější syntaxi než výrazy lambda v kolekcích primitivních typů. Můžete použít libovolný konstruktor filtru uvnitř takového výrazu lambda, který můžete použít mimo jeden, s pouze dvěma výjimkami.

Za prvé, funkce search.ismatch a search.ismatchscoring nejsou podporovány uvnitř výrazů lambda. Další informace najdete v tématu Principy filtrů kolekce OData ve službě Azure AI Search.

Za druhé, odkazování na pole, která nejsou svázaná s proměnnou rozsahu (tzv . volných proměnných), není povolená. Představte si například následující dva ekvivalentní výrazy 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))

První výraz je povolen, zatímco druhý formulář je odmítnut, protože details/margin není vázán na proměnnou srozsahu .

Toto pravidlo také rozšiřuje výrazy, které mají proměnné vázané ve vnějším oboru. Tyto proměnné jsou volné vzhledem k rozsahu, ve kterém se zobrazují. První výraz je například povolený, zatímco druhý ekvivalentní výraz není povolený, protože s/name je volný vzhledem k rozsahu proměnné arozsahu:

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

Toto omezení by nemělo být v praxi problém, protože vždy je možné vytvořit filtry tak, aby výrazy lambda obsahovaly pouze vázané proměnné.

Tahák pro pravidla filtru kolekcí

Následující tabulka shrnuje pravidla pro vytváření platných filtrů pro každý datový typ kolekce.

Datový typ Funkce povolené ve výrazech lambda s využitím any Funkce povolené ve výrazech lambda s využitím all
Collection(Edm.ComplexType) Vše kromě search.ismatch a search.ismatchscoring Stejné
Collection(Edm.String) Porovnání s eq nebo search.in

Kombinování dílčích výrazů s or
Porovnání s ne nebo not search.in()

Kombinování dílčích výrazů s and
Collection(Edm.Boolean) Porovnání s eq nebo ne Stejné
Collection(Edm.GeographyPoint) Použití s geo.distance lt nebo le

geo.intersects

Kombinování dílčích výrazů s or
Použití s geo.distance gt nebo ge

not geo.intersects(...)

Kombinování dílčích výrazů s and
Collection(Edm.DateTimeOffset), Collection(Edm.Double), , Collection(Edm.Int32)Collection(Edm.Int64) Porovnání pomocí eq, , nelt, gt, , le, neboge

Kombinování porovnání s jinými dílčími výrazy pomocí or

Kombinování porovnání s výjimkou ne jiných dílčích výrazů pomocí and

Výrazy používající kombinace a and or v disjunktivním normálním formátu (DNF)
Porovnání pomocí eq, , nelt, gt, , le, neboge

Kombinování porovnání s jinými dílčími výrazy pomocí and

Kombinování porovnání s výjimkou eq jiných dílčích výrazů pomocí or

Výrazy používající kombinace konjunktivového and or normálního formátu (CNF)

Příklady vytvoření platných filtrů pro jednotlivé případy naleznete v tématu Jak zapsat platné filtry kolekce.

Pokud zapisujete filtry často a rozumíte pravidlům z prvních principů, pomůže vám to více než jen jejich zapamatování, přečtěte si téma Principy filtrů kolekce OData ve službě Azure AI Search.

Další kroky