Partilhar via


Adicionar um filtro em uma consulta vetorial no Azure AI Search

Você pode definir uma solicitação de consulta vetorial que inclua uma expressão de filtro para adicionar critérios de inclusão ou exclusão às suas consultas. Neste artigo, saiba como:

Este artigo usa REST para ilustração. Para exemplos de código em outros idiomas, consulte o repositório GitHub azure-search-vector-samples para obter soluções de ponta a ponta que incluem consultas vetoriais.

Você também pode usar o Gerenciador de Pesquisa no portal do Azure para consultar conteúdo vetorial. Se você usar o modo de exibição JSON, poderá adicionar filtros e especificar o modo de filtro.

Como funciona a filtragem em uma consulta vetorial

Os filtros aplicam-se a filterable campos não vetoriais, seja um campo de cadeia de caracteres ou numérico, para incluir ou excluir documentos de pesquisa com base em critérios de filtro. Embora um campo vetorial não seja filtrável, os filtros podem ser aplicados a outros campos no mesmo índice, incluindo ou excluindo os documentos que também contêm campos vetoriais.

Os filtros são aplicados antes ou depois da execução da vectorFilterMode consulta com base no parâmetro.

Definir um filtro

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.

Se você não tiver campos de origem com texto ou valores numéricos, verifique se há metadados do documento, como as propriedades LastModified ou CreatedBy, que podem ser úteis em um filtro de metadados.

2024-07-01 é a versão estável para esta API. Dispõe de:

No exemplo a seguir, o vetor é uma representação dessa cadeia de caracteres de consulta: "quais serviços do Azure oferecem suporte à pesquisa de texto completo". A consulta destina-se ao contentVector campo. O vetor real tem 1536 incorporações, por isso é cortado neste exemplo para legibilidade.

Os critérios de filtro são aplicados a um campo de texto filtrável (category neste exemplo) antes que o mecanismo de pesquisa execute a consulta vetorial.

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

Definir o vectorFilterMode

O parâmetro de consulta vectorFilterMode determina se o filtro é aplicado antes ou depois da execução da consulta vetorial.

Usar o 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.

Usar o 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.