Busca y filtra con embeddings de vectores

En esta página, se describen las diferentes formas en que puedes consultar las incorporaciones de vectores. Para obtener una descripción general de las búsquedas de similitud de ANN y KNN, consulta búsquedas de vectores.

Búsqueda de vecino más cercano aproximado (ANN)

Para realizar una búsqueda de ANN, usa la función approx_distance en una cláusula SELECT y ORDER BY. Debes usar una cláusula LIMIT en una búsqueda de ANN. También puedes obtener el valor de la distancia si colocas approx_distance en una lista SELECT.

Usa la siguiente sintaxis para las consultas de ANN:

# Ordering by distance
SELECT title
FROM books
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
LIMIT 4;

# Selecting the distance value
SELECT
  approx_distance(
    embedding_name,
    string_to_vector('[1,2,3]'),
    'distance_measure=cosine,num_leaves_to_search=3')
    dist
FROM table
ORDER BY dist
LIMIT limit_value;

La función approx_distance usa las siguientes opciones:

  • embedding: Usa el nombre de la columna de incorporación vectorial de la tabla base.
  • string_to_vector o vector_to_string: Convierte un vector en una cadena y una cadena en un vector para que el vector sea legible por humanos.
  • distance_measure: Especifica la medida de distancia que se usará para una búsqueda de similitud de vectores. Este valor debe coincidir con el que estableciste en el parámetro distance_measure cuando creaste el índice. Este parámetro es obligatorio. Los valores posibles de este parámetro son los siguientes:
    • COSINE
    • L2_SQUARED
    • DOT_PRODUCT
  • num_leaves_to_search: Opcional. Especifica la cantidad de hojas que se sondearán para una búsqueda de similitud de vectores de ANN. Si no especificas la cantidad de hojas, Cloud SQL usa un valor generado según el tamaño de la tabla, la cantidad de hojas en el índice de vectores y otros factores. Puedes ver este valor en information_schema.innodb_vector_indexes. Te recomendamos que ajustes num_leaves_to_search para lograr el mejor equilibrio entre la calidad de la búsqueda y el rendimiento de tu carga de trabajo específica. Si se aumenta, afecta el rendimiento, pero mejora la recuperación.

En el siguiente ejemplo, se muestra cómo usar approx_distance para encontrar las K filas más cercanas con la medición de distancia l2_squared y ordenar los resultados por distancia.

# Ordering by distance
SELECT title
FROM books
ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'),
                         'distance_measure=l2_squared')
LIMIT 4;

# Selecting the distance value
SELECT
    approx_distance
        (embedding, string_to_vector('[1,2,3]'),
         'distance_measure=l2_squared') dist
FROM table
ORDER BY dist
LIMIT 4;

Cómo filtrar los resultados de las consultas de approx_distance

Puedes usar la función approx_distance con condiciones WHERE que filtren los resultados de la consulta con un predicado no vectorial para realizar el filtrado posterior. La función approx_distance se evalúa antes de aplicar el filtro, lo que significa que la cantidad de resultados que se muestran no es determinista.

Por ejemplo, en la siguiente consulta:

SELECT id FROM products WHERE price < 100
ORDER BY approx(embedding, @query_vector,'distance_measure=cosine')
LIMIT 11;

La función approx_distance muestra los 11 vecinos más cercanos al vector de consulta, independientemente del precio. En el filtrado posterior, se seleccionan los productos con un precio inferior a 100. Es posible que todos los vecinos más cercanos tengan un precio inferior a 100, por lo que hay 11 resultados para la consulta. Como alternativa, si ninguno de los vecinos más cercanos tiene un precio inferior a 100, no se muestra ninguna fila.

Si anticipas que tu filtro en la condición WHERE es muy selectivo, una búsqueda exacta (KNN) podría ser una mejor opción para garantizar que se muestre una cantidad suficiente de filas.

Verifica el estado de resguardo en las búsquedas de ANN

En algunos casos, una búsqueda de ANN recurre a una búsqueda de KNN. Entre estos, se incluyen los siguientes:

  • No hay un índice vectorial en la tabla base.
  • Hay un índice de vectores en la tabla base, pero usa una medida de distancia diferente del parámetro distance_measure en las opciones de búsqueda approx_distance.
  • El índice vectorial está dañado o es invisible para la transacción actual.
  • El LIMIT especificado es mayor que 10,000.
  • No se especificó LIMIT.
  • La consulta actual incluye más de una llamada a approx_distance en la misma tabla base.
  • El optimizador calcula que es más eficiente usar KNN.

En todos estos casos, se envía una advertencia al cliente en la que se indica que se realizó la búsqueda exacta y el motivo.

Usa el siguiente comando en el cliente mysql para ver el estado de resguardo:

SHOW global status LIKE '%cloudsql_vector_knn_fallback%';

Si quieres usar ANN y se recurre a KNN, es posible que la consulta se ejecute más lento. Debes encontrar el motivo por el que se recurre a la ANN y evaluar si debes hacer cambios para que se use en su lugar.

Ejemplo: Crea un índice vectorial y ejecuta una consulta de ANN

En la siguiente explicación de ejemplo, se proporcionan pasos para crear un índice de vectores y ejecutar una consulta de ANN en Cloud SQL.

  1. Genera embeddings de vectores. Puedes crear embeddings de vectores de forma manual o usar una API de embedding de texto que elijas. Para ver un ejemplo que usa Vertex AI, consulta Genera embeddings de vectores según los datos de la fila.
  2. Crea una tabla en Cloud SQL que contenga una columna de embedding de vectores con tres dimensiones.

    CREATE TABLE books(
    id INTEGER PRIMARY KEY AUTO_INCREMENT, title VARCHAR(60), embedding VECTOR(3) USING VARBINARY);
    
  3. Inserta un embedding de vectores en la columna.

    INSERT INTO books VALUES ((1, 'book title', string_to_vector('[1,2,3]')));
    
  4. Confirma los cambios.

    commit;
    
  5. Crea el índice de vectores con la función L2_squared para medir la distancia.

    CREATE
      VECTOR INDEX vectorIndex
    ON dbname.books(embeddings)
    USING SCANN QUANTIZER = SQ8 DISTANCE_MEASURE = l2_squared;
    
  6. Usa la siguiente sintaxis para realizar una búsqueda de ANN con un LIMIT de 4 resultados de búsqueda:

    SELECT title
    FROM books
    ORDER BY approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=l2_squared')
    LIMIT 4;
    
    SELECT approx_distance(embedding, string_to_vector('[1,2,3]'), 'distance_measure=cosine') dist
    FROM books
    ORDER BY dist
    LIMIT 4;
    

Búsqueda de k-vecinos más cercanos (KNN)

Para realizar una búsqueda de vecino más cercano, usa la función vector_distance con una opción de medición de distancia y una función de conversión de vectores (string_to_vector o vector_to_string) en una sentencia SELECT. Usa la siguiente sintaxis:

SELECT vector_distance(string_to_vector('[1,2,3]'),
                      string_to_vector('[1,2,3]'),
                      'Distance_Measure=dot_product');

Reemplaza los valores [1,2,3] por los valores de incorporación de tus datos.

En el siguiente ejemplo, se muestra cómo usar esta consulta con la función cosine_distance y la función de conversión de vectores string_to_vector.

SELECT id,cosine_distance(embedding, string_to_vector('[1,2,3]')) dist
FROM books
ORDER BY distance
LIMIT 10;

Obtén la distancia de coseno en una consulta de KNN

Usa la función cosine_distance de Cloud SQL para calcular la distancia con el coseno.

SELECT cosine_distance(embedding, string_to_vector('[3,1,2]')) AS distance FROM books WHERE id = 10;

Obtén la distancia del producto punto en una consulta de KNN

Usa la función dot_product de Cloud SQL para calcular la distancia con el producto punto.

SELECT dot_product(embedding, string_to_vector('[3,1,2]')) AS distance FROM books WHERE id = 10;

Obtén la distancia de L2 al cuadrado en una consulta de KNN

Usa la función l2_squared_distance de Cloud SQL para calcular la distancia con L2 al cuadrado.

SELECT
  l2_squared_distance(embedding, string_to_vector('[3,1,2]'))
    AS distance
FROM books
WHERE id = 10;

¿Qué sigue?