Partilhar via


Filtros em consultas vetoriais

Você pode definir modos de filtro de vetor em uma consulta vetorial para especificar se deseja filtrar antes ou depois da execução da consulta.

Os filtros determinam o escopo de uma consulta vetorial. Os filtros são definidos e iterados sobre cadeias de caracteres não vetoriais e campos numéricos atribuídos como filterable no índice, mas a finalidade de um filtro determina o que a consulta vetorial executa: todo o espaço pesquisável ou o conteúdo de um resultado de pesquisa.

Este artigo descreve cada modo de filtro e fornece orientação sobre quando usar cada um.

Modo de pré-filtro

A pré-filtragem aplica filtros antes da execução da consulta, reduzindo a área da superfície de pesquisa na qual o algoritmo de pesquisa vetorial procura conteúdo semelhante. Em uma consulta vetorial, preFilter é o padrão.

Diagrama de pré-filtros.

Modo pós-filtro

A pós-filtragem aplica filtros após a execução da consulta, restringindo os resultados da pesquisa.

Diagrama de pós-filtros.

Teste de benchmark de modos de filtro vetorial

Para entender as condições em que um modo de filtro tem um desempenho melhor do que o outro, executamos uma série de testes para avaliar os resultados da consulta em índices pequenos, médios e grandes.

  • Pequeno (100.000 documentos, índice de 2,5 GB, 1536 dimensões)
  • Médio (1 milhão de documentos, índice de 25 GB, 1536 dimensões)
  • Grande (1 bilhão de documentos, índice de 1,9 TB, 96 dimensões)

Para as cargas de trabalho pequenas e médias, usamos um serviço Standard 2 (S2) com uma partição e uma réplica. Para a grande carga de trabalho, usamos um serviço Standard 3 (S3) com 12 partições e uma réplica.

Os índices tinham uma construção idêntica: um campo chave, um campo vetorial, um campo de texto e um campo filtrável numérico. O índice a seguir é definido usando a sintaxe 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"
            }
        ]
      }
    }

Nas consultas, usamos um filtro idêntico para operações de pré-filtro e pós-filtro. Usamos um filtro simples para garantir que as variações no desempenho fossem devidas ao modo de filtragem e não à complexidade do filtro.

Os resultados foram medidos em Consultas por Segundo (QPS).

Conclusões

  • A pré-filtragem é quase sempre mais lenta do que a pós-filtragem, exceto em pequenos índices onde o desempenho é aproximadamente igual.

  • Em conjuntos de dados maiores, a pré-filtragem é ordens de magnitude mais lenta.

  • Então, por que o pré-filtro é o padrão se ele é quase sempre mais lento? A pré-filtragem garante que k os resultados sejam retornados se existirem no índice, onde o viés favorece a recuperação e a precisão em detrimento da velocidade.

  • A pós-filtragem destina-se a clientes que:

    • velocidade do valor sobre a seleção (a pós-filtragem pode retornar menos do que k os resultados)
    • Use filtros que não sejam excessivamente seletivos
    • ter índices de dimensão suficiente para que o desempenho da pré-filtragem seja inaceitável

Detalhes

  • Dado um conjunto de dados com 100.000 vetores em 1536 dimensões:

    • Ao filtrar mais de 30% do conjunto de dados, a pré-filtragem e a pós-filtragem foram comparáveis.
    • Ao filtrar menos de 0,1% do conjunto de dados, a pré-filtragem foi cerca de 50% mais lenta do que a pós-filtragem.
  • Dado um conjunto de dados com 1 milhão de vetores em 1536 dimensões:

    • Ao filtrar mais de 30% do conjunto de dados, a pré-filtragem foi cerca de 30% mais lenta.
    • Ao filtrar menos de 2% do conjunto de dados, a pré-filtragem foi cerca de sete vezes mais lenta.
  • Dado um conjunto de dados com 1 bilhão de vetores em 96 dimensões:

    • Ao filtrar mais de 5% do conjunto de dados, a pré-filtragem foi cerca de 50% mais lenta.
    • Ao filtrar menos de 10% do conjunto de dados, a pré-filtragem foi cerca de sete vezes mais lenta.

O gráfico a seguir mostra o QPS relativo do pré-filtro, calculado como QPS pré-filtro dividido pelo QPS pós-filtro.

Gráfico mostrando o desempenho do QPS para índices pequenos, médios e grandes para QPS relativo.

O eixo vertical é QPS de pré-filtragem sobre QPS de pós-filtragem. Por exemplo, um valor de 0,0 significa que a pré-filtragem é 100% mais lenta, 0,5 no eixo vertical significa que a pré-filtragem é 50% mais lenta, 1,0 significa que a pré-filtragem e a pós-filtragem são equivalentes.

O eixo horizontal representa a taxa de filtragem ou a percentagem de documentos candidatos após a aplicação do filtro. Por exemplo, 1.00% significa que um por cento do corpus de pesquisa foi selecionado pelos critérios de filtro.