Dodawanie filtru w zapytaniu wektorowym w usłudze Azure AI Search

Możesz zdefiniować wektorowe żądanie zapytania zawierające wyrażenie filtru, aby dodać kryteria dołączania lub wykluczania do zapytań. Z tego artykułu dowiesz się, jak wykonywać następujące działania:

W tym artykule użyto architektury REST na potrzeby ilustracji. Przykłady kodu w innych językach można znaleźć w repozytorium GitHub azure-search-vector-samples , które zawiera kompleksowe rozwiązania obejmujące zapytania wektorowe.

Eksplorator wyszukiwania można również użyć w witrynie Azure Portal do wykonywania zapytań dotyczących zawartości wektorowej. Jeśli używasz widoku JSON, możesz dodać filtry i określić tryb filtrowania.

Jak działa filtrowanie w zapytaniu wektorowym

Filtry mają zastosowanie do filterable pól innych niż wektory, pola ciągu lub liczbowe, aby uwzględnić lub wykluczyć dokumenty wyszukiwania na podstawie kryteriów filtru. Chociaż pole wektorowe nie jest możliwe do filtrowania, filtry można stosować do innych pól w tym samym indeksie, w tym do dokumentów zawierających również pola wektorowe.

Filtry są stosowane przed wykonaniem zapytania lub po nim na podstawie parametru vectorFilterMode .

Definiowanie filtru

Filtry określają zakres zapytania wektorowego. Filtry są ustawiane i iterowane przez ciąg niewektorowy i pola liczbowe przypisane jako filterable w indeksie, ale cel filtru określa, co wykonuje zapytanie wektorowe: całe miejsce z możliwością wyszukiwania lub zawartość wyniku wyszukiwania.

Jeśli nie masz pól źródłowych z wartościami tekstowymi lub liczbowymi, sprawdź metadane dokumentu, takie jak Właściwości LastModified lub CreatedBy, które mogą być przydatne w filtrze metadanych.

2024-07-01 jest stabilną wersją tego interfejsu API. Ma:

W poniższym przykładzie wektor jest reprezentacją tego ciągu zapytania: "to, co usługi platformy Azure obsługują wyszukiwanie pełnotekstowe". Zapytanie jest przeznaczone dla contentVector pola . Rzeczywisty wektor ma 1536 osadzonych elementów, więc jest przycinany w tym przykładzie pod kątem czytelności.

Kryteria filtrowania są stosowane do pola tekstowego z możliwością filtrowania (category w tym przykładzie) przed wykonaniem zapytania wektorowego przez aparat wyszukiwania.

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
        }
    ]
}

Ustawianie wektoraFilterMode

Parametr zapytania vectorFilterMode określa, czy filtr jest stosowany przed wykonaniem zapytania wektorowego, czy po nim.

Korzystanie z trybu filtrowania wstępnego

Filtrowanie wstępne stosuje filtry przed wykonaniem zapytania, zmniejszając obszar powierzchni wyszukiwania, na którym algorytm wyszukiwania wektorowego szuka podobnej zawartości.

W zapytaniu preFilter wektorowym jest wartością domyślną.

Diagram wstępnie filtrów.

Korzystanie z trybu postfiltrowania

Filtrowanie po filtrowaniu stosuje filtry po wykonaniu zapytania, zawężając wyniki wyszukiwania.

Diagram przedstawiający filtry po filtrach.

Testowanie porównawcze trybów filtrowania wektorów

Aby zrozumieć warunki, w których jeden tryb filtrowania działa lepiej niż drugi, przeprowadziliśmy serię testów w celu oceny wyników zapytań w przypadku małych, średnich i dużych indeksów.

  • Mały (100 000 dokumentów, indeks 2,5 GB, 1536 wymiarów)
  • Średni (1 milion dokumentów, indeks 25 GB, 1536 wymiarów)
  • Duży (1 miliard dokumentów, indeks 1,9 TB, 96 wymiarów)

W przypadku małych i średnich obciążeń użyliśmy usługi Standardowa 2 (S2) z jedną partycją i jedną repliką. W przypadku dużego obciążenia użyliśmy usługi Standardowa 3 (S3) z 12 partycjami i jedną repliką.

Indeksy miały identyczną konstrukcję: jedno pole klucza, jedno pole wektorowe, jedno pole tekstowe i jedno pole filtrowalne liczbowo. Poniższy indeks jest zdefiniowany przy użyciu składni 2023-11-03.

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"
            }
        ]
      }
    }

W zapytaniach użyliśmy identycznego filtru dla operacji filtrowania wstępnego i postfiltru. Użyliśmy prostego filtru, aby upewnić się, że zmiany wydajności były spowodowane trybem filtrowania, a nie złożonością filtrowania.

Wyniki zostały zmierzone w zapytaniach na sekundę (QPS).

Wnioski

  • Filtrowanie wstępne jest prawie zawsze wolniejsze niż pofiltrowaniu, z wyjątkiem małych indeksów, w których wydajność jest w przybliżeniu równa.

  • W przypadku większych zestawów danych filtrowanie wstępne jest o wielkości wolniejsze.

  • Dlaczego więc filtr wstępny jest domyślny, jeśli jest prawie zawsze wolniejszy? Wstępne filtrowanie gwarantuje, że k wyniki są zwracane, jeśli istnieją w indeksie, gdzie stronniczość sprzyja kompletności i precyzji z szybkością.

  • Filtrowanie końcowe jest przeznaczone dla klientów, którzy:

    • szybkość zaznaczenia (filtrowanie postfiltrujące może zwracać mniej niż k wyniki)
    • używanie filtrów, które nie są nadmiernie selektywne
    • mają indeksy o wystarczających rozmiarach, tak aby wydajność filtrowania wstępnego jest niedopuszczalna

Szczegóły

  • Biorąc pod uwagę zestaw danych z 100 000 wektorów o wymiarach 1536:

    • Podczas filtrowania ponad 30% zestawu danych porównywano filtrowanie wstępne i filtrowanie postfiltrujące.
    • Podczas filtrowania mniejszego niż 0,1% zestawu danych filtrowanie wstępne było o około 50% wolniejsze niż po filtrowaniu.
  • Biorąc pod uwagę zestaw danych z 1 milionami wektorów o wymiarach 1536:

    • Podczas filtrowania ponad 30% zestawu danych wstępne filtrowanie było o około 30% wolniejsze.
    • Podczas filtrowania mniejszego niż 2% zestawu danych wstępne filtrowanie było około siedmiu razy wolniejsze.
  • Biorąc pod uwagę zestaw danych z 1 miliardami wektorów o wymiarach 96:

    • Podczas filtrowania ponad 5% zestawu danych wstępne filtrowanie było o około 50% wolniejsze.
    • Podczas filtrowania mniejszego niż 10% zestawu danych wstępne filtrowanie było około siedmiu razy wolniejsze.

Na poniższym wykresie przedstawiono wstępne filtrowanie względne QPS obliczone jako wstępne filtrowanie QPS podzielone przez QPS postfilter.

Wykres przedstawiający wydajność QPS dla małych, średnich i dużych indeksów dla względnych QPS.

Oś pionowa to QPS wstępnego filtrowania na QPS po filtrowaniu. Na przykład wartość 0,0 oznacza, że filtrowanie wstępne jest o 100% wolniejsze, 0,5 na osi pionowej oznacza, że filtrowanie wstępne jest o 50% wolniejsze, 1,0 oznacza, że filtrowanie wstępne i filtrowanie po są równoważne.

Oś pozioma reprezentuje współczynnik filtrowania lub procent dokumentów kandydatów po zastosowaniu filtru. Na przykład oznacza, 1.00% że jeden procent korpusu wyszukiwania został wybrany przez kryteria filtru.