Introduction
LanceDB est une base de données vectorielle embarquée et open-source, conçue pour les applications IA comme la recherche sémantique, le RAG (Retrieval-Augmented Generation) ou les recommandations. Contrairement à Pinecone ou Weaviate qui nécessitent un serveur distant, LanceDB stocke tout localement sur disque, avec des performances ultra-rapides grâce au format Lance (colonne-oriented).
Pourquoi l'utiliser en 2026 ? Les modèles d'IA comme Llama 3 ou Mistral génèrent des embeddings en masse, et LanceDB gère des millions de vecteurs sur un laptop sans latence réseau. Ce tutoriel beginner vous montre comment l'installer, créer une table, insérer des données vectorielles et effectuer des recherches KNN. À la fin, vous aurez une app fonctionnelle pour indexer 1000+ documents. Idéal pour prototypes rapides ou edge computing. (128 mots)
Prérequis
- Python 3.10 ou supérieur
- pip (gestionnaire de paquets)
- Connaissances de base en Python et NumPy
- 500 Mo d'espace disque pour les exemples
Installation de LanceDB
pip install lancedb
pip install numpy
pip install sentence-transformersCes commandes installent LanceDB (noyau vectoriel), NumPy (pour les vecteurs) et sentence-transformers (pour générer des embeddings réels). LanceDB est purement Python, sans dépendances C++ lourdes, pour une installation en <1 min. Évitez les environnements virtuels partagés pour prévenir les conflits de versions.
Création de la base de données
LanceDB utilise des dossiers locaux comme bases de données persistantes. Chaque DB contient des tables (collections) de vecteurs. Pensez-y comme à un SQLite pour embeddings : zéro config serveur.
Initialiser DB et table vide
import lancedb
import numpy as np
# Créer ou ouvrir une DB locale
db = lancedb.connect('./my_vector_db')
# Schéma de table : vecteur 384 dims + métadonnées
schema = {
'vector': 'float[384]',
'text': 'string',
'category': 'string'
}
table = db.create_table('documents', schema=schema)
print('Table créée avec succès !')Ce code crée un dossier ./my_vector_db et une table documents avec un champ vectoriel de 384 dimensions (standard pour all-MiniLM-L6-v2). Le schéma est obligatoire pour la persistance. Piège : Oubliez connect('./path') et la DB sera en RAM seulement, perdue au redémarrage.
Insertion de données vectorielles
Analogie : Comme insérer des lignes SQL, mais avec vecteurs. LanceDB supporte des batchs massifs (10k+ rows/sec). Utilisez un encodeur pour transformer du texte en vecteurs.
Générer et insérer des embeddings
import lancedb
import numpy as np
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')
# Données exemple
data = [
{'vector': model.encode('Python est un langage polyvalent pour l\'IA.').tolist(), 'text': 'Python est un langage polyvalent pour l\'IA.', 'category': 'langage'},
{'vector': model.encode('LanceDB excelle en recherche vectorielle.').tolist(), 'text': 'LanceDB excelle en recherche vectorielle.', 'category': 'db'},
{'vector': model.encode('Les embeddings capturent la sémantique.').tolist(), 'text': 'Les embeddings capturent la sémantique.', 'category': 'ia'}
]
# Connexion et insertion
db = lancedb.connect('./my_vector_db')
table = db.open_table('documents')
# Batch upsert (insert ou update)
table.add(data)
print(f'Inséré {len(data)} documents. Comptez: {table.count()}')Ici, sentence-transformers génère des vecteurs réels de 384 dims. add() est asynchrone et batché pour la perf. Utilisez .tolist() car LanceDB attend des listes Python, pas NumPy arrays. Piège : Vecteurs de dims incohérentes crashent la table ; validez toujours la taille.
Recherche vectorielle KNN
La force de LanceDB : recherche ANN (Approximate Nearest Neighbors) ultra-rapide. Query par vecteur ou texte brut (avec auto-embedding).
Effectuer une recherche sémantique
import lancedb
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')
query_vector = model.encode('Qu\'est-ce que LanceDB ?').tolist()
# Connexion
db = lancedb.connect('./my_vector_db')
table = db.open_table('documents')
# Recherche KNN : top 2 plus proches
results = table.search(
query_vector,
query_type='knn',
n_results=2,
select={'text': True, 'category': True}
).to_pandas()
print(results)search() utilise IVF-PQ par défaut pour scaler à des milliards de vecteurs. n_results=2 limite les retours ; select optimise la bande passante. Résultat : DataFrame Pandas prêt à l'emploi. Piège : Sans index, les queries lentes sur >10k rows ; LanceDB indexe auto à l'insertion.
Mise à jour et suppression
LanceDB gère les mutations ACID comme upsert/delete par ID. Idéal pour datasets dynamiques.
Upsert et delete
import lancedb
import numpy as np
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')
db = lancedb.connect('./my_vector_db')
table = db.open_table('documents')
# Upsert : nouveau ou update par _id (auto-généré)
new_data = [
{'vector': model.encode('Next.js optimise React pour le web.').tolist(), 'text': 'Next.js optimise React pour le web.', 'category': 'framework'}
]
table.add(new_data)
# Delete par filtre
results = table.search(model.encode('Python IA').tolist(), n_results=10).limit(1).to_pandas()
if not results.empty:
table.delete(where=f"_id = '{results['_id'].iloc[0]}'")
print('Opérations terminées. Nouveau count:', table.count())add() génère des _id UUID auto ; utilisez-les pour delete précis via where. Transactions implicites assurent consistance. Piège : Delete sans limite peut vider la table ; testez toujours avec to_pandas() avant.
Filtrage sémantique + métadonnées
import lancedb
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')
query_vec = model.encode('recherche rapide').tolist()
db = lancedb.connect('./my_vector_db')
table = db.open_table('documents')
# Recherche filtrée : seulement category='ia' ET KNN
results = table.search(
query_vec,
query_type='knn',
n_results=3,
where="category = 'ia'"
).to_arrow().to_pandas()
print(results[['text', 'category', '_distance']])Le filtre SQL-like (where) s'applique post-vector search pour précision. _distance mesure la similarité cosinus (0=identique). Arrow intermédiaire booste perf sur gros datasets. Piège : Filtres trop stricts retournent zéro ; déboguez avec queries sans filtre.
Bonnes pratiques
- Toujours indexer : LanceDB auto-optimise, mais limitez dims à <1024 pour perf.
- Batch inserts : >1000 rows par
add()pour x10 vitesse. - Utilisez Pandas :
to_pandas()pour intégration data science. - Backup DB : Copiez le dossier ; supporte hot-backup.
- Cloud sync : Montez sur S3 via fsspec pour scalabilité.
Erreurs courantes à éviter
- Dims mismatch : Vérifiez
len(vector)==schema_dimou crash à l'insert. - Oubli persistance :
connect(':memory:')perd tout ; forcez chemin disque. - Modèle non chargé : Réutilisez 1 instance SentenceTransformer (coûteux en RAM).
- Queries sans n_results : Par défaut 10, mais surchargez pour top-1 précis.
Pour aller plus loin
Explorez la doc officielle LanceDB pour full-text hybrid search. Intégrez avec LangChain ou LlamaIndex pour RAG avancés. Découvrez nos formations IA Learni pour maîtriser les bases vectorielles en prod.