Compartir a través de


Indexación y vectores de consulta en Azure Cosmos DB for NoSQL en Java

En este artículo se explica cómo crear datos vectoriales, indexar los datos y, a continuación, consultarlos en un contenedor.

Antes de usar la indexación y la búsqueda de vectores, primero debe habilitar la búsqueda de vectores en Azure Cosmos DB para NoSQL. Después de configurar el contenedor de Azure Cosmos DB para la búsqueda de vectores, se crea una directiva de inserción de vectores. A continuación, agregará índices vectoriales a la directiva de indexación de contenedores. A continuación, cree un contenedor con índices vectoriales y una directiva de inserción de vectores. Por último, se realiza una búsqueda de vectores en los datos almacenados.

Requisitos previos

Habilitar la característica

Para habilitar la búsqueda de vectores para Azure Cosmos DB para NoSQL, siga estos pasos:

  1. Vaya a la página de recursos de Azure Cosmos DB para NoSQL.
  2. En el panel izquierdo, en Configuración, seleccione Características.
  3. Seleccione Búsqueda de vectores para NoSQL API.
  4. Lea la descripción de la característica para confirmar que desea habilitarla.
  5. Seleccione Habilitar para activar la búsqueda de vectores en Azure Cosmos DB para NoSQL.

Sugerencia

Como alternativa, use la CLI de Azure para actualizar las funcionalidades de su cuenta para admitir la búsqueda de vectores de Azure Cosmos DB para NoSQL.

az cosmosdb update \
     --resource-group <resource-group-name> \
     --name <account-name> \
     --capabilities EnableNoSQLVectorSearch

La solicitud de registro se aprobó automáticamente, pero puede tardar 15 minutos en surtir efecto.

En los pasos siguientes se da por supuesto que sabe cómo configurar una cuenta de Azure Cosmos DB para NoSQL y crear una base de datos. La característica de búsqueda vectorial no se admite actualmente en los contenedores existentes. Debe crear un nuevo contenedor. Al crear el contenedor, se especifica la directiva de inserción de vectores de nivel de contenedor y la directiva de indexación de vectores.

Veamos un ejemplo de cómo crear una base de datos para una librería basada en Internet. Quiere almacenar información de título, autor, ISBN y descripción para cada libro. También debe definir las dos propiedades siguientes para contener incrustaciones de vectores:

  • La contentVector propiedad contiene incrustaciones de texto que se generan a partir del contenido de texto del libro. Por ejemplo, concatenas las propiedades title, author, isbn y description antes de crear la incrustación.
  • La coverImageVector propiedad se genera a partir de imágenes de la portada del libro.

Para realizar una búsqueda vectorial, haga lo siguiente:

  1. Cree y almacene incrustaciones de vectores para los campos en los que desea realizar el vector de búsqueda.
  2. Especifique las rutas de acceso de inserción de vectores en la directiva de inserción de vectores.
  3. Incluya los índices vectoriales que desee en la directiva de indexación para el contenedor.

Para las secciones posteriores de este artículo, tenga en cuenta la siguiente estructura para los elementos almacenados en el contenedor:

{
  "title": "book-title", 
  "author": "book-author", 
  "isbn": "book-isbn", 
  "description": "book-description", 
  "contentVector": [2, -1, 4, 3, 5, -2, 5, -7, 3, 1], 
  "coverImageVector": [0.33, -0.52, 0.45, -0.67, 0.89, -0.34, 0.86, -0.78] 
} 

En primer lugar, cree el objeto CosmosContainerProperties.

CosmosContainerProperties collectionDefinition = new CosmosContainerProperties(UUID.randomUUID().toString(), "Partition_Key_Def");

Creación de una directiva de inserción de vectores para el contenedor

Ahora debe definir una directiva de vectores de contenedor. Esta directiva proporciona información que informa al motor de consultas de Azure Cosmos DB sobre cómo controlar las propiedades vectoriales en las funciones del VectorDistance sistema. Esta directiva también proporciona información necesaria a la directiva de indexación de vectores, si decide especificar una.

La siguiente información se incluye en la política de vectores de contenedores:

Parámetro Description
path La propiedad path que contiene vectores.
datatype Tipo de los elementos del vector. El valor predeterminado es Float32.
dimensions Longitud de cada vector de la ruta de acceso. El valor predeterminado es 1536.
distanceFunction Métrica que se usa para calcular la distancia o similitud. El valor predeterminado es Cosine.

En el ejemplo con detalles del libro, la directiva de vectores podría ser similar al ejemplo siguiente:

// Creating vector embedding policy
CosmosVectorEmbeddingPolicy cosmosVectorEmbeddingPolicy = new CosmosVectorEmbeddingPolicy();

CosmosVectorEmbedding embedding1 = new CosmosVectorEmbedding();
embedding1.setPath("/coverImageVector");
embedding1.setDataType(CosmosVectorDataType.FLOAT32);
embedding1.setDimensions(8L);
embedding1.setDistanceFunction(CosmosVectorDistanceFunction.COSINE);

CosmosVectorEmbedding embedding2 = new CosmosVectorEmbedding();
embedding2.setPath("/contentVector");
embedding2.setDataType(CosmosVectorDataType.FLOAT32);
embedding2.setDimensions(10L);
embedding2.setDistanceFunction(CosmosVectorDistanceFunction.DOT_PRODUCT);

cosmosVectorEmbeddingPolicy.setCosmosVectorEmbeddings(Arrays.asList(embedding1, embedding2, embedding3));

collectionDefinition.setVectorEmbeddingPolicy(cosmosVectorEmbeddingPolicy);

Creación de un índice vectorial en la directiva de indexación

Después de decidir las rutas para la incrustación de vectores, debe agregar índices vectoriales a la directiva de indexación. Actualmente, la característica de búsqueda de vectores para Azure Cosmos DB para NoSQL solo se admite en nuevos contenedores. Al crear el contenedor, se aplica la directiva de vectores. No se puede modificar la directiva más adelante. La directiva de indexación tiene un aspecto similar al del ejemplo siguiente:

IndexingPolicy indexingPolicy = new IndexingPolicy();
indexingPolicy.setIndexingMode(IndexingMode.CONSISTENT);
ExcludedPath excludedPath1 = new ExcludedPath("/coverImageVector/*");
ExcludedPath excludedPath2 = new ExcludedPath("/contentVector/*");
indexingPolicy.setExcludedPaths(ImmutableList.of(excludedPath1, excludedPath2));

IncludedPath includedPath1 = new IncludedPath("/*");
indexingPolicy.setIncludedPaths(Collections.singletonList(includedPath1));

// Creating vector indexes
CosmosVectorIndexSpec cosmosVectorIndexSpec1 = new CosmosVectorIndexSpec();
cosmosVectorIndexSpec1.setPath("/coverImageVector");
cosmosVectorIndexSpec1.setType(CosmosVectorIndexType.QUANTIZED_FLAT.toString());

CosmosVectorIndexSpec cosmosVectorIndexSpec2 = new CosmosVectorIndexSpec();
cosmosVectorIndexSpec2.setPath("/contentVector");
cosmosVectorIndexSpec2.setType(CosmosVectorIndexType.DISK_ANN.toString());

indexingPolicy.setVectorIndexes(Arrays.asList(cosmosVectorIndexSpec1, cosmosVectorIndexSpec2, cosmosVectorIndexSpec3));

collectionDefinition.setIndexingPolicy(indexingPolicy);

Por último, cree el contenedor con la directiva de índice de contenedor y la directiva de índice de vectores.

database.createContainer(collectionDefinition).block();

Importante

Ruta de acceso vectorial agregada a la sección excludedPaths de la directiva de indexación para garantizar un rendimiento optimizado para la inserción. No agregar la ruta de acceso del vector a excludedPaths da como resultado una mayor carga de unidad de solicitud y latencia para las inserciones vectoriales.

Ejecución de una consulta de búsqueda de similitud vectorial

Después de crear un contenedor con la directiva de vectores que desea e insertar datos vectoriales en el contenedor, use la función del sistema VectorDistance en una consulta para realizar una búsqueda vectorial.

Supongamos que desea buscar libros sobre recetas de alimentos examinando la descripción. Primero debe obtener las incrustaciones para el texto de la consulta. En este caso, es posible que quiera generar incrustaciones para el texto food recipede consulta . Después de tener la inserción de la consulta de búsqueda, puede usarla en la función VectorDistance de la consulta de búsqueda vectorial para obtener todos los elementos similares a la consulta:

SELECT TOP 10 c.title, VectorDistance(c.contentVector, [1,2,3,4,5,6,7,8,9,10]) AS SimilarityScore   
FROM c  
ORDER BY VectorDistance(c.contentVector, [1,2,3,4,5,6,7,8,9,10])   

Esta consulta recupera los títulos del libro junto con puntuaciones de similitud con respecto a la consulta. Este es un ejemplo en Java:

float[] embedding = new float[10];
for (int i = 0; i < 10; i++) {
    array[i] = i + 1;
}
ArrayList<SqlParameter> paramList = new ArrayList<SqlParameter>();
  paramList.add(new SqlParameter("@embedding", embedding));
  SqlQuerySpec querySpec = new SqlQuerySpec("SELECT c.title, VectorDistance(c.contentVector,@embedding) AS SimilarityScore  FROM c ORDER BY VectorDistance(c.contentVector,@embedding)", paramList);
  CosmosPagedIterable<Family> filteredFamilies = container.queryItems(querySpec, new CosmosQueryRequestOptions(), Family.class);

  if (filteredFamilies.iterator().hasNext()) {
      Family family = filteredFamilies.iterator().next();
      logger.info(String.format("First query result: Family with (/id, partition key) = (%s,%s)",family.getId(),family.getLastName()));
  }