Adición de un filtro en una consulta vectorial en Búsqueda de Azure AI
Puede definir una solicitud de consulta vectorial que incluya una expresión de filtro para agregar criterios de inclusión o exclusión a las consultas. En este artículo, aprenderá a:
En este artículo se usa REST para ilustrarlo. Para ver ejemplos de código en otros lenguajes, consulte el repositorio de GitHub azure-search-vector-samples para soluciones de un extremo a otro que incluyen consultas vectoriales.
También puede usar el Explorador de búsqueda en Azure Portal para consultar contenido vectorial. Si usa la vista JSON, puede agregar filtros y especificar el modo de filtro.
Funcionamiento del filtrado en una consulta vectorial
Los filtros se aplican a campos filterable
no vectoriales, ya sea un campo de cadena o numérico, para incluir o excluir documentos de búsqueda en función de los criterios de filtro. Aunque un campo vectorial no se puede filtrar por sí mismo, los filtros se pueden aplicar a otros campos del mismo índice, incluyendo o excluyendo los documentos que también contienen campos vectoriales.
Los filtros se aplican antes o después de la ejecución de consultas en función del parámetro vectorFilterMode
.
Definición de un filtro
Los filtros determinan el ámbito de una consulta vectorial. Los filtros se establecen e iteran los campos numéricos y de cadena que se atribuyen como filterable
en el índice, pero el propósito del filtro determina sobre qué se ejecuta la consulta vectorial: todo el espacio que se puede buscar o el contenido de un resultado de búsqueda.
Si no tiene campos de origen con valores numéricos o de texto, compruebe si hay metadatos de documento, como las propiedades LastModified o CreatedBy, que podrían resultar útiles en un filtro de metadatos.
2024-07-01 es la versión estable de esta API. Tiene:
vectorFilterMode
para los modos de filtrado prefiltro (predeterminado) o postfiltro.filter
proporciona los criterios.
En el ejemplo siguiente, el vector es una representación de esta cadena de consulta: "qué servicios de Azure admiten la búsqueda de texto completo". La consulta tiene como destino el campo contentVector
. El vector real tiene 1 536 incrustaciones, por lo que se recorta en este ejemplo para mejorar la legibilidad.
Los criterios de filtro se aplican a un campo de texto filtrable (category
en este ejemplo) antes de que el motor de búsqueda ejecute la consulta vectorial.
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
}
]
}
Establecer vectorFilterMode
El parámetro de consulta vectorFilterMode determina si el filtro se aplica antes o después de la ejecución de la consulta vectorial.
Uso del modo de prefiltro
El filtrado previo aplica filtros antes de la ejecución de la consulta, lo que reduce el área expuesta de búsqueda sobre la que el algoritmo del vector de búsqueda busca contenido similar.
En una consulta vectorial, preFilter
es el valor predeterminado.
Uso del modo de postfiltro
El filtrado posterior aplica filtros después de la ejecución de la consulta, lo que limita los resultados de la búsqueda.
Punto de referencia de comparación de modos de filtro vectorial
Para comprender las condiciones en las que un modo de filtro funciona mejor que el otro, hemos ejecutado una serie de pruebas para evaluar los resultados de las consultas en índices pequeños, medianos y grandes.
- Pequeño (100 000 documentos, índice de 2,5 GB, 1536 dimensiones)
- Mediando (1 millón de documentos, índice de 25 GB, 1536 dimensiones)
- Grande (Mil millones de documentos, índice de 1.9 GB, 96 dimensiones)
Para las cargas de trabajo pequeñas y medianas, usamos un servicio Standard 2 (S2) con una partición y una réplica. Para la carga de trabajo grande, usamos un servicio Standard 3 (S3) con 12 particiones y una réplica.
Los índices tenían una construcción idéntica: un campo clave, un campo vectorial, un campo de texto y un campo filtrable numérico. El siguiente índice se define mediante la sintaxis 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"
}
]
}
}
En las consultas, hemos usado un filtro idéntico para las operaciones de prefiltro y postfiltro. Usamos un filtro sencillo para asegurarnos de que las variaciones en el resultado se deben al modo de filtrado y no a la complejidad del filtro.
Los resultados se midieron en consultas por segundo (QPS).
Puntos clave
El filtrado previo es casi siempre más lento que el posterior, excepto en índices pequeños en los que el rendimiento es aproximadamente igual.
En conjuntos de datos más grandes, el filtrado previo es más lento.
¿Por qué el valor predeterminado es el filtrado previo si casi siempre es más lento? El filtrado previo garantiza que
k
resultados se devuelvas si existen en el índice, donde el sesgo favorece la recuperación y la precisión con respecto a la velocidad.El filtrado posterior es para los clientes que:
- valoran la velocidad por encima de la selección (el filtrado posterior puede devolver menos de
k
resultados) - usar filtros que no son demasiado selectivos
- tienen índices de tamaño suficiente, de modo que el rendimiento del prefiltro es inaceptable
- valoran la velocidad por encima de la selección (el filtrado posterior puede devolver menos de
Detalles
Si tenemos un conjunto de datos con 100 000 vectores en 1536 dimensiones:
- Al filtrar más del 30 % del conjunto de datos, el filtrado previo y el posterior fueron similares.
- Al filtrar menos del 0,1 % del conjunto de datos, el filtrado previo fue aproximadamente un 50 % más lento que el posterior.
Si tenemos un conjunto de datos con 1 millón de vectores en 1536 dimensiones:
- Al filtrar más del 30 % del conjunto de datos, el filtrado previo fue aproximadamente un 30 % más lento.
- Al filtrar menos del 2 % del conjunto de datos, el filtrado previo fue aproximadamente siete veces más lento.
Si tenemos un conjunto de datos con mil millones de vectores en 96 dimensiones:
- Al filtrar más del 5 % del conjunto de datos, el filtrado previo fue aproximadamente un 50 % más lento.
- Al filtrar menos del 10 % del conjunto de datos, el filtrado previo fue aproximadamente siete veces más lento.
En el gráfico siguiente se muestran las QPS relativo al prefiltro, calculadas como QPS de prefiltro divididas por QPS de postfiltro.
El eje vertical es QPS de prefiltro sobre QPS de postfiltro. Por ejemplo, un valor de 0,0 significa que el filtrado previo es un 100 % más lento, 0,5 en el eje vertical significa que el filtrado previo es un 50 % más lento, 1,0 significa que el filtrado previo y el filtrado posterior son equivalentes.
El eje horizontal representa la tasa de filtrado o el porcentaje de documentos candidatos después de aplicar el filtro. Por ejemplo, 1.00%
significa que el criterio de filtro seleccionó un porcentaje del corpus de búsqueda.