Szűrő hozzáadása vektoros lekérdezésben az Azure AI Searchben
Definiálhat egy vektoros lekérdezési kérelmet, amely egy szűrőkifejezést tartalmaz a lekérdezések befogadási vagy kizárási feltételeinek hozzáadásához. Ebből a cikkből megtudhatja, hogyan:
Ez a cikk REST-et használ az ábrához. Más nyelvű kódmintákért tekintse meg az azure-search-vector-samples GitHub-adattárat a vektoros lekérdezéseket tartalmazó végpontok közötti megoldásokhoz.
A Keresőböngészőt az Azure Portalon is lekérdezheti a vektortartalmat. Ha JSON-nézetet használ, szűrőket adhat hozzá, és megadhatja a szűrési módot.
A szűrés működése vektoros lekérdezésekben
A szűrők sztringmezőkre filterable
vagy numerikus mezőkre vonatkoznak a keresési dokumentumok szűrési feltételek alapján való belefoglalásához vagy kizárásához. Bár egy vektormező önmagában nem szűrhető, a szűrők alkalmazhatók ugyanazon index más mezőire is, beleértve vagy kizárva a vektormezőket is tartalmazó dokumentumokat.
A szűrők a lekérdezés végrehajtása előtt vagy után kerülnek alkalmazásra a vectorFilterMode
paraméter alapján.
Szűrő definiálása
A szűrők határozzák meg a vektoros lekérdezés hatókörét. A szűrők be vannak kapcsolva, és iterálódnak az indexhez rendelt filterable
nemvektor-sztringek és numerikus mezők felett, de a szűrő célja határozza meg , hogy a vektoros lekérdezés mit hajt végre: a teljes kereshető területet vagy a keresési eredmény tartalmát.
Ha nem rendelkezik szöveges vagy numerikus értékeket tartalmazó forrásmezőkkel, ellenőrizze, hogy vannak-e olyan dokumentum metaadatai, mint például a LastModified vagy a CreatedBy tulajdonságok, amelyek hasznosak lehetnek egy metaadat-szűrőben.
A 2024-07-01 az API stabil verziója. A következőt teszi:
vectorFilterMode
előszűrő (alapértelmezett) vagy postfilter szűrési mód esetén.filter
adja meg a feltételeket.
A következő példában a vektor ennek a lekérdezési sztringnek a reprezentációja: "amit az Azure-szolgáltatások támogatnak a teljes szöveges keresésben". A lekérdezés a contentVector
mezőt célozza meg. A tényleges vektor 1536 beágyazással rendelkezik, ezért ebben a példában az olvashatóság érdekében vágja le.
A szűrőfeltételeket a program egy szűrhető szövegmezőre alkalmazza (category
ebben a példában), mielőtt a keresőmotor végrehajtja a vektoros lekérdezést.
POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2024-07-01
Content-Type: application/json
api-key: {{admin-api-key}}
{
"count": true,
"select": "title, content, category",
"filter": "category eq 'Databases'",
"vectorFilterMode": "preFilter",
"vectorQueries": [
{
"kind": "vector",
"vector": [
-0.009154141,
0.018708462,
. . .
-0.02178128,
-0.00086512347
],
"exhaustive": true,
"fields": "contentVector",
"k": 5
}
]
}
A vectorFilterMode beállítása
A vectorFilterMode lekérdezési paraméter határozza meg, hogy a szűrő a vektoros lekérdezés végrehajtása előtt vagy után van-e alkalmazva.
Előszűrő mód használata
Az előszűrés szűrőket alkalmaz a lekérdezés végrehajtása előtt, így csökkenti a keresési felület azon területét, amelyen a vektorkeresési algoritmus hasonló tartalmat keres.
Vektoros lekérdezésben preFilter
ez az alapértelmezett érték.
Postfilter mód használata
A szűrés utáni szűrés szűrőket alkalmaz a lekérdezés végrehajtása után, és szűkíti a keresési eredményeket.
Vektorszűrő módok benchmark-tesztelése
Annak érdekében, hogy megértsük azokat a feltételeket, amelyek mellett az egyik szűrőmód a másiknál jobban teljesít, tesztsorozatot futtattunk a lekérdezési eredmények kiértékelésére kis, közepes és nagy indexeken.
- Kicsi (100 000 dokumentum, 2,5 GB-os index, 1536 dimenzió)
- Közepes (1 millió dokumentum, 25 GB-os index, 1536 dimenzió)
- Nagy (1 milliárd dokumentum, 1,9 TB index, 96 dimenzió)
A kis és közepes számítási feladatokhoz egy Standard 2 (S2) szolgáltatást használtunk egy partícióval és egy replikával. A nagy számítási feladatokhoz egy Standard 3 (S3) szolgáltatást használtunk 12 partícióval és egy replikával.
Az indexek felépítése azonos volt: egy kulcsmező, egy vektormező, egy szövegmező és egy numerikus szűrhető mező. A következő index a 2023-11-03 szintaxissal van definiálva.
def get_index_schema(self, index_name, dimensions):
return {
"name": index_name,
"fields": [
{"name": "id", "type": "Edm.String", "key": True, "searchable": True},
{"name": "content_vector", "type": "Collection(Edm.Single)", "dimensions": dimensions,
"searchable": True, "retrievable": True, "filterable": False, "facetable": False, "sortable": False,
"vectorSearchProfile": "defaulthnsw"},
{"name": "text", "type": "Edm.String", "searchable": True, "filterable": False, "retrievable": True,
"sortable": False, "facetable": False},
{"name": "score", "type": "Edm.Double", "searchable": False, "filterable": True,
"retrievable": True, "sortable": True, "facetable": True}
],
"vectorSearch": {
"algorithms": [
{
"name": "defaulthnsw",
"kind": "hnsw",
"hnswParameters": { "metric": "euclidean" }
}
],
"profiles": [
{
"name": "defaulthnsw",
"algorithm": "defaulthnsw"
}
]
}
}
A lekérdezésekben azonos szűrőt használtunk az előszűrő és a postfilter műveletekhez is. Egy egyszerű szűrőt használtunk annak biztosítására, hogy a teljesítménybeli eltérések a szűrési módnak, és nem a szűrés összetettségének köszönhetők.
Az eredményeket másodpercenkénti lekérdezésekben (QPS) mérték.
Legfontosabb ismeretek
Az előszűrés szinte mindig lassabb, mint a postfilterezés, kivéve a kis indexeket, ahol a teljesítmény körülbelül egyenlő.
Nagyobb adathalmazok esetén az előszűrés nagyságrendekkel lassabb.
Miért az előszűrés az alapértelmezett, ha szinte mindig lassabb? Az előszűrés garantálja, hogy
k
az eredmények akkor lesznek visszaadva, ha az indexben vannak, ahol a torzítás előnyben részesíti a visszahívást és a pontosságot a sebesség felett.A postfiltering azoknak az ügyfeleknek szól, akik:
- értéksebesség a kijelöléshez képest (a postfiltering az eredményeknél
k
kevesebbet adhat vissza) - olyan szűrők használata, amelyek nem túl szelektívek
- megfelelő méretű indexek vannak, hogy az előszűrési teljesítmény elfogadhatatlan
- értéksebesség a kijelöléshez képest (a postfiltering az eredményeknél
Részletek
100 000 vektort tartalmazó adathalmaz 1536 dimenzióban:
- Az adathalmaz több mint 30%-ának szűrésekor az előszűrés és a postfilterezés összehasonlítható volt.
- Az adathalmaz kevesebb mint 0,1%-ának szűrésekor az előszűrés körülbelül 50%-kal lassabb volt, mint a postfilterelés.
Egy 1 millió vektort tartalmazó adathalmaz 1536 dimenzióban:
- Az adathalmaz több mint 30%-ának szűrésekor az előszűrés körülbelül 30%-kal lassabb volt.
- Az adathalmaz kevesebb mint 2%-ának szűrése esetén az előszűrés körülbelül hétszer lassabb volt.
Egy 1 milliárd vektort tartalmazó adathalmaz 96 dimenzióban:
- Az adathalmaz több mint 5%-ának szűrésekor az előszűrés körülbelül 50%-kal lassabb volt.
- Az adathalmaz kevesebb mint 10%-ának szűrésekor az előszűrés körülbelül hétszer lassabb volt.
Az alábbi grafikon az előszűrő relatív QPS-ét mutatja be, amely a QPS-t követő QPS-vel osztva előszűrőként van kiszámítva.
A függőleges tengely a QPS előszűrése a QPS-hez az utószűrés QPS-ével szemben. A 0,0 érték például azt jelenti, hogy az előszűrés 100%-kal lassabb, a függőleges tengelyen a 0,5 azt jelenti, hogy az előszűrés 50%-kal lassabb, az 1,0 pedig azt jelenti, hogy az előszűrés és az utószűrés egyenértékű.
A vízszintes tengely a szűrési arányt vagy a jelölt dokumentumok százalékos arányát jelöli a szűrő alkalmazása után. Ez azt jelenti például, 1.00%
hogy a keresési korpusz egy százalékát a szűrőfeltételek jelölték ki.