Az OData-gyűjteményszűrők működésének ismertetése az Azure AI Keresésben

Megjegyzés

Azure AI Keresés a Azure portálon, REST API-kon és Azure SDK-k keresztül érhető el. Emellett a Foundry IQ-t is támogatja, amely a vállalati tartalmakat újrafelhasználható, engedélytudatos tudásbázisokká alakítja át az Microsoft Foundry portálon található ügynökök számára.

Ez a cikk olyan fejlesztőknek nyújt hátteret, akik összetett lambdakifejezésekkel írnak speciális szűrőket. A cikk azt ismerteti, hogy miért léteznek a gyűjteményszűrőkre vonatkozó szabályok, ha megvizsgáljuk, hogyan hajtja végre az Azure AI Keresés ezeket a szűrőket.

Amikor az Azure AI Keresés gyűjteménymezőire készít szűrőt, a és operátorokat együtt használhatja a lambdakifejezésekkel. A Lambda-kifejezések olyan logikai kifejezések, amelyek egy tartományváltozóra hivatkoznak. A lambda kifejezést használó szűrőkben az operátorok és any az all operátorok a legtöbb programozási nyelvben hasonlóak egy for hurokhoz, a tartományváltozó a ciklusváltozó szerepét veszi át, a lambda kifejezés pedig a hurok törzse. A tartományváltozó a ciklus iterációja során veszi át a gyűjtemény "aktuális" értékét.

Legalábbis így működik fogalmilag. Az Azure AI Keresés a valóságban egészen más módon implementálja a szűrőket a hurkok működéséhez for . Ideális esetben ez a különbség láthatatlan lenne az Ön számára, de bizonyos helyzetekben nem. A végeredmény az, hogy vannak szabályok, amelyeket be kell tartania a lambda kifejezések írásakor.

Megjegyzés

További információ a gyűjteményszűrők szabályairól, beleértve a példákat is: OData-gyűjteményszűrők hibaelhárítása az Azure AI Keresésben.

Miért korlátozottak a gyűjteményszűrők?

Három alapvető oka van annak, hogy a szűrőfunkciók nem támogatottak teljes mértékben az összes gyűjteménytípus esetében:

  1. Bizonyos adattípusok esetében csak bizonyos operátorok támogatottak. Például nincs értelme a true és false logikai értékeket olyan összehasonlító operátorokkal összehasonlítani, mint a lt és a gt.
  2. Az Azure AI Keresés támogatja a korrelált szűrőket a Collection(Edm.ComplexType) típusú mezőkön, azonban az ezeken a mezőkön végzett mezőszintű teljes szöveges keresés nem korrelált.
  3. Az Azure AI Keresés invertált indexekkel hajt végre szűrőket minden adattípuson, beleértve a gyűjteményeket is.

Az első ok csak az OData nyelv és az EDM típusú rendszer definiálásának következménye. Az utolsó kettőt részletesebben a cikk további részében ismertetjük.

Ha összetett objektumok gyűjteményére több szűrési feltételt alkalmaz, a feltételek korrelálnak, mert a gyűjtemény minden egyes objektumára vonatkoznak. Az alábbi szűrő például azokat a szállodákat adja vissza, amelyek legalább egy deluxe szobával rendelkeznek, és a díjszabása 100-nál kisebb:

    Rooms/any(room: room/Type eq 'Deluxe Room' and room/BaseRate lt 100)

Ha a szűrés nem volt korrelálatlan, a fenti szűrő olyan szállodákat adhat vissza, ahol egy szoba deluxe, és egy másik szoba alapdíja 100-nál alacsonyabb. Ennek nem lenne értelme, mivel a lambda kifejezés mindkét záradéka ugyanarra a tartományváltozóra vonatkozik, nevezetesen room. Ezért vannak korrelálva az ilyen szűrők.

A teljes szöveges kereséshez azonban nem lehet egy adott tartományváltozóra hivatkozni. Ha az alábbihoz hasonló teljes Lucene-lekérdezést ad ki mezős kereséssel:

    Rooms/Type:deluxe AND Rooms/Description:"city view"

Előfordulhat, hogy olyan szállodákat talál, ahol az egyik szoba prémium, míg egy másik szoba leírásában "városnézet" szerepel. Az alábbi dokumentum például megegyezik a lekérdezéssel Id1 :

{
  "value": [
    {
      "Id": "1",
      "Rooms": [
        { "Type": "deluxe", "Description": "Large garden view suite" },
        { "Type": "standard", "Description": "Standard city view room" }
      ]
    },
    {
      "Id": "2",
      "Rooms": [
        { "Type": "deluxe", "Description": "Courtyard motel room" }
      ]
    }
  ]
}

Ennek az az oka, hogy Rooms/Type a mező összes elemzett kifejezésére hivatkozik a Rooms/Type teljes dokumentumban, és ehhez Rooms/Descriptionhasonlóan az alábbi táblázatokban látható módon.

A teljes szöveges keresés tárolási módja Rooms/Type :

Kifejezés a következőben: Rooms/Type Dokumentumazonosítók
Deluxe 1, 2
szabvány 1

A teljes szöveges keresés tárolási módja Rooms/Description :

Kifejezés a következőben: Rooms/Description Dokumentumazonosítók
udvar 2
Város 1
kert 1
nagy 1
motel 2
szoba 1, 2
szabvány 1
programcsomag 1
nézet 1

Tehát ellentétben a fenti szűrővel, amely alapvetően azt mondja, "keresett dokumentumok, ahol a szoba Type egyenlő a 'Deluxe Szobával', és ugyanaz a szoba kevesebb, mint 100-szal rendelkezik", a keresési lekérdezés azt mondja, "keresett dokumentumok, ahol BaseRate tartalmazza a "deluxe" kifejezést és Rooms/Type tartalmazza a "városnézet" kifejezést. Az utóbbi esetben nem létezik olyan különálló helyiség, amelynek mezői korrelálhatók.

Fordított indexek és gyűjtemények

Észreveheti, hogy a Lambda-kifejezések sokkal kevesebb korlátozással rendelkeznek az összetett gyűjteményekre, mint az egyszerű gyűjteményekre, például Collection(Edm.Int32) és Collection(Edm.GeographyPoint). Ez a különbség azért van, mert Azure AI Keresés az összetett gyűjteményeket aldokumentumok tényleges gyűjteményeként tárolja, míg az egyszerű gyűjtemények egyáltalán nem gyűjteményként vannak tárolva.

Vegyük például egy szűrhető sztringgyűjtési mezőt, például seasons egy online kereskedő indexében. Az indexbe feltöltött dokumentumok némelyike a következőképpen nézhet ki:

{
  "value": [
    {
      "id": "1",
      "name": "Hiking boots",
      "seasons": ["spring", "summer", "fall"]
    },
    {
      "id": "2",
      "name": "Rain jacket",
      "seasons": ["spring", "fall", "winter"]
    },
    {
      "id": "3",
      "name": "Parka",
      "seasons": ["winter"]
    }
  ]
}

A mező értékei seasons egy fordított indexnek nevezett struktúrában vannak tárolva, amely a következőképpen néz ki:

Időszak Dokumentumazonosítók
tavasz 1, 2
nyár 1
esik 1, 2
tél 2, 3

Ez az adatstruktúra úgy lett kialakítva, hogy nagy sebességgel válaszoljon egy kérdésre: Mely dokumentumokban jelenik meg egy adott kifejezés? A kérdés megválaszolása inkább egy egyszerű egyenlőség-ellenőrzéshez hasonlít, mint egy gyűjteményen keresztüli hurok. Valójában ez az oka annak, hogy a sztringgyűjtemények esetében az Azure AI Keresés csak összehasonlító operátorként teszi lehetővé eq a lambda kifejezésen belül.any

Következő lépésként áttekintjük, hogyan kombinálható több egyenlőségi ellenőrzés ugyanazon a tartományváltozón or. Az algebra és a kvantátorok disztribúciós tulajdonságának köszönhetően működik. Ez a kifejezés:

    seasons/any(s: s eq 'winter' or s eq 'fall')

egyenértékű a következővel:

    seasons/any(s: s eq 'winter') or seasons/any(s: s eq 'fall')

és a két any alkifejezés mindegyike hatékonyan végrehajtható az invertált index használatával. Emellett a kvantátorok tagadási törvényének köszönhetően ez a kifejezés:

    seasons/all(s: s ne 'winter' and s ne 'fall')

egyenértékű a következővel:

    not seasons/any(s: s eq 'winter' or s eq 'fall')

Ezért lehetséges a all, ne és and használata.

Megjegyzés

Bár a részletek túlmutatnak a jelen dokumentum hatókörén, ugyanezek az alapelvek kiterjednek a térbeli pontok gyűjteményeinek távolság- és metszetvizsgálatára is. Ezért, a következő esetben any:

  • geo.intersects nem tagadható meg
  • A geo.distance összehasonlítását lt vagy le használatával kell elvégezni.
  • A kifejezéseket or-val kell kombinálni, nem and-val.

A converse szabályok a következőre vonatkoznak all: .

A kifejezések szélesebb köre engedélyezett, ha például olyan adattípusok gyűjteményére szűr, amelyek támogatják a lt, gt, le, és ge operátorokat, például Collection(Edm.Int32) . Pontosan használhatja a and, valamint a or kifejezéseket a any-ben, mindaddig, amíg a mögöttes összehasonlító kifejezések tartomány-összehasonlításokká vannak kombinálva a and használatával, amelyeket aztán további or kombinációkkal lehet összekapcsolni. A logikai kifejezések ezen struktúráját disjunctive Normal Form (DNF) néven nevezzük, más néven "AND-k ORs-ének". Ezzel szemben az ilyen adattípusok lambda-kifejezéseinek all conjunctive Normal Form (CNF) formában kell lenniük, más néven "ORs AND-k" néven. Az Azure AI Keresés lehetővé teszi az ilyen tartomány-összehasonlításokat, mivel invertált indexekkel hatékonyan hajtja végre őket, ugyanúgy, mint ahogyan gyors keresést végez sztringek esetében.

Összefoglalva: a lambda kifejezésben megengedett ökölszabály:

  • any belül mindig engedélyezett a pozitív tesztelés, például egyenlőség, tartomány-összehasonlítás, geo.intersects vagy geo.distance összevetve lt-hoz vagy le-höz (a "közelség" olyan, mint az egyenlőség a távolság ellenőrzésekor).
  • any Belül ormindig engedélyezett. Csak olyan adattípusokhoz használható and , amelyek képesek a tartomány-ellenőrzések kifejezésére, és csak akkor, ha az AND-k (DNF) ORs-eit használja.
  • Belül all a szabályok megfordulnak. Csak negatív ellenőrzések engedélyezettek, mindig használhatók and , és csak az ORS-ek (CNF) AND-jeiként kifejezett tartományellenőrzésekhez használható or .

Gyakorlatilag ezek azok a szűrők, amelyeket úgyis leggyakrabban használunk. Még mindig hasznos megérteni a határokat, hogy mi lehetséges mégis.

Az érvényes gyűjteményszűrők írása című témakörben konkrét példákat talál arra, hogy milyen típusú szűrők engedélyezettek és melyek nem.

Következő lépések