Voici des situations oĂč la recherche textuelle classique montre ses limites. ConcrĂštement, cela donne :
Un portail d'assistance ne renvoie aucun résultat lorsqu'un utilisateur saisit « ne s'allume pas » au lieu de l'expression exacte utilisée dans l'article d'aide.
Une plateforme e-commerce ne trouve rien quand un client cherche « quelque chose de chaud pour l'hiver » parce qu'aucune fiche produit ne contient exactement ces mots.
Une base de connaissances passe à cÎté du bon document car l'utilisateur a formulé sa question différemment du libellé du document.
La recherche sĂ©mantique rĂ©sout ce problĂšme. Elle comprend le sens et l'intention derriĂšre une requĂȘte plutĂŽt que de faire correspondre des mots Ă l'identique.
Ce tutoriel vous montre comment implémenter une recherche sémantique dans MongoDB avec Python et le modÚle d'embedding gratuit nomic-embed-text-v1 .
Remarque : nomic-embed-text-v1 pÚse environ 0,27 Go une fois chargé en mémoire. Assurez-vous que votre machine dispose d'au moins 1 Go de RAM disponible avant d'exécuter un script de ce tutoriel. Lors de la premiÚre exécution, le modÚle est téléchargé depuis Hugging Face : prévoyez un délai supplémentaire selon votre connexion. Les exécutions suivantes chargent le modÚle depuis le cache local. L'inférence sur CPU est nettement plus lente que sur GPU. Sur une machine sans GPU dédié, le modÚle s'exécute sur CPU et utilise la RAM plutÎt que la VRAM, ce qui peut rallonger la génération des embeddings.
Dans ce tutoriel, vous apprendrez :
Ce que sont les embeddings vectoriels et comment ils représentent le sens
Comment générer et stocker des embeddings dans MongoDB
Comment créer un index MongoDB Vector Search
Comment convertir une requĂȘte utilisateur en vecteur
Comment exécuter un pipeline d'agrégation $vectorSearch et interpréter les résultats
Vous trouverez tous les extraits de code de ce tutoriel dans le référentiel GitHub .
Recherche textuelle vs recherche sémantique
La recherche textuelle retrouve les documents qui contiennent exactement les mots de votre requĂȘte. La recherche sĂ©mantique retourne des documents qui portent le mĂȘme sens que votre requĂȘte, mĂȘme s'ils utilisent des mots complĂštement diffĂ©rents.
Le tableau suivant illustre ce que chaque approche retourne pour la requĂȘte « heart problems » :
Texte du document Recherche textuelle Recherche sémantique Pourquoi la recherche textuelle le retourne "...heart problems in adults..." Oui Oui Contient exactement les mots « heart problems » "...cardiac conditions and symptoms..." Non Oui Ne contient pas exactement les mots « heart problems » "...risk factors for heart disease..." Non Oui Ne contient pas exactement les mots « heart problems » "...chest pain and shortness of breath..." Non Oui Ne contient pas exactement les mots « heart problems »
Notions clés de la recherche sémantique
Trois concepts sont centraux pour la recherche sémantique dans MongoDB. Ils vous aideront à comprendre pourquoi chaque étape de ce tutoriel fonctionne comme elle le fait.
Embeddings vectoriels
Un modÚle d'embedding convertit un texte en une liste de nombres de longueur fixe appelée vecteur. Chaque nombre du vecteur représente une dimension de sens.
Deux textes qui ont des sens proches produisent des vecteurs numĂ©riquement proches. « cardiac conditions » et « heart problems » se retrouvent voisins dans l'espace vectoriel, mĂȘme s'ils ne partagent aucun mot. Cette proximitĂ© rend la recherche sĂ©mantique possible.
Ce tutoriel utilise le modÚle d'embedding nomic-embed-text-v1, gratuit, open source et entiÚrement exécutable en local. Le modÚle est automatiquement téléchargé depuis Hugging Face lors de la premiÚre exécution, puis mis en cache localement pour les suivantes. Le modÚle produit 768 nombres par entrée.
Index de recherche vectorielle
Un index de recherche vectorielle indique Ă MongoDB quel champ contient les embeddings, combien de dimensions attendre et quelle fonction de similaritĂ© utiliser pour la comparaison. Vous devez crĂ©er cet index avant d'exĂ©cuter des requĂȘtes $vectorSearch.
L'étape d'agrégation $vectorSearch
$vectorSearch est l'Ă©tape d'agrĂ©gation qui exĂ©cute la recherche. Elle accepte un vecteur de requĂȘte, parcourt le champ indexĂ© et renvoie les documents classĂ©s par similaritĂ© sĂ©mantique. Vous pouvez l'enchaĂźner avec $project et d'autres Ă©tapes comme dans n'importe quel pipeline d'agrĂ©gation.
Allons-y.
Prérequis
Avant de commencer, assurez-vous d'avoir :
Python 3.8 ou version ultérieure installé
Un compte MongoDB Atlas avec un cluster M0 (offre Free tier) configuré
pymongo 4.7 ou ultérieur, et les packages Python sentence-transformers et einops installés
Des notions de base en Python et sur les collections MongoDB
Votre chaĂźne de connexion Atlas, disponible dans l'interface Atlas sous **Database > Connect > Drivers**
Votre adresse IP autorisée dans Atlas avant d'exécuter des scripts. Allez dans **Security > Network Access** dans l'interface Atlas et ajoutez votre adresse IP actuelle.
Créez un dossier pour votre projet et placez-vous dedans via le terminal :
mkdir mongodb-semantic-search
cd mongodb-semantic-searchPropulsé par
Créez et activez un environnement virtuel pour isoler les dépendances du projet :
python -m venv venv
source venv/bin/activatePropulsé par
Sous Windows, activez l'environnement virtuel avec :
venv\ Scripts\ activatePropulsé par
Installez maintenant les packages requis :
pip install pymongo sentence-transformers einopsPropulsé par
Vous allez créer un fichier Python pour chaque étape de ce tutoriel. Tous les fichiers iront dans le dossier mongodb-semantic-search.
Créer le fichier d'utilitaires d'embedding
Créez un fichier nommé embedding_utils.py. Ce fichier contient les deux fonctions d'embedding utilisées dans ce tutoriel :
from sentence_transformers import SentenceTransformer
model = SentenceTransformer( "nomic-ai/nomic-embed-text-v1" , trust_remote_code= True )
def get_embedding ( text, precision= "float32" ) :
return model. encode( text, precision= precision) . tolist( )
def get_query_embedding ( text, precision= "float32" ) :
return model. encode( text, precision= precision) . tolist( ) Propulsé par
Avertissement : trust_remote_code=True autorise l'exécution sur votre machine de code Python spécifique au modÚle et téléchargé depuis Hugging Face. Si le code source du modÚle sur Hugging Face est compromis ou contient des modifications malveillantes, ce code s'exécutera automatiquement dans votre environnement. Faites preuve de prudence avant d'utiliser ce paramÚtre en production.
Générer et stocker les embeddings vectoriels
Créez un fichier nommé generate_embeddings.py. Ce fichier importe la fonction d'embedding depuis embedding_utils.py, génÚre un vecteur pour le champ texte de chaque document et stocke le document complet, y compris l'embedding, dans MongoDB :
from embedding_utils import get_embedding
from pymongo import MongoClient
mongodb_client = MongoClient(
"mongodb+srv://<USERNAME>:<PASSWORD>@<HOST>/" ,
appname= "devrel-tutorial-python-semantic-search"
)
collection = mongodb_client[ "sample_db" ] [ "documents" ]
sample_documents = [
{
"title" : "MongoDB Atlas" ,
"text" : "MongoDB Atlas is a fully managed cloud database."
} ,
{
"title" : "Vector Search" ,
"text" : "Vector search finds results based on semantic meaning."
} ,
{
"title" : "Nomic AI" ,
"text" : "nomic-embed-text-v1 is a free, open-source embedding model."
} ,
]
docs_to_insert = [ ]
for doc in sample_documents:
embedding = get_embedding( doc[ "text" ] )
docs_to_insert. append( {
"title" : doc[ "title" ] ,
"text" : doc[ "text" ] ,
"embedding" : embedding
} )
collection. drop( )
result = collection. insert_many( docs_to_insert)
print ( f"Inserted { len ( result. inserted_ids) } documents with embeddings." )
mongodb_client. close( ) Propulsé par
Dans le code ci-dessus, collection.drop() supprime tous les documents et index de la collection avant chaque exĂ©cution. Relancer generate_embeddings.py sans cette ligne insĂšre des doublons, ce qui amĂšne $vectorSearch Ă retourner plusieurs fois le mĂȘme document. La suppression de la collection efface aussi l'index de recherche vectorielle : vous devrez donc relancer create_vector_index.py Ă chaque fois que vous relancez generate_embeddings.py.
Exécutez le script :
python generate_embeddings.pyPropulsé par
Vous verrez la sortie suivante dans votre terminal :
< All keys matched successfully>
Inserted 3 documents with embeddings.Propulsé par
Chaque document dans MongoDB contient dĂ©sormais Ă la fois le texte d'origine et son vecteur Ă 768 dimensions dans le champ embedding. Le vecteur vit aux cĂŽtĂ©s de vos donnĂ©es, dans le mĂȘme document : aucun stockage sĂ©parĂ© ni recherche additionnelle n'est nĂ©cessaire au moment de la requĂȘte.
Créer un index MongoDB Vector Search
CrĂ©ez un fichier nommĂ© create_vector_index.py. Ce fichier dĂ©finit et crĂ©e un index de recherche vectorielle sur le champ embedding afin que MongoDB puisse exĂ©cuter des requĂȘtes $vectorSearch sur votre collection.
La définition de l'index requiert trois champs :
path : le champ qui contient les embeddings (embedding dans ce tutoriel)
numDimensions : doit correspondre Ă la taille de sortie du modĂšle (768 pour nomic-embed-text-v1)
similarity : la fonction de comparaison (cosine convient Ă ce modĂšle)
La valeur de numDimensions doit correspondre exactement à celle de votre modÚle d'embedding. En cas d'écart, la création de l'index échoue :
from pymongo. mongo_client import MongoClient
from pymongo. operations import SearchIndexModel
import time
mongodb_client = MongoClient(
"mongodb+srv://<USERNAME>:<PASSWORD>@<HOST>/" ,
appname= "devrel-tutorial-python-semantic-search"
)
database = mongodb_client[ "sample_db" ]
collection = database[ "documents" ]
search_index_model = SearchIndexModel(
definition= {
"fields" : [
{
"type" : "vector" ,
"path" : "embedding" ,
"numDimensions" : 768 ,
"similarity" : "cosine"
}
]
} ,
name= "vector_index" ,
type = "vectorSearch"
)
result = collection. create_search_index( model= search_index_model)
print ( "New search index named " + result + " is building." )
print ( "Polling to check if the index is ready. This may take up to a minute." )
predicate = lambda index: index. get( "queryable" ) is True
while True :
indices = list ( collection. list_search_indexes( result) )
if len ( indices) and predicate( indices[ 0 ] ) :
break
time. sleep( 5 )
print ( result + " is ready for querying." )
mongodb_client. close( ) Propulsé par
Exécutez le script :
python create_vector_index.pyPropulsé par
Vous verrez la sortie suivante dans votre terminal :
New search index named vector_index is building.
Polling to check if the index is ready. This may take up to a minute.
vector_index is ready for querying.Propulsé par
La construction de l'index peut prendre jusqu'Ă une minute. La boucle d'interrogation vĂ©rifie toutes les 5 secondes et ne s'arrĂȘte que lorsque MongoDB confirme que l'index est interrogeable. N'avancez pas tant que vous n'avez pas vu « vector_index is ready for querying. »
Convertir votre requĂȘte de recherche en vecteur
Créez un fichier nommé generate_query_vector.py. Ce fichier importe la fonction get_query_embedding() depuis embedding_utils.py. Exécutez generate_query_vector.py pour vérifier que le modÚle d'embedding se charge correctement et produit un vecteur à 768 dimensions :
Il définit la fonction get_query_embedding() qui sera importée à l'étape suivante.
Vous pouvez l'exécuter seul pour vérifier que le modÚle fonctionne correctement.
Vous devez utiliser le mĂȘme modĂšle ici que lors de la premiĂšre Ă©tape. Un modĂšle diffĂ©rent produit des vecteurs dans un espace numĂ©rique diffĂ©rent, rendant la comparaison inutile :
from embedding_utils import get_query_embedding
user_query = "I need an automated, scalable system for serious information storage"
query_vector = get_query_embedding( user_query)
print ( f"Query: ' { user_query} '" )
print ( f"Vector dimensions: { len ( query_vector) } " )
print ( f"First 5 values: { query_vector[ : 5] } " ) Propulsé par
Exécutez le script :
python generate_query_vector.pyPropulsé par
Vous obtiendrez une sortie semblable Ă celle-ci :
< All keys matched successfully>
Query: 'I need an automated, scalable system for serious information storage'
Vector dimensions: 768
First 5 values: [ 0.0025914530269801617 , 0.09862980246543884 , -0.023092379793524742, -0.0171672236174345, -0.05548065900802612] Propulsé par
Dans la sortie ci-dessus, Vector dimensions: 768 confirme que la sortie du modÚle correspond à vos embeddings stockés.
ExĂ©cuter une requĂȘte $vectorSearch
Créez un fichier nommé run_vector_search.py. Ce fichier importe la fonction get_query_embedding() depuis embedding_utils.py et convertit le terme recherché par l'utilisateur en vecteur. run_vector_search.py exécute un pipeline d'agrégation $vectorSearch et affiche les résultats classés par similarité sémantique :
from embedding_utils import get_query_embedding
from pymongo import MongoClient
mongodb_client = MongoClient(
"mongodb+srv://<USERNAME>:<PASSWORD>@<HOST>/" ,
appname= "devrel-tutorial-python-semantic-search"
)
collection = mongodb_client[ "sample_db" ] [ "documents" ]
user_query = "I need an automated, scalable system for serious information storage"
query_vector = get_query_embedding( user_query)
pipeline = [
{
"$vectorSearch" : {
"index" : "vector_index" ,
"path" : "embedding" ,
"queryVector" : query_vector,
"numCandidates" : 150 ,
"limit" : 3
}
} ,
{
"$project" : {
"_id" : 0 ,
"title" : 1 ,
"text" : 1 ,
"score" : {
"$meta" : "vectorSearchScore"
}
}
}
]
results = collection. aggregate( pipeline)
print ( f"\nTop results for query: ' { user_query} '\n" )
for doc in results:
print ( f"Title: { doc[ 'title' ] } " )
print ( f"Text: { doc[ 'text' ] } " )
print ( f"Score: { doc[ 'score' ] : .4f } " )
print ( )
mongodb_client. close( ) Propulsé par
Dans le code ci-dessus, deux paramĂštres pilotent le comportement de la recherche :
numCandidates dĂ©finit la taille du premier ensemble de candidats que MongoDB examine avant de restreindre les rĂ©sultats finaux. Une valeur plus Ă©levĂ©e amĂ©liore le rappel, au prix d'un temps de requĂȘte lĂ©gĂšrement supĂ©rieur.
limit définit le nombre de résultats renvoyés. Dans ce tutoriel, limit est fixé à 3 et numCandidates à 150. Un bon point de départ consiste à régler numCandidates à 10 à 15 fois votre limit.
Exécutez maintenant le script :
python run_vector_search.pyPropulsé par
Vous obtiendrez une sortie similaire Ă celle-ci :
< All keys matched successfully>
Top results for query: 'I need an automated, scalable system for serious information storage.'
Title: MongoDB Atlas
Text: MongoDB Atlas is a fully managed cloud database.
Score: 0.7211
Title: Nomic AI
Text: nomic-embed-text-v1 is a free, open-source embedding model.
Score: 0.6818
Title: Vector Search
Text: Vector search finds results based on semantic meaning.
Score: 0.6642 Propulsé par
« MongoDB Atlas » obtient le meilleur score, mĂȘme si la requĂȘte « I need an automated, scalable system for serious information storage » ne partage aucun mot avec « MongoDB Atlas is a fully managed cloud database. » Le rĂ©sultat est retournĂ© car leurs vecteurs sont proches en termes de sens : « ...un systĂšme automatisĂ© et scalable de stockage d'informations » correspond sĂ©mantiquement à « ...une base de donnĂ©es cloud entiĂšrement managĂ©e ». Une recherche textuelle avec la mĂȘme requĂȘte renverrait zĂ©ro rĂ©sultat, puisque aucun mot exact n'apparaĂźt dans les documents. C'est prĂ©cisĂ©ment le fonctionnement attendu de la recherche sĂ©mantique.
Points clés à retenir
MongoDB Vector Search fonctionne sur un cluster M0 Free tier. Aucun plan payant n'est requis.
Vous devez utiliser le mĂȘme modĂšle d'embedding pour gĂ©nĂ©rer les embeddings stockĂ©s et les vecteurs de requĂȘte. MĂ©langer les modĂšles produit des rĂ©sultats dĂ©nuĂ©s de sens.
La valeur numDimensions dans la définition de votre index doit correspondre exactement à la taille de sortie de votre modÚle d'embedding. nomic-embed-text-v1 produit toujours 768 dimensions.
input_type="document" optimise les embeddings pour le stockage. input_type="query" les optimise pour la recherche. Utilisez le bon type à chaque étape.
numCandidates contrĂŽle l'ampleur du filet de recherche que MongoDB jette avant de restreindre aux rĂ©sultats finaux dĂ©finis par limit. Une valeur plus Ă©levĂ©e amĂ©liore le rappel au dĂ©triment du temps de requĂȘte.
vectorSearchScore classe les rĂ©sultats par similaritĂ© sĂ©mantique. Les rĂ©sultats n'ont pas besoin de contenir les mots exacts de la requĂȘte. Les plages de score varient selon le modĂšle et le jeu de donnĂ©es, mais les seuils suivants constituent un bon point de dĂ©part pour nomic-embed-text-v1 avec la similaritĂ© cosinus :
0,9 et plus : sens quasi identique. Le document et la requĂȘte sont presque Ă©quivalents sĂ©mantiquement.
0,7 Ă 0,9 : forte pertinence. Le document correspond clairement Ă l'intention de la requĂȘte.
0,5 à 0,7 : pertinence modérée. Le document est lié au sujet mais avec un cadrage ou un contexte différent.
En dessous de 0,5 : faible pertinence. Le lien est tĂ©nu et le rĂ©sultat peut ĂȘtre peu utile.
Vous trouverez tous les extraits de code de ce tutoriel dans le référentiel GitHub .
Pour aller plus loin
Voici des situations oĂč la recherche textuelle classique montre ses limites. ConcrĂštement, cela donne :
La recherche sĂ©mantique rĂ©sout ce problĂšme. Elle comprend le sens et l'intention derriĂšre une requĂȘte plutĂŽt que de faire correspondre des mots Ă l'identique.
Ce tutoriel vous montre comment implémenter une recherche sémantique dans MongoDB avec Python et le modÚle d'embedding gratuit nomic-embed-text-v1.
Remarque :
nomic-embed-text-v1pÚse environ 0,27 Go une fois chargé en mémoire. Assurez-vous que votre machine dispose d'au moins 1 Go de RAM disponible avant d'exécuter un script de ce tutoriel. Lors de la premiÚre exécution, le modÚle est téléchargé depuis Hugging Face : prévoyez un délai supplémentaire selon votre connexion. Les exécutions suivantes chargent le modÚle depuis le cache local. L'inférence sur CPU est nettement plus lente que sur GPU. Sur une machine sans GPU dédié, le modÚle s'exécute sur CPU et utilise la RAM plutÎt que la VRAM, ce qui peut rallonger la génération des embeddings.Dans ce tutoriel, vous apprendrez :
$vectorSearchet interpréter les résultatsVous trouverez tous les extraits de code de ce tutoriel dans le référentiel GitHub.
Recherche textuelle vs recherche sémantique
La recherche textuelle retrouve les documents qui contiennent exactement les mots de votre requĂȘte. La recherche sĂ©mantique retourne des documents qui portent le mĂȘme sens que votre requĂȘte, mĂȘme s'ils utilisent des mots complĂštement diffĂ©rents.
Le tableau suivant illustre ce que chaque approche retourne pour la requĂȘte « heart problems » :
Notions clés de la recherche sémantique
Trois concepts sont centraux pour la recherche sémantique dans MongoDB. Ils vous aideront à comprendre pourquoi chaque étape de ce tutoriel fonctionne comme elle le fait.
Embeddings vectoriels
Un modÚle d'embedding convertit un texte en une liste de nombres de longueur fixe appelée vecteur. Chaque nombre du vecteur représente une dimension de sens.
Deux textes qui ont des sens proches produisent des vecteurs numĂ©riquement proches. « cardiac conditions » et « heart problems » se retrouvent voisins dans l'espace vectoriel, mĂȘme s'ils ne partagent aucun mot. Cette proximitĂ© rend la recherche sĂ©mantique possible.
Ce tutoriel utilise le modĂšle d'embedding
nomic-embed-text-v1, gratuit, open source et entiÚrement exécutable en local. Le modÚle est automatiquement téléchargé depuis Hugging Face lors de la premiÚre exécution, puis mis en cache localement pour les suivantes. Le modÚle produit 768 nombres par entrée.Index de recherche vectorielle
Un index de recherche vectorielle indique Ă MongoDB quel champ contient les embeddings, combien de dimensions attendre et quelle fonction de similaritĂ© utiliser pour la comparaison. Vous devez crĂ©er cet index avant d'exĂ©cuter des requĂȘtes
$vectorSearch.L'étape d'agrégation
$vectorSearch$vectorSearchest l'Ă©tape d'agrĂ©gation qui exĂ©cute la recherche. Elle accepte un vecteur de requĂȘte, parcourt le champ indexĂ© et renvoie les documents classĂ©s par similaritĂ© sĂ©mantique. Vous pouvez l'enchaĂźner avec$projectet d'autres Ă©tapes comme dans n'importe quel pipeline d'agrĂ©gation.Allons-y.
Prérequis
Avant de commencer, assurez-vous d'avoir :
pymongo4.7 ou ultérieur, et les packages Pythonsentence-transformerseteinopsinstallésConfigurer votre projet
Créez un dossier pour votre projet et placez-vous dedans via le terminal :
Créez et activez un environnement virtuel pour isoler les dépendances du projet :
Sous Windows, activez l'environnement virtuel avec :
Installez maintenant les packages requis :
Vous allez créer un fichier Python pour chaque étape de ce tutoriel. Tous les fichiers iront dans le dossier
mongodb-semantic-search.Créer le fichier d'utilitaires d'embedding
Créez un fichier nommé
embedding_utils.py. Ce fichier contient les deux fonctions d'embedding utilisées dans ce tutoriel :Avertissement :
trust_remote_code=Trueautorise l'exécution sur votre machine de code Python spécifique au modÚle et téléchargé depuis Hugging Face. Si le code source du modÚle sur Hugging Face est compromis ou contient des modifications malveillantes, ce code s'exécutera automatiquement dans votre environnement. Faites preuve de prudence avant d'utiliser ce paramÚtre en production.Générer et stocker les embeddings vectoriels
Créez un fichier nommé
generate_embeddings.py. Ce fichier importe la fonction d'embedding depuisembedding_utils.py, génÚre un vecteur pour le champ texte de chaque document et stocke le document complet, y compris l'embedding, dans MongoDB :Dans le code ci-dessus,
collection.drop()supprime tous les documents et index de la collection avant chaque exĂ©cution. Relancergenerate_embeddings.pysans cette ligne insĂšre des doublons, ce qui amĂšne$vectorSearchĂ retourner plusieurs fois le mĂȘme document. La suppression de la collection efface aussi l'index de recherche vectorielle : vous devrez donc relancercreate_vector_index.pyĂ chaque fois que vous relancezgenerate_embeddings.py.ExĂ©cutez le script :
Vous verrez la sortie suivante dans votre terminal :
Chaque document dans MongoDB contient désormais à la fois le texte d'origine et son vecteur à 768 dimensions dans le champ
embedding. Le vecteur vit aux cĂŽtĂ©s de vos donnĂ©es, dans le mĂȘme document : aucun stockage sĂ©parĂ© ni recherche additionnelle n'est nĂ©cessaire au moment de la requĂȘte.CrĂ©er un index MongoDB Vector Search
Créez un fichier nommé
create_vector_index.py. Ce fichier dĂ©finit et crĂ©e un index de recherche vectorielle sur le champembeddingafin que MongoDB puisse exĂ©cuter des requĂȘtes$vectorSearchsur votre collection.La dĂ©finition de l'index requiert trois champs :
path: le champ qui contient les embeddings (embeddingdans ce tutoriel)numDimensions: doit correspondre Ă la taille de sortie du modĂšle (768pournomic-embed-text-v1)similarity: la fonction de comparaison (cosineconvient Ă ce modĂšle)La valeur de
numDimensionsdoit correspondre exactement à celle de votre modÚle d'embedding. En cas d'écart, la création de l'index échoue :Exécutez le script :
Vous verrez la sortie suivante dans votre terminal :
La construction de l'index peut prendre jusqu'Ă une minute. La boucle d'interrogation vĂ©rifie toutes les 5 secondes et ne s'arrĂȘte que lorsque MongoDB confirme que l'index est interrogeable. N'avancez pas tant que vous n'avez pas vu « vector_index is ready for querying. »
Convertir votre requĂȘte de recherche en vecteur
Créez un fichier nommé
generate_query_vector.py. Ce fichier importe la fonctionget_query_embedding()depuisembedding_utils.py. ExĂ©cutezgenerate_query_vector.pypour vĂ©rifier que le modĂšle d'embedding se charge correctement et produit un vecteur Ă 768 dimensions :get_query_embedding()qui sera importĂ©e Ă l'Ă©tape suivante.Vous devez utiliser le mĂȘme modĂšle ici que lors de la premiĂšre Ă©tape. Un modĂšle diffĂ©rent produit des vecteurs dans un espace numĂ©rique diffĂ©rent, rendant la comparaison inutile :
Exécutez le script :
Vous obtiendrez une sortie semblable Ă celle-ci :
Dans la sortie ci-dessus,
Vector dimensions: 768confirme que la sortie du modĂšle correspond Ă vos embeddings stockĂ©s.ExĂ©cuter une requĂȘte
$vectorSearchCréez un fichier nommé
run_vector_search.py. Ce fichier importe la fonctionget_query_embedding()depuisembedding_utils.pyet convertit le terme recherché par l'utilisateur en vecteur.run_vector_search.pyexécute un pipeline d'agrégation$vectorSearchet affiche les résultats classés par similarité sémantique :Dans le code ci-dessus, deux paramÚtres pilotent le comportement de la recherche :
numCandidatesdĂ©finit la taille du premier ensemble de candidats que MongoDB examine avant de restreindre les rĂ©sultats finaux. Une valeur plus Ă©levĂ©e amĂ©liore le rappel, au prix d'un temps de requĂȘte lĂ©gĂšrement supĂ©rieur.limitdĂ©finit le nombre de rĂ©sultats renvoyĂ©s. Dans ce tutoriel,limitest fixĂ© Ă 3 etnumCandidatesĂ 150. Un bon point de dĂ©part consiste Ă rĂ©glernumCandidatesĂ 10 Ă 15 fois votrelimit.ExĂ©cutez maintenant le script :
Vous obtiendrez une sortie similaire Ă celle-ci :
« MongoDB Atlas » obtient le meilleur score, mĂȘme si la requĂȘte « I need an automated, scalable system for serious information storage » ne partage aucun mot avec « MongoDB Atlas is a fully managed cloud database. » Le rĂ©sultat est retournĂ© car leurs vecteurs sont proches en termes de sens : « ...un systĂšme automatisĂ© et scalable de stockage d'informations » correspond sĂ©mantiquement à « ...une base de donnĂ©es cloud entiĂšrement managĂ©e ». Une recherche textuelle avec la mĂȘme requĂȘte renverrait zĂ©ro rĂ©sultat, puisque aucun mot exact n'apparaĂźt dans les documents. C'est prĂ©cisĂ©ment le fonctionnement attendu de la recherche sĂ©mantique.
Points clés à retenir
numDimensionsdans la dĂ©finition de votre index doit correspondre exactement Ă la taille de sortie de votre modĂšle d'embedding.nomic-embed-text-v1produit toujours 768 dimensions.input_type="document"optimise les embeddings pour le stockage.input_type="query"les optimise pour la recherche. Utilisez le bon type Ă chaque Ă©tape.numCandidatescontrĂŽle l'ampleur du filet de recherche que MongoDB jette avant de restreindre aux rĂ©sultats finaux dĂ©finis parlimit. Une valeur plus Ă©levĂ©e amĂ©liore le rappel au dĂ©triment du temps de requĂȘte.vectorSearchScoreclasse les rĂ©sultats par similaritĂ© sĂ©mantique. Les rĂ©sultats n'ont pas besoin de contenir les mots exacts de la requĂȘte. Les plages de score varient selon le modĂšle et le jeu de donnĂ©es, mais les seuils suivants constituent un bon point de dĂ©part pournomic-embed-text-v1avec la similaritĂ© cosinus :Vous trouverez tous les extraits de code de ce tutoriel dans le rĂ©fĂ©rentiel GitHub.
Pour aller plus loin