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

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 ltgtge/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, gteller 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ör anykan du bara lt använda eller le. För allkan du bara gt använda eller ge. Du kan negera uttryck som involverar geo.distance, men du måste ändra jämförelseoperatorn (geo.distance(...) lt x blir not (geo.distance(...) ge x) och geo.distance(...) le x blir not (geo.distance(...) gt x)).
  • I brödtexten i en allgeo.intersects måste funktionen negeras. I brödtexten i en anyfår geo.intersects funktionen däremot inte negeras.
  • I brödtexten i ett anykan geo-spatiala uttryck kombineras med hjälp av or. I brödtexten i en allkan 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, gtoch 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, gteller ge kan kombineras med and/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 av or. 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, gteller ge kan kombineras med and/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 av and. 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:

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

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:

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

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 , eqne, lt, gt, leellerge

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 , eqne, lt, gt, leellerge

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.

Nästa steg