La recherche vectorielle est une technologie clé pour effectuer des recherches de similarité efficaces. Cette rubrique explique comment implémenter rapidement la recherche vectorielle à l'aide d'exemples détaillés.
Prérequis
-
La bibliothèque PyMilvus est installée sur votre client local et mise à jour vers la dernière version.
Pour installer ou mettre à jour la bibliothèque PyMilvus, exécutez la commande suivante.
pip install --upgrade pymilvus Une instance Milvus a été créée. Pour plus d'informations, consultez la rubrique Créer une instance Milvus.
Notes
Alibaba Cloud AISearch for Milvus (Milvus) prend en charge les connexions via un réseau interne et Internet. Avant de vous connecter à une instance Milvus, assurez-vous que votre client dispose des autorisations d'accès au réseau requises. Pour plus d'informations, consultez la rubrique Paramètres d'accès au réseau et de sécurité.
Procédure
Étape 1 : Se connecter à une instance Milvus
Utilisez le code suivant pour vous connecter à une instance Milvus.
from pymilvus import MilvusClient
# Create a Milvus client.
client = MilvusClient(
uri="http://c-xxxx.milvus.aliyuncs.com:19530", # The public endpoint of the Milvus instance.
token="<yourUsername>:<yourPassword>", # The username and password to log on to the Milvus instance.
db_name="default" # The name of the database to connect to. This example uses the default database.
)
Étape 2 : Créer une collection
Utilisez le code suivant pour créer une collection. Pour plus d'options de paramètres personnalisés, consultez la rubrique Gérer les collections.
client.create_collection(
collection_name="demo", # The name of the collection.
dimension=5 # The vector dimensions.
)
Ce code définit le nom de la collection et les dimensions du vecteur. Il applique également automatiquement les configurations suivantes :
Utilise les noms par défaut pour le champ de clé primaire « id » et le champ de vecteur « vector ».
La propriété « metric_type » utilise par défaut le type de métrique COSINE.
Définit le champ de clé primaire « id » comme un entier. Sa valeur n'est pas incrémentée automatiquement.
Ajoute un champ supplémentaire « $meta » pour stocker les données des champs non définis dans le schéma sous forme de paires clé-valeur.
Étape 3 : Insérer des données
Après avoir créé une collection, le système charge automatiquement la collection et son index en mémoire. Utilisez le code suivant pour insérer des données de test dans la collection.
Insérer une petite quantité de données
Ce code insère 10 entités prédéfinies. Chaque entité possède un vecteur fixe et un tag de couleur.
data=[{'id': 0, 'vector': [-0.493313706583155, -0.172001225836391, 0.16825615330139554, -0.0198911518739604, -0.9756816265213708], 'color': 'green_5760'}, {'id': 1, 'vector': [0.6695699219225086, 0.49952523907354496, -0.49870548178008534, 0.8824655547230731, -0.7182693622931615], 'color': 'blue_2330'}, {'id': 2, 'vector': [-0.6057771959702387, 0.9141473782193543, 0.32053983678483466, -0.32126010092015655, 0.725222856037071], 'color': 'grey_9673'}, {'id': 3, 'vector': [0.14082089434165868, 0.9924029949938447, 0.7943279666144052, -0.7898608705081103, -0.9941425813199956], 'color': 'white_2829'}, {'id': 4, 'vector': [-0.46180540826224026, 0.33216876051895783, 0.5786699695956004, 0.8891120357625131, 0.04872530176990697], 'color': 'pink_9061'}, {'id': 5, 'vector': [-0.6097452740606673, 0.35648319550551144, -0.5699789153006387, 0.15085357921088316, -0.8817226997144627], 'color': 'pink_8525'}, {'id': 6, 'vector': [0.7843522543512762, -0.7663837586858071, -0.8681839054724569, 0.6880645348647785, -0.5151293183261791], 'color': 'green_5016'}, {'id': 7, 'vector': [-0.9967116931989293, 0.5741923070732655, -0.019126124261334976, -0.34163875885482753, -0.8189843931354175], 'color': 'brown_7434'}, {'id': 8, 'vector': [0.7347243385915765, -0.7358853080124825, -0.23737428377511716, 0.06980552357261627, -0.30613964550461437], 'color': 'blue_5059'}, {'id': 9, 'vector': [-0.21187155428455862, -0.3288541717216129, -0.32564136453418824, -0.14054963599686743, 0.5491320339870627], 'color': 'yellow_9887'}]
res = client.insert(
collection_name="demo",
data=data
)
Insérer davantage de données
Ce code utilise une compréhension de liste pour générer dynamiquement de nombreuses entités. Les vecteurs et les tags de couleur de ces entités sont générés aléatoirement dans une plage spécifiée.
import random
colors = ["green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey"]
data = [ {
"id": i,
"vector": [ random.uniform(-1, 1) for _ in range(5) ],
"color": f"{random.choice(colors)}_{str(random.randint(1000, 9999))}"
} for i in range(1000) ]
res = client.insert(
collection_name="demo",
data=data[1:]
)
print(res)
Étape 4 : Recherche vectorielle
L'insertion des données est un processus asynchrone. Après l'insertion des données, le système ne met pas immédiatement à jour l'index de recherche. Pour interroger les dernières données, attendez quelques secondes que l'index soit mis à jour avant d'effectuer la recherche.
Recherche vectorielle unique
Pour effectuer une recherche de similarité, fournissez une liste contenant un seul vecteur de requête.
query_vectors = [
[-0.8832567462711804, -0.2999882617491647, 0.9921295273224382, -0.272575369985379, -0.688914679645338]
]
res = client.search(
collection_name="demo", # The collection to query
data=query_vectors, # The query vectors.
limit=3, # The number of entities to return.
)
print(res)
Recherche vectorielle par lot
Pour une recherche par lot avec plusieurs vecteurs de requête, utilisez une liste de vecteurs comme paramètre d'entrée. L'exemple de code suivant illustre cette procédure.
query_vectors = [
[0.06586461994037252, 0.7693023529849932, 0.8199991781350795, -0.6988017611187176, 0.408383847889378],
[0.8988257992203861, 0.021911711196309414, 0.19086900086430836, 0.63590610476426, -0.6713237387993141]
]
res = client.search(
collection_name="demo",
data=query_vectors,
limit=3,
)
print(res)
Étape 5 : Recherche filtrée
Utilisez les champs définis dans le schéma pour définir des conditions de filtre. Cela permet de réduire la portée de la recherche et d'améliorer son efficacité.
Filtrer par un champ numérique
L'exemple suivant montre comment filtrer en fonction de la plage de valeurs du champ id.
query_vectors = [
[-0.30932351869632435, -0.7132856078639205, 0.6006201320181415, 0.40140510356426784, -0.21223937444001328]
]
res = client.search(
collection_name="demo",
data=query_vectors,
filter="3 < id < 5", # The filter condition for a numeric field range.
limit=3
)
print(res)
Filtrer par un champ de métadonnées ($meta)
L'exemple suivant montre comment rechercher des enregistrements dont la valeur de la propriété color commence par « green ». Il spécifie également que le champ color doit être inclus dans la sortie.
query_vectors = [
[0.9636568288732006, -0.5900490884830603, 0.2504591754023724, 0.7120903924474389, 0.7620604497390009]
]
res = client.search(
collection_name="demo",
data=query_vectors,
filter='$meta["color"] like "green%"', # The filter condition to match a metadata field property value.
limit=3,
output_fields=["color"] # The fields to include in the returned results.
)
print(res)