Initialisation des données Chroma persistantes
import { ChromaClient } from 'chromadb'
Initialisation du client
const client = new ChromaClient();
Opérations courantes du client
await client.reset() // Efface la base de données
Travail avec les collections
Chromadb utilise le concept de collection
pour gérer des ensembles de données vectorielles, qui peuvent être assimilées à des tables dans MySQL.
Création, consultation et suppression de collections
Chroma utilise le nom de la collection dans l'URL, donc il existe certaines restrictions de nommage :
- La longueur du nom doit être comprise entre 3 et 63 caractères.
- Le nom doit commencer et se terminer par des lettres minuscules ou des chiffres, et peut contenir des points, des tirets et des traits de soulignement entre eux.
- Le nom ne peut pas contenir deux points consécutifs.
- Le nom ne peut pas être une adresse IP valide.
Pour créer une collection, le nom de la collection et une fonction de calcul de vecteur facultative (également appelée fonction d'incorporation) doivent être spécifiés. Si une fonction d'incorporation est fournie, elle doit être fournie à chaque accès à la collection.
Remarque : La fonction d'incorporation est utilisée pour calculer des vecteurs de texte.
import { ChromaClient } from 'chromadb'
Créez et référencez une collection comme indiqué ci-dessous :
let collection = await client.createCollection({name: "ma_collection", embeddingFunction: emb_fn})
let collection2 = await client.getCollection({name: "ma_collection", embeddingFunction: emb_fn})
La fonction d'incorporation prend du texte en entrée et renvoie des données vectorielles calculées.
Remarque : Les débutants peuvent en apprendre davantage sur les modèles d'incorporation de texte à partir de ce tutoriel.
Les collections existantes peuvent être référencées en utilisant .getCollection
par leur nom, et peuvent également être supprimées en utilisant .deleteCollection
.
const collection = await client.getCollection({name: "tizi365"}) // Référence la collection tizi365
await client.deleteCollection({name: "ma_collection"}) // Supprime la collection
Fonctions courantes de la collection
await collection.peek() // Renvoie les 10 premiers enregistrements de données dans la collection
await collection.count() // Renvoie le nombre total d'enregistrements de données dans la collection
Ajustement des méthodes de calcul de distance vectorielle
La fonction createCollection
inclut également un paramètre facultatif metadata
, où la valeur de hnsw:space peut être définie pour personnaliser la méthode de calcul de distance pour l'espace vectoriel.
Remarque : Les données vectorielles représentent la similarité entre les vecteurs en calculant la distance spatiale entre eux, les distances plus proches indiquant une similarité plus élevée et vice versa.
let collection = client.createCollection("nom_de_collection", undefined, metadata={ "hnsw:space": "cosine" })
Les options valides pour hnsw:space sont "l2", "ip" ou "cosine". Par défaut, c'est "l2".
Ajout de données à une collection
Utilisez .add
pour ajouter des données à la collection Chroma.
Ajoutez des données directement sans spécifier les vecteurs de document :
await collection.add({
ids: ["id1", "id2", "id3", ...],
metadatas: [{"chapitre": "3", "verset": "16"}, {"chapitre": "3", "verset": "5"}, {"chapitre": "29", "verset": "11"}, ...],
documents: ["lorem ipsum...", "doc2", "doc3", ...],
})
// Explication des paramètres
// ids - requis
// embeddings - optionnel
// metadata - optionnel
// documents - optionnel
Si Chroma reçoit une liste de documents, il utilisera automatiquement la fonction d'embedding de la collection pour calculer des vecteurs pour les documents (si une fonction d'embedding n'a pas été fournie lors de la création de la collection, la valeur par défaut sera utilisée). Chroma stockera également les documents eux-mêmes. Si un document est trop grand pour être utilisé avec la fonction d'embedding sélectionnée, une exception se produira.
Chaque document doit avoir un ID unique (ids). Ajouter le même ID deux fois entraînera seul la valeur initiale stockée. Une liste facultative de dictionnaires de métadonnées (metadatas) peut être fournie pour chaque document afin de stocker des informations supplémentaires pour filtrer les données lors des requêtes.
Alternativement, vous pouvez directement fournir une liste de données vectorielles liées au document, et Chroma utilisera les données vectorielles que vous avez fournies sans calculer automatiquement le vecteur.
await collection.add({
ids: ["id1", "id2", "id3", ...],
embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],
metadatas: [{"chapitre": "3", "verset": "16"}, {"chapitre": "3", "verset": "5"}, {"chapitre": "29", "verset": "11"}, ...],
documents: ["lorem ipsum...", "doc2", "doc3", ...],
})
Si les dimensions des données vectorielles fournies ne correspondent pas aux dimensions de la collection, une exception se produira.
Vous pouvez également stocker des documents ailleurs et simplement fournir les données vectorielles et la liste de métadonnées à Chroma. Vous pouvez utiliser des IDs pour associer les vecteurs aux documents stockés ailleurs.
await collection.add({
ids: ["id1", "id2", "id3", ...],
embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],
metadatas: [{"chapitre": "3", "verset": "16"}, {"chapitre": "3", "verset": "5"}, {"chapitre": "29", "verset": "11"}, ...],
})
Remarque : La fonction principale de la base de données vectorielle est la recherche de similarité sémantique basée sur les données vectorielles. Pour réduire la taille de la base de données vectorielles et améliorer l'efficacité, nous pouvons choisir de stocker des données vectorielles et certaines conditions d'attributs filtrables dans la base de données vectorielle. D'autres données, telles que le contenu des articles, peuvent être stockées dans des bases de données comme MYSQL, tant qu'elles sont associées par des IDs.
Interrogation des données de la Collection
La méthode .query
peut être utilisée pour interroger l'ensemble de données Chroma de plusieurs manières.
Vous pouvez effectuer une requête en utilisant un ensemble de query_embeddings (données vectorielles).
Astuce : Pour obtenir des query_embeddings, dans des scénarios de développement réels, la requête de l'utilisateur est généralement d'abord calculée en un vecteur de requête via un modèle d'encodage de texte, puis ce vecteur est utilisé pour interroger un contenu similaire.
const resultat = await collection.query({
queryEmbeddings: [[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
nResults: 10,
where: {"champ_metadata": "est_égal_à_cela"},
})
// ordre d'entrée
// query_embeddings - optionnel
// n_results - requis
// where - optionnel
// query_texts - optionnel
La requête renverra les n_results premiers résultats pour chaque vecteur de requête (query_embedding) dans l'ordre. Un dictionnaire de filtre where optionnel peut être fourni pour filtrer les résultats en fonction des métadonnées associées à chaque document. De plus, un dictionnaire de filtre where_document optionnel peut être fourni pour filtrer les résultats en fonction du contenu du document.
Si les query_embeddings fournis ne sont pas cohérents avec les dimensions de la collection, une exception se produira. Pour garantir la cohérence des vecteurs, il est recommandé d'utiliser le même modèle d'encodage de texte pour calculer les vecteurs.
Vous pouvez également interroger en utilisant un ensemble de textes de requête. Chroma calculera d'abord le vecteur pour chaque texte de requête en utilisant la fonction d'encodage de la collection, puis exécutera la requête en utilisant les vecteurs de texte générés.
await collection.query({
nResults: 10, // n_results
where: {"champ_metadata": "est_égal_à_cela"}, // where
queryTexts: ["doc10", "ainsi parlait zarathoustra", ...], // query_text
})
Vous pouvez également utiliser .get
pour interroger des données de la collection par ID.
await collection.get({
ids: ["id1", "id2", "id3", ...], //ids
where: {"style": "style1"} // where
})
.get
prend également en charge les filtres where
et where_document
. Si aucun id
n'est fourni, il renverra toutes les données de la collection correspondant aux filtres where
et where_document
.
Spécification des champs renvoyés
Lors de l'utilisation de get
ou query
, vous pouvez utiliser le paramètre include
pour spécifier les champs de données à renvoyer, y compris les données vectorielles, les documents et toutes les données dans les métadonnées. Par défaut, Chroma renvoie les documents, les métadonnées et les distances vectorielles. Vous pouvez spécifier les champs à renvoyer en passant un tableau de noms de champs au paramètre d'inclusion de la méthode get ou query.
collection.get(
include=["documents"]
)
collection.query(
query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
include=["documents"]
)
Utilisation des filtres where
Chroma prend en charge le filtrage des requêtes en fonction des métadonnées et du contenu du document. Le filtre where
est utilisé pour filtrer les métadonnées, et le filtre where_document
est utilisé pour filtrer le contenu du document. Ci-dessous, nous expliquons comment écrire des expressions de conditions de filtre.
Filtrage par métadonnées
Pour filtrer les métadonnées, un dictionnaire de filtre where
doit être fourni pour la requête. Le dictionnaire doit avoir la structure suivante :
{
"champ_metadata": {
<Opérateur>: <Valeur>
}
}
Le filtrage des métadonnées prend en charge les opérateurs suivants :
- $eq - Égal à (chaîne, entier, flottant)
- $ne - Non égal à (chaîne, entier, flottant)
- $gt - Supérieur à (entier, flottant)
- $gte - Supérieur ou égal à (entier, flottant)
- $lt - Inférieur à (entier, flottant)
- $lte - Inférieur ou égal à (entier, flottant)
L'utilisation de l'opérateur $eq équivaut à utiliser le filtre where
.
{
"champ_metadata": "chaîne_de_recherche"
}
{
"champ_metadata": {
"$eq": "chaîne_de_recherche"
}
}
Filtrage du contenu du document
Pour filtrer le contenu du document, un dictionnaire de filtre where_document
doit être fourni pour la requête. Le dictionnaire doit avoir la structure suivante :
{
"$contains": "chaîne_de_recherche"
}
Utilisation des opérateurs logiques
Vous pouvez également utiliser les opérateurs logiques $and
et $or
pour combiner plusieurs filtres.
L'opérateur $and
renverra les résultats correspondant à tous les filtres de la liste.
{
"$and": [
{
"champ_metadata": {
<Opérateur>: <Valeur>
}
},
{
"champ_metadata": {
<Opérateur>: <Valeur>
}
}
]
}
L'opérateur $or
renverra les résultats correspondant à n'importe quelle condition de filtrage de la liste.
{
"$or": [
{
"champ_metadata": {
<Opérateur>: <Valeur>
}
},
{
"champ_metadata": {
<Opérateur>: <Valeur>
}
}
]
}
Mise à jour des données
Chroma prend également en charge l'opération upsert, qui peut mettre à jour les données existantes et insérer de nouvelles données si les données n'existent pas.
await collection.upsert({
ids: ["id1", "id2", "id3"],
embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2]],
metadatas: [{"chapitre": "3", "verset": "16"}, {"chapitre": "3", "verset": "5"}, {"chapitre": "29", "verset": "11"}],
documents: ["doc1", "doc2", "doc3"]
})
Suppression des données
Chroma prend en charge l'utilisation de .delete pour supprimer des données de la collection par id.
await collection.delete({
ids: ["id1", "id2", "id3",...], //ids
where: {"chapitre": "20"} //where
})