Felsöka OData-samlingsfilter i Azure AI Search
Om du vill filtrera efter samlingsfält i Azure AI Search kan du använda operatorernaany
och all
tillsammans med lambda-uttryck. Ett lambda-uttryck är ett underfilter som tillämpas på varje element i en samling.
Alla funktioner i filteruttryck är inte tillgängliga i ett lambda-uttryck. Vilka funktioner som är tillgängliga varierar beroende på datatypen för samlingsfältet som du vill filtrera. Detta kan resultera i ett fel om du försöker använda en funktion i ett lambda-uttryck som inte stöds i den kontexten. Om du stöter på sådana fel när du försöker skriva ett komplext filter över samlingsfält hjälper den här artikeln dig att felsöka problemet.
Vanliga samlingsfilterfel
I följande tabell visas fel som kan uppstå när du försöker köra ett samlingsfilter. Dessa fel inträffar när du använder en funktion i filteruttryck som inte stöds i ett lambda-uttryck. Varje fel ger viss vägledning om hur du kan skriva om filtret för att undvika felet. Tabellen innehåller också en länk till relevant avsnitt i den här artikeln som innehåller mer information om hur du undviker det felet.
Felmeddelande | Situation | Details |
---|---|---|
Funktionen ismatch har inga parametrar som är bundna till intervallvariabeln 's'. Endast bundna fältreferenser stöds i lambda-uttryck ("alla" eller "alla"). Du kan dock ändra filtret så att ismatch funktionen ligger utanför lambda-uttrycket och försöka igen. |
Använda search.ismatch eller search.ismatchscoring inuti ett lambda-uttryck |
Regler för filtrering av komplexa samlingar |
Ogiltigt lambda-uttryck. Hittade ett test för likhet eller ojämlikhet där motsatsen förväntades i ett lambda-uttryck som itererar över ett fält av typen Collection(Edm.String). För "any" använder du uttryck för formuläret "x eq y" eller "search.in(...)". För "alla" använder du uttryck för formuläret "x ne y", "not (x eq y)" eller "not search.in(...)". | Filtrering på ett typfält Collection(Edm.String) |
Regler för filtrering av strängsamlingar |
Ogiltigt lambda-uttryck. Hittade en form av komplext booleskt uttryck som inte stöds. För "any" använder du uttryck som är "ORs of ANDs", även kallat Disjunctive Normal Form. Till exempel: (a and b) or (c and d) där a, b, c och d är jämförelse- eller likhetsunderuttryck. För "alla" använder du uttryck som är "ANDs of ORs", även kallat Konjunktivt normalformulär. Till exempel: (a or b) and (c or d) där en, b, c och d är jämförelse- eller ojämlikhetsunderuttryck. Exempel på jämförelseuttryck: "x gt 5", "x le 2". Exempel på ett likhetsuttryck: "x eq 5". Exempel på ett ojämlikhetsuttryck: "x ne 5". |
Filtrering på fält av typen Collection(Edm.DateTimeOffset) , Collection(Edm.Double) , Collection(Edm.Int32) eller Collection(Edm.Int64) |
Regler för filtrering av jämförbara samlingar |
Ogiltigt lambda-uttryck. Hittade en användning av geo.distance() eller geo.intersects() i ett lambda-uttryck som itererar över ett fält av typen Collection(Edm.GeographyPoint). För "any" kontrollerar du att du jämför geo.distance() med operatorerna "lt" eller "le" och ser till att all användning av geo.intersects() inte negeras. För "alla" ska du jämföra geo.distance() med operatorerna "gt" eller "ge" och se till att all användning av geo.intersects() negeras. | Filtrering på ett typfält Collection(Edm.GeographyPoint) |
Regler för filtrering av GeographyPoint-samlingar |
Ogiltigt lambda-uttryck. Komplexa booleska uttryck stöds inte i lambda-uttryck som itererar över fält av typen Collection(Edm.GeographyPoint). För "any" ansluter du underuttryck med "or"; "och" stöds inte. För "alla" ansluter du underuttryck med "och"; "eller" stöds inte. | Filtrera efter fält av typen Collection(Edm.String) eller Collection(Edm.GeographyPoint) |
Regler för filtrering av strängsamlingar Regler för filtrering av GeographyPoint-samlingar |
Ogiltigt lambda-uttryck. Hittade en jämförelseoperator (en av 'lt', 'le', 'gt' eller 'ge'). Endast likhetsoperatorer tillåts i lambda-uttryck som itererar över fält av typen Collection(Edm.String). För "any" ser du uttryck för formuläret "x eq y". För "alla" använder du uttryck för formuläret "x ne y" eller "not (x eq y)". | Filtrering på ett typfält Collection(Edm.String) |
Regler för filtrering av strängsamlingar |
Så här skriver du giltiga samlingsfilter
Reglerna för att skriva giltiga samlingsfilter skiljer sig åt för varje datatyp. I följande avsnitt beskrivs reglerna genom att visa exempel på vilka filterfunktioner som stöds och vilka som inte stöds:
- Regler för filtrering av strängsamlingar
- Regler för filtrering av booleska samlingar
- Regler för filtrering av GeographyPoint-samlingar
- Regler för filtrering av jämförbara samlingar
- Regler för filtrering av komplexa samlingar
Regler för filtrering av strängsamlingar
I lambda-uttryck för strängsamlingar är eq
de enda jämförelseoperatorer som kan användas och ne
.
Kommentar
Azure AI Search stöder inte operatorerna lt
gt
ge
/le
//för strängar, vare sig i eller utanför ett lambda-uttryck.
Kroppen av en any
kan bara testa för likhet medan kroppen av en all
kan bara testa för ojämlikhet.
Det är också möjligt att kombinera flera uttryck via or
i brödtexten i en any
, och via and
i brödtexten i en all
. Eftersom funktionen search.in
motsvarar att kombinera likhetskontroller med or
, tillåts den också i brödtexten i en any
. Omvänt not search.in
tillåts i brödtexten i en all
.
Dessa uttryck är till exempel tillåtna:
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'))
Även om dessa uttryck inte tillåts:
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'))
Regler för filtrering av booleska samlingar
Typen Edm.Boolean
stöder endast operatorerna eq
och ne
. Därför är det inte meningsfullt att kombinera sådana satser som kontrollerar samma intervallvariabel med and
/or
eftersom det alltid skulle leda till tautologier eller motsägelser.
Här är några exempel på filter på booleska samlingar som tillåts:
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))
Till skillnad från strängsamlingar har booleska samlingar inga gränser för vilken operator som kan användas i vilken typ av lambda-uttryck. Både eq
och ne
kan användas i kroppen av any
eller all
.
Uttryck som följande tillåts inte för booleska samlingar:
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)
Regler för filtrering av GeographyPoint-samlingar
Värden av typen Edm.GeographyPoint
i en samling kan inte jämföras direkt med varandra. I stället måste de användas som parametrar för geo.distance
funktionerna och geo.intersects
. Funktionen geo.distance
måste i sin tur jämföras med ett avståndsvärde med någon av jämförelseoperatorerna lt
, le
, gt
eller ge
. Dessa regler gäller även för Edm.GeographyPoint-fält som inte är insamlade.
Liksom strängsamlingar Edm.GeographyPoint
har samlingar vissa regler för hur geo-spatiala funktioner kan användas och kombineras i de olika typerna av lambda-uttryck:
- Vilka jämförelseoperatorer du kan använda med
geo.distance
funktionen beror på typen av lambda-uttryck. Förany
kan du baralt
använda ellerle
. Förall
kan du baragt
använda ellerge
. Du kan negera uttryck som involverargeo.distance
, men du måste ändra jämförelseoperatorn (geo.distance(...) lt x
blirnot (geo.distance(...) ge x)
ochgeo.distance(...) le x
blirnot (geo.distance(...) gt x)
). - I brödtexten i en
all
geo.intersects
måste funktionen negeras. I brödtexten i enany
fårgeo.intersects
funktionen däremot inte negeras. - I brödtexten i ett
any
kan geo-spatiala uttryck kombineras med hjälp avor
. I brödtexten i enall
kan sådana uttryck kombineras med .and
Ovanstående begränsningar finns av liknande skäl som likhets-/ojämlikhetsbegränsningen för strängsamlingar. Mer information om dessa orsaker finns i Förstå OData-samlingsfilter i Azure AI Search .
Här följer några exempel på filter på Edm.GeographyPoint
samlingar som tillåts:
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))'))
Uttryck som följande tillåts inte för Edm.GeographyPoint
samlingar:
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))'))
Regler för filtrering av jämförbara samlingar
Det här avsnittet gäller för alla följande datatyper:
Collection(Edm.DateTimeOffset)
Collection(Edm.Double)
Collection(Edm.Int32)
Collection(Edm.Int64)
Typer som Edm.Int32
och Edm.DateTimeOffset
stöder alla sex jämförelseoperatorerna: eq
, ne
, lt
, le
, gt
och ge
. Lambda-uttryck över samlingar av dessa typer kan innehålla enkla uttryck med någon av dessa operatorer. Detta gäller både any
och all
. Dessa filter är till exempel tillåtna:
ratings/any(r: r ne 5)
dates/any(d: d gt 2017-08-24T00:00:00Z)
not margins/all(m: m eq 3.5)
Det finns dock begränsningar för hur sådana jämförelseuttryck kan kombineras till mer komplexa uttryck i ett lambda-uttryck:
- Regler för
any
:Enkla ojämlikhetsuttryck kan inte kombineras med andra uttryck. Det här uttrycket tillåts till exempel:
ratings/any(r: r ne 5)
men det här uttrycket är inte:
ratings/any(r: r ne 5 and r gt 2)
och även om det här uttrycket tillåts är det inte användbart eftersom villkoren överlappar varandra:
ratings/any(r: r ne 5 or r gt 7)
Enkla jämförelseuttryck som involverar
eq
,lt
,le
,gt
ellerge
kan kombineras medand
/or
. Till exempel:ratings/any(r: r gt 2 and r le 5)
ratings/any(r: r le 5 or r gt 7)
Jämförelseuttryck i kombination med
and
(konjunktioner) kan kombineras ytterligare med hjälp avor
. Det här formuläret är känt i boolesk logik som "Disjunctive Normal Form" (DNF). Till exempel:ratings/any(r: (r gt 2 and r le 5) or (r gt 7 and r lt 10))
- Regler för
all
:Enkla likhetsuttryck kan inte kombineras med andra uttryck. Det här uttrycket tillåts till exempel:
ratings/all(r: r eq 5)
men det här uttrycket är inte:
ratings/all(r: r eq 5 or r le 2)
och även om det här uttrycket tillåts är det inte användbart eftersom villkoren överlappar varandra:
ratings/all(r: r eq 5 and r le 7)
Enkla jämförelseuttryck som involverar
ne
,lt
,le
,gt
ellerge
kan kombineras medand
/or
. Till exempel:ratings/all(r: r gt 2 and r le 5)
ratings/all(r: r le 5 or r gt 7)
Jämförelseuttryck som kombineras med
or
(disjunctions) kan kombineras ytterligare med hjälp avand
. Det här formuläret är känt i boolesk logik som "Conjunctive Normal Form" (CNF). Till exempel:ratings/all(r: (r le 2 or gt 5) and (r lt 7 or r ge 10))
Regler för filtrering av komplexa samlingar
Lambda-uttryck över komplexa samlingar stöder en mycket mer flexibel syntax än lambda-uttryck över samlingar av primitiva typer. Du kan använda valfri filterkonstruktion i ett sådant lambda-uttryck som du kan använda utanför ett, med endast två undantag.
Först fungerar search.ismatch
och search.ismatchscoring
stöds inte i lambda-uttryck. Mer information finns i Förstå OData-samlingsfilter i Azure AI Search.
För det andra är det inte tillåtet att referera till fält som inte är bundna till intervallvariabeln (så kallade kostnadsfria variabler). Tänk dig till exempel följande två motsvarande OData-filteruttryck:
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))
Det första uttrycket tillåts, medan det andra formuläret avvisas eftersom details/margin
det inte är bundet till intervallvariabeln s
.
Den här regeln omfattar även uttryck som har variabler bundna i ett yttre omfång. Sådana variabler är kostnadsfria när det gäller det omfång som de visas i. Det första uttrycket tillåts till exempel, medan det andra motsvarande uttrycket inte tillåts eftersom s/name
det är kostnadsfritt med avseende på omfånget för intervallvariabeln 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'))
Den här begränsningen bör inte vara ett problem i praktiken eftersom det alltid är möjligt att konstruera filter så att lambda-uttryck endast innehåller bundna variabler.
Fuskark för insamlingsfilterregler
I följande tabell sammanfattas reglerna för att konstruera giltiga filter för varje samlingsdatatyp.
Datatyp | Funktioner som tillåts i lambda-uttryck med any |
Funktioner som tillåts i lambda-uttryck med all |
---|---|---|
Collection(Edm.ComplexType) |
Allt utom search.ismatch och search.ismatchscoring |
Samma |
Collection(Edm.String) |
Jämförelser med eq eller search.in Kombinera underuttryck med or |
Jämförelser med ne eller not search.in() Kombinera underuttryck med and |
Collection(Edm.Boolean) |
Jämförelser med eq eller ne |
Samma |
Collection(Edm.GeographyPoint) |
Använda geo.distance med lt eller le geo.intersects Kombinera underuttryck med or |
Använda geo.distance med gt eller ge not geo.intersects(...) Kombinera underuttryck med and |
Collection(Edm.DateTimeOffset) , Collection(Edm.Double) , , Collection(Edm.Int32) Collection(Edm.Int64) |
Jämförelser med , eq ne , lt , gt , le ellerge Kombinera jämförelser med andra underuttryck med hjälp av or Kombinera jämförelser förutom ne med andra underuttryck med hjälp av and Uttryck med hjälp av kombinationer av and och or i disjunctive Normal Form (DNF) |
Jämförelser med , eq ne , lt , gt , le ellerge Kombinera jämförelser med andra underuttryck med hjälp av and Kombinera jämförelser förutom eq med andra underuttryck med hjälp av or Uttryck som använder kombinationer av and och or i konjunktiv normal form (CNF) |
Exempel på hur du skapar giltiga filter för varje ärende finns i Så här skriver du giltiga samlingsfilter.
Om du skriver filter ofta och förstå reglerna från de första principerna hjälper dig mer än att bara memorera dem kan du läsa Förstå OData-samlingsfilter i Azure AI Search.