Partager via


Indexer et interroger des vecteurs dans Azure Cosmos DB for NoSQL dans Python

Avant d’utiliser l’indexation et la recherche vectorielles, vous devez d’abord activer la fonctionnalité. Cet article couvre les étapes suivantes :

  1. Activation de la recherche vectorielle dans Azure Cosmos DB for NoSQL
  2. Configuration du conteneur Azure Cosmos DB pour la recherche vectorielle
  3. Création de la stratégie d’incorporation de vecteurs
  4. Ajout d’index vectoriels à la stratégie d’indexation du conteneur
  5. Création d’un conteneur avec des index vectoriels et une stratégie d’incorporation de vecteurs
  6. Exécution d’une recherche vectorielle sur les données stockées

Ce guide décrit le processus de création de données vectorielles, d’indexation des données, et d’interrogation des données d’un conteneur.

Prérequis

Activer la fonctionnalité

La recherche vectorielle pour Azure Cosmos DB for NoSQL nécessite l’activation de la fonctionnalité en effectuant les étapes suivantes :

  1. Accédez à votre page de ressource Azure Cosmos DB for NoSQL.

  2. Sélectionnez le volet « Fonctionnalités » sous l’élément de menu « Paramètres ».

  3. Sélectionnez « Recherche vectorielle dans Azure Cosmos DB for NoSQL ».

  4. Lisez la description de la fonctionnalité pour confirmer que vous souhaitez l’activer.

  5. Sélectionnez « Activer » pour activer la recherche vectorielle dans Azure Cosmos DB for NoSQL.

    Conseil

    Vous pouvez également utiliser Azure CLI pour mettre à jour les fonctionnalités de votre compte pour prendre en charge la recherche vectorielle NoSQL.

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

Remarque

La demande d’inscription est approuvée automatiquement, mais sa prise d’effet peut parfois prendre 15 minutes.

Les étapes suivantes partent du principe que vous savez configurer un compte NoSQL Cosmos DB et créer une base de données. La fonctionnalité de recherche vectorielle n’est pas prise en charge sur les conteneurs existants. Vous devez donc créer un conteneur, et spécifier la stratégie d’incorporation de vecteurs au niveau du conteneur ainsi que la stratégie d’indexation vectorielle au moment de la création du conteneur.

Prenons l’exemple de la création d’une base de données pour une librairie en ligne. Vous devez stocker le titre, l’auteur, l’ISBN et la description de chaque livre. Nous allons également définir deux propriétés pour contenir les incorporations de vecteurs. La première est la propriété « contentVector », qui contient les incorporations de texte générées à partir du contenu textuel du livre (par exemple, en concaténant les propriétés « title » « author » « isbn » et « description » avant de créer l’incorporation). Le second est la propriété « coverImageVector », qui est générée à partir d’images de la couverture du livre.

  1. Créez et stockez des incorporations de vecteurs pour les champs sur lesquels vous souhaitez effectuer une recherche vectorielle.
  2. Spécifiez les chemins d’accès d’incorporation de vecteurs dans la stratégie d’incorporation de vecteurs.
  3. Incluez les index vectoriels souhaités dans la stratégie d’indexation du conteneur.

Dans les sections suivantes de cet article, nous prenons en compte la structure ci-dessous pour les éléments stockés au sein de notre conteneur :

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

Création d’une stratégie d’incorporation de vecteurs pour votre conteneur

Vous devez ensuite définir une stratégie vectorielle de conteneur. Cette stratégie fournit des informations qui sont utilisées pour indiquer au moteur de requête Azure Cosmos DB comment gérer les propriétés vectorielles dans les fonctions système VectorDistance. Cela permet également d’indiquer les informations nécessaires à la stratégie d’indexation vectorielle, si vous choisissez d’en spécifier une. Les informations suivantes sont incluses dans la stratégie vectorielle contenue :

  • « path » : chemin d’accès de propriété qui contient les vecteurs
  • « datatype » : type des éléments du vecteur (Float32 par défaut)
  • « dimensions » : longueur de chaque vecteur du chemin d’accès (1536 par défaut)
  • « distanceFunction » : métrique utilisée pour calculer la distance/similarité (cosinus par défaut)

Pour notre exemple avec les détails du livre, la stratégie vectorielle peut ressembler à l’exemple JSON :

vector_embedding_policy = { 
    "vectorEmbeddings": [ 
        { 
            "path": "/coverImageVector", 
            "dataType": "float32", 
            "distanceFunction": "dotproduct", 
            "dimensions": 8 
        }, 
        { 
            "path": "/contentVector", 
            "dataType": "float32", 
            "distanceFunction": "cosine", 
            "dimensions": 10 
        } 
    ]    
} 

Création d’un index vectoriel dans la stratégie d’indexation

Une fois les chemins d’accès d’incorporation de vecteurs choisis, les index vectoriels doivent être ajoutés à la stratégie d’indexation. Pour cet exemple, la stratégie d’indexation ressemble à ceci :

indexing_policy = { 
    "includedPaths": [ 
        { 
            "path": "/*" 
        } 
    ], 
    "excludedPaths": [ 
        { 
            "path": "/\"_etag\"/?",
            "path": "/coverImageVector/*",
            "path": "/contentVector/*"
            
        } 
    ], 
    "vectorIndexes": [ 
        {"path": "/coverImageVector", 
         "type": "quantizedFlat" 
        }, 
        {"path": "/contentVector", 
         "type": "quantizedFlat" 
        } 
    ] 
} 

Important

Chemin vectoriel ajouté à la section « excludedPaths » de la stratégie d’indexation pour garantir un niveau de performance optimisé pour l’insertion. Ne pas ajouter le chemin vectoriel à « excludedPaths » entraîne une charge RU et une latence plus élevées pour les insertions vectorielles.

Important

Pour le moment, la recherche vectorielle dans Azure Cosmos DB for NoSQL est prise en charge uniquement sur les nouveaux conteneurs. Vous devez définir à la fois la stratégie vectorielle du conteneur et une stratégie d’indexation vectorielle au moment de la création du conteneur, car aucune modification n’est possible par la suite.

Créer un conteneur avec une stratégie vectorielle

Pour le moment, la fonctionnalité de recherche vectorielle d’Azure Cosmos DB for NoSQL est prise en charge uniquement sur les nouveaux conteneurs. Vous devez donc appliquer la stratégie vectorielle au moment de la création du conteneur. Vous ne pourrez pas la modifier par la suite.

try:     
    container = db.create_container_if_not_exists( 
                    id=CONTAINER_NAME, 
                    partition_key=PartitionKey(path='/id'), 
                    indexing_policy=indexing_policy, 
                    vector_embedding_policy=vector_embedding_policy) 
    print('Container with id \'{0}\' created'.format(id)) 

except exceptions.CosmosHttpResponseError: 
        raise 

Exécution d’une requête de recherche de similarité vectorielle

Une fois que vous avez créé un conteneur avec la stratégie vectorielle souhaitée, et que vous avez inséré des données vectorielles dans le conteneur, vous pouvez effectuer une recherche vectorielle à l’aide de la fonction système Distance vectorielle dans une requête. Supposons que vous souhaitiez rechercher des livres sur les recettes de cuisine en consultant la description, vous devez tout d’abord obtenir les incorporations pour votre texte de requête. Dans ce cas, vous pouvez être amené à générer des incorporations pour le texte de requête « recette de cuisine ». Une fois que vous disposez de l’incorporation pour votre requête de recherche, vous pouvez l’utiliser dans la fonction VectorDistance de la requête de recherche vectorielle, et obtenir tous les éléments similaires à votre requête, comme indiqué ici :

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

Cette requête récupère les titres de livres ainsi que les scores de similarité par rapport à votre requête. Voici un exemple en Python :

query_embedding = [1,2,3,4,5,6,7,8,9,10] 
# Query for items 
for item in container.query_items( 
            query='SELECT c.title, VectorDistance(c.contentVector,@embedding) AS SimilarityScore FROM c ORDER BY VectorDistance(c.contentVector,@embedding)', 
            parameters=[ 
                {"name": "@embedding", "value": query_embedding} 
            ], 
            enable_cross_partition_query=True): 
    print(json.dumps(item, indent=True))