Ř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ů
- Pravidla pro filtrování logických kolekcí
- Pravidla pro filtrování kolekcí GeographyPoint
- Pravidla pro filtrování srovnatelných kolekcí
- Pravidla pro filtrování složitých kolekcí
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 lt
gt
ge
/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 any
v 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
, gt
nebo 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. Proany
, můžete použít pouzelt
nebole
. Proall
, můžete použít pouzegt
neboge
. Můžete negovat výrazy zahrnujícígeo.distance
, ale musíte změnit relační operátor (geo.distance(...) lt x
stanenot (geo.distance(...) ge x)
se ageo.distance(...) le x
stanenot (geo.distance(...) gt x)
). - V těle
all
funkcegeo.intersects
musí být negatedována. Naopak v těleany
,geo.intersects
funkce nesmí být negovány. - V těle
any
, geoprostorové výrazy lze kombinovat pomocíor
. V těle ,all
takové 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
, ,lt
le
,gt
, neboge
mohou být kombinovány sand
/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
, ,lt
le
,gt
, neboge
mohou být kombinovány sand
/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:
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))
První výraz je povolen, zatímco druhý formulář je odmítnut, protože details/margin
není vázán na proměnnou s
rozsahu .
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é a
rozsahu:
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'))
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 , , ne lt , 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 , , ne lt , 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.