En esta página, se describe cómo realizar búsquedas híbridas de texto completo y vectoriales en Spanner. La búsqueda híbrida combina la precisión de la concordancia de palabras clave (búsqueda de texto completo, FTS) con la recuperación de la concordancia semántica (búsqueda de vectores) para producir resultados de búsqueda muy relevantes.
Spanner admite los siguientes patrones de búsqueda híbrida, que se dividen en tres categorías principales:
| Categoría | Descripción | Objetivo principal |
| Fusion | Fusion recupera y clasifica documentos de forma independiente con la búsqueda por palabras clave y la búsqueda de vectores, y, luego, combina (fusiona) los resultados. | Combina varios indicadores de puntuación para lograr la máxima recuperación y relevancia. |
| Filtrado | Las palabras clave filtran o definen mejor el espacio de búsqueda. | Asegúrate de que la coincidencia de palabras clave sea un requisito mientras aprovechas la relevancia semántica. |
| Clasificación basada en AA | Un modelo de aprendizaje automático refina un conjunto inicial de candidatos para obtener una clasificación final más precisa. | Lograr la mayor precisión posible para un pequeño conjunto final de resultados |
Búsqueda combinada
La búsqueda combinada implica ejecutar la FTS y la búsqueda vectorial de forma independiente en el mismo corpus de datos. Luego, combina los resultados para crear una lista clasificada única, unificada y muy pertinente.
Si bien puedes ejecutar consultas independientes del lado del cliente, la búsqueda híbrida en Spanner ofrece las siguientes ventajas:
- Simplifica la lógica de la aplicación administrando las solicitudes paralelas y la combinación de resultados en el servidor.
- Evita transferir al cliente conjuntos de resultados intermedios potencialmente grandes.
Puedes usar SQL para crear métodos de fusión en Spanner. En esta sección, se proporcionan ejemplos de la fusión de clasificación recíproca y la fusión de puntuación relativa. Sin embargo, te recomendamos que evalúes diferentes estrategias de fusión para determinar cuál se adapta mejor a los requisitos de tu aplicación.
Fusión basada en el ranking
Usa la fusión basada en el ranking cuando las puntuaciones de relevancia de diferentes métodos de recuperación (como las puntuaciones de FTS y las distancias vectoriales) sean difíciles de comparar o normalizar porque se miden en diferentes espacios. Este método usa la posición de clasificación de cada documento de cada recuperador para generar una puntuación y una clasificación finales.
La fusión de clasificación recíproca (RRF) es una función de fusión basada en la clasificación. La puntuación del RRF para un documento es la suma de los recíprocos de sus rangos de múltiples recuperadores y se calcula de la siguiente manera:
\[ score\ (d\epsilon D)\ =\ \sum\limits_{r\epsilon R}^{}(1\ /\ (\ 𝑘\ +\ ran{k}_{r}\ (𝑑)\ )\ )\ \]
Aquí:
- d es el documento.
- R es el conjunto de recuperadores (búsqueda de texto completo y búsqueda de vectores).
- k es una constante (a menudo establecida en 60) que se usa para moderar la influencia de los documentos con una clasificación muy alta.
- w es la clasificación del documento del recuperador r.
Implementa el RR en una consulta de Spanner
Las métricas de vectores (como APPROX_DOT_PRODUCT) y las puntuaciones de búsqueda de texto (como SCORE_NGRAMS) operan en escalas incompatibles. Para resolver este problema, en el siguiente ejemplo, se implementa el RR para normalizar los datos según la posición del ranking en lugar de las puntuaciones sin procesar.
La consulta usa UNNEST(ARRAY(...) WITH OFFSET para asignar una clasificación a los 100 candidatos principales de cada método. Luego, calcula una puntuación estandarizada con la inversa de esas clasificaciones y agrega los resultados para devolver las cinco coincidencias principales.
SELECT SUM(1 / (60 + rank)) AS rrf_score, key
FROM (
(
SELECT rank, x AS key
FROM UNNEST(ARRAY(
SELECT key
FROM hybrid_search
WHERE embedding IS NOT NULL
ORDER BY APPROX_DOT_PRODUCT(@vector, embedding,
OPTIONS => JSON '{"num_leaves_to_search": 50}') DESC
LIMIT 100)) AS x WITH OFFSET AS rank
)
UNION ALL
(
SELECT rank, x AS key
FROM UNNEST(ARRAY(
SELECT key
FROM hybrid_search
WHERE SEARCH_NGRAMS(text_tokens_ngrams, 'foo')
ORDER BY SCORE_NGRAMS(text_tokens_ngrams, 'foo') DESC
LIMIT 100)) AS x WITH OFFSET AS rank
)
)
GROUP BY key
ORDER BY rrf_score DESC
LIMIT 5;
Fusión basada en la puntuación
La fusión basada en la puntuación es eficaz cuando las puntuaciones de relevancia de diferentes métodos son comparables o se pueden normalizar, lo que podría permitir una clasificación más precisa que incorpore el peso de relevancia real de cada método.
La fusión de puntuación relativa (RSF) es un método basado en la puntuación que normaliza las puntuaciones de diferentes métodos en relación con las puntuaciones más altas y más bajas dentro de cada método, por lo general, con las funciones MIN() y MAX(). La puntuación de RSF de un documento recuperado por un conjunto de recuperadores se calcula de la siguiente manera:
\[ score(d\epsilon D)\ =\ \sum\limits_{r\epsilon R}^{}({w}_{r}*(scor{e}_{r}(d)\ -\ mi{n}_{r})\ /\ (ma{x}_{r\ }-mi{n}_{r})\ ) \]
Aquí:
- d es el documento.
- R es el conjunto de recuperadores (búsqueda de texto completo y búsqueda de vectores).
- w es el peso asignado a un recuperador específico.
Implementa RSF en una consulta de Spanner
Para implementar el RSF, debes normalizar las puntuaciones del vector y del FTS en una escala común. En el siguiente ejemplo, se calculan las puntuaciones mínima y máxima en cláusulas WITH separadas para derivar los factores de normalización. Luego, combina los resultados con un FULL OUTER JOIN, sumando las puntuaciones normalizadas de la búsqueda de vecino más cercano aproximado (ANN) (convertida de cosine_distance) y la FTS.
WITH ann AS (
SELECT key, APPROX_COSINE_DISTANCE(@vector, embedding,
OPTIONS => JSON '{"num_leaves_to_search": 50}') AS cosine_distance,
FROM hybrid_search
WHERE embedding IS NOT NULL
ORDER BY cosine_distance
LIMIT 100
),
fts AS (
SELECT key, SCORE_NGRAMS(text_tokens_ngrams, 'Green') AS score,
FROM hybrid_search
WHERE SEARCH_NGRAMS(text_tokens_ngrams, 'Green')
ORDER BY score DESC
LIMIT 100
),
ann_min AS (
SELECT MIN(1 - cosine_distance) AS min
FROM ann
),
ann_max AS (
SELECT MAX(1 - cosine_distance) AS max
FROM ann
),
fts_min AS (
SELECT MIN(score) AS min
FROM fts
),
fts_max AS (
SELECT MAX(score) AS max
FROM fts
)
SELECT IFNULL(ann.key, fts.key),
IFNULL(((1 - ann.cosine_distance) - ann_min.min) /
(ann_max.max - ann_min.min), 0) +
IFNULL((fts.score - fts_min.min) /
(fts_max.max - fts_min.min), 0) AS score
FROM ann
FULL OUTER JOIN fts
ON ann.key = fts.key
CROSS JOIN ann_min
CROSS JOIN ann_max
CROSS JOIN fts_min
CROSS JOIN fts_max
ORDER BY score DESC
LIMIT 5;
Búsqueda filtrada
Las búsquedas filtradas usan FTS para crear un filtro que reduce el conjunto de documentos considerados para una búsqueda vectorial de k-vecinos más cercanos (KNN). De manera opcional, puedes usar una clasificación previa para limitar el tamaño del conjunto de resultados.
Implementa la búsqueda filtrada en una consulta de Spanner
La búsqueda de ejemplo en esta sección sigue los siguientes pasos para reducir el espacio de búsqueda de vectores al subconjunto de datos que coinciden con las palabras clave:
- Usa
SEARCH (text_tokens, 'Green')para encontrar filas en las que la columnatext_tokenscontiene el textoGreen. Las primeras 1,000 filas se muestran en un orden de clasificación definido por el índice de búsqueda. - Usa una función de vector,
DOT_PRODUCT(@vector, embedding), para calcular la similitud entre el vector de búsqueda (@vector) y el vector de documento almacenado (embedding). Luego, ordena los resultados y muestra las 10 coincidencias principales finales.
SELECT key
FROM (
SELECT key, embedding
FROM hybrid_search
WHERE SEARCH (text_tokens, 'Green')
ORDER BY presort
LIMIT 1000)
ORDER BY DOT_PRODUCT(@vector, embedding) DESC
LIMIT 10;
Clasificación con AA
El nuevo ranking basado en AA es un enfoque preciso, pero que requiere una gran cantidad de procesamiento. Aplica un modelo de aprendizaje automático a un pequeño conjunto de candidatos que se redujo con la FTS, la búsqueda de vectores o una combinación de ambas. Para obtener más información sobre la integración de Vertex AI en Spanner, consulta la descripción general de la integración de Vertex AI en Spanner.
Puedes integrar la clasificación basada en AA con la función ML.PREDICT de Spanner y un modelo de Vertex AI implementado.
Implementa la clasificación basada en AA
- Implementa un modelo de reranking (por ejemplo, de HuggingFace) en un extremo de Vertex AI.
Crea un objeto
MODELde Spanner que apunte al extremo de Vertex AI. Por ejemplo, en el siguiente ejemplo de modeloReranker:text ARRAY<string(max)>son los documentos.text_pair ARRAY<string(max)>es el texto de la búsqueda en el ejemplo.scoreson las puntuaciones de relevancia que asigna el modelo de AA a los pares de textos de entrada.
CREATE MODEL Reranker INPUT (text ARRAY<string(max)>, text_pair ARRAY<string(max)>) OUTPUT (score FLOAT32) REMOTE OPTIONS ( endpoint = '...' );Usa una subconsulta para recuperar los candidatos iniciales (como los 100 resultados principales de una búsqueda de ANN) y pasarlos a
ML.PREDICT. La función devuelve una nueva columna de puntuación para la ordenación final.SELECT key FROM ML.PREDICT( MODEL Reranker, ( SELECT key, text, "gift for 8-year-old" AS text_pair FROM hybrid_search WHERE embedding IS NOT NULL ORDER BY APPROX_DOT_PRODUCT(@vector, embedding, options=>JSON '{"num_leaves_to_search": 50}') DESC LIMIT 100) ) ORDER BY score DESC LIMIT 3;
¿Qué sigue?
- Personaliza tu motor de búsqueda con la búsqueda híbrida potenciada por IA en Spanner.
- Obtén más información sobre la búsqueda en el texto completo.