Initialisierung von persistanten Chroma-Daten

import { ChromaClient } from 'chromadb'

Initialisierung des Clients

const client = new ChromaClient();

Gemeinsame Client-Operationen

await client.reset() // Löscht die Datenbank

Arbeit mit Sammlungen

Chromadb verwendet das Konzept von Sammlungen, um Mengen von Vektordaten zu verwalten, die mit Tabellen in MySQL verglichen werden können.

Erstellen, Anzeigen und Löschen von Sammlungen

Chroma verwendet den Sammlungsnamen in der URL, daher gelten einige Namensbeschränkungen:

  • Die Namenslänge muss zwischen 3 und 63 Zeichen liegen.
  • Der Name muss mit Kleinbuchstaben oder Zahlen beginnen und enden und kann in der Mitte Punkte, Bindestriche und Unterstriche enthalten.
  • Der Name darf keine zwei aufeinanderfolgenden Punkte enthalten.
  • Der Name darf keine gültige IP-Adresse sein.

Um eine Sammlung zu erstellen, muss der Sammlungsname und eine optionale Vektorberechnungsfunktion (auch als Einbettungsfunktion bekannt) angegeben werden. Wenn eine Einbettungsfunktion angegeben wird, muss sie jedes Mal bereitgestellt werden, wenn auf die Sammlung zugegriffen wird.

Hinweis: Die Einbettungsfunktion wird verwendet, um Textvektoren zu berechnen.

import { ChromaClient } from 'chromadb'

Erstellen und Referenzieren einer Sammlung wie unten gezeigt:

let collection = await client.createCollection({name: "meine_sammlung", embeddingFunction: emb_fn})

let collection2 = await client.getCollection({name: "meine_sammlung", embeddingFunction: emb_fn})

Die Einbettungsfunktion nimmt Text als Eingabe und gibt berechnete Vektordaten zurück.

Hinweis: Anfänger können sich über Texteinbettungsmodelle in diesem Tutorial informieren.

Vorhandene Sammlungen können über .getCollection nach Namen referenziert und auch über .deleteCollection gelöscht werden.

const collection = await client.getCollection({name: "tizi365"}) // Referenz auf die Sammlung tizi365
await client.deleteCollection({name: "meine_sammlung"}) // Löschen der Sammlung

Gemeinsame Sammlungsfunktionen

await collection.peek() // Gibt die ersten 10 Datensätze in der Sammlung zurück
await collection.count() // Gibt die Gesamtanzahl der Datensätze in der Sammlung zurück

Anpassung von Methoden zur Berechnung von Vektordistanzen

Die createCollection enthält auch einen optionalen metadata-Parameter, bei dem der Wert von hnsw:space festgelegt werden kann, um die Methode zur Berechnung von Vektordistanzen im Vektorraum anzupassen.

Hinweis: Vektordaten stellen die Ähnlichkeit zwischen Vektoren dar, indem der räumliche Abstand zwischen ihnen berechnet wird, wobei nähere Abstände eine höhere Ähnlichkeit und umgekehrt anzeigen.

let collection = client.createCollection("sammlungsname", undefined, metadata={ "hnsw:space": "cosine" })

Die gültigen Optionen für hnsw:space sind "l2", "ip" oder "kosinus". Der Standardwert ist "l2".

Hinzufügen von Daten zu einer Sammlung

Verwenden Sie .add, um Daten zur Chroma-Sammlung hinzuzufügen.

Fügen Sie Daten direkt hinzu, ohne Dokumentvektoren anzugeben:

await collection.add({
    ids: ["id1", "id2", "id3", ...],
    metadaten: [{"kapitel": "3", "vers": "16"}, {"kapitel": "3", "vers": "5"}, {"kapitel": "29", "vers": "11"}, ...],
    dokumente: ["Lorem Ipsum...", "Dokument 2", "Dokument 3", ...],
})
// Parametererklärung
// ids - erforderlich
// embeddings - optional
// metadaten - optional
// dokumente - optional

Wenn Chroma eine Liste von Dokumenten erhält, verwendet es automatisch die Einbettungsfunktion der Sammlung, um Vektoren für die Dokumente zu berechnen (wenn keine Einbettungsfunktion angegeben wurde, wird der Standardwert verwendet). Chroma speichert auch die Dokumente selbst. Wenn ein Dokument für die ausgewählte Einbettungsfunktion zu groß ist, tritt eine Ausnahme auf.

Jedes Dokument muss eine eindeutige ID (ids) haben. Das Hinzufügen derselben ID zweimal führt dazu, dass nur der ursprüngliche Wert gespeichert wird. Es kann eine optionale Liste von Metadaten-Dictionaries (metadaten) für jedes Dokument bereitgestellt werden, um zusätzliche Informationen zur Filterung von Daten während Abfragen zu speichern.

Alternativ können Sie direkt eine Liste von dokumentspezifischen Vektordaten bereitstellen, und Chroma wird die von Ihnen bereitgestellten Vektordaten ohne automatische Berechnung des Vektors verwenden.

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], ...],
    metadaten: [{"kapitel": "3", "vers": "16"}, {"kapitel": "3", "vers": "5"}, {"kapitel": "29", "vers": "11"}, ...],
    dokumente: ["Lorem Ipsum...", "Dokument 2", "Dokument 3", ...],
})

Wenn die bereitgestellten Vektordatenabmessungen (Länge) nicht mit den Dimensionen der Sammlung übereinstimmen, tritt eine Ausnahme auf.

Sie können auch Dokumente an anderer Stelle speichern und einfach die Vektordaten und die Metadatenliste an Chroma bereitstellen. Sie können IDs verwenden, um die Vektoren mit den anderswo gespeicherten Dokumenten zu verknüpfen.

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], ...],
    metadaten: [{"kapitel": "3", "vers": "16"}, {"kapitel": "3", "vers": "5"}, {"kapitel": "29", "vers": "11"}, ...],
})

Hinweis: Die Kernfunktion der Vektordatenbank ist die semantische Ähnlichkeitssuche basierend auf Vektordaten. Um die Größe der Vektordatenbank zu reduzieren und die Effizienz zu verbessern, können wir wählen, Vektordaten und einige filterbare Attributbedingungen in der Vektordatenbank zu speichern. Andere Daten, wie zum Beispiel Artikelinhalt, können in Datenbanken wie MYSQL gespeichert werden, solange sie durch IDs verknüpft sind.

Abfragen von Sammlungsdaten

Die Methode .query kann verwendet werden, um den Chroma-Datensatz auf verschiedene Weisen abzufragen.

Sie können mithilfe von query_embeddings (Vektordaten) abfragen.

Tipp: Um query_embeddings zu erhalten, wird in tatsächlichen Entwicklungsszenarien die Benutzerabfrage normalerweise zuerst in einen Abfragevektor über ein Texteinbettungsmodell umgerechnet, und dieser Vektor wird dann verwendet, um ähnliche Inhalte abzufragen.

const result = await collection.query({
    queryEmbeddings: [[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
    nResults: 10,
    where: {"metadata_field": "ist_gleich_diesem"},
})
// Eingabereihenfolge
// query_embeddings - optional
// n_results - erforderlich
// where - optional
// query_texts - optional

Die Abfrage gibt die top n_results Ergebnisse für jeden Abfragevektor (query_embedding) in Reihenfolge zurück. Es kann eine optionale where-Filterdictionary bereitgestellt werden, um die Ergebnisse basierend auf Metadaten, die jedem Dokument zugeordnet sind, zu filtern. Darüber hinaus kann eine optionale where_document-Filterdictionary bereitgestellt werden, um die Ergebnisse basierend auf dem Dokumenteninhalt zu filtern.

Wenn die bereitgestellten query_embeddings nicht mit den Dimensionen der Sammlung übereinstimmen, tritt eine Ausnahme auf. Um die Vektor-Konsistenz sicherzustellen, wird empfohlen, das gleiche Texteinbettungsmodell für die Berechnung der Vektoren zu verwenden.

Sie können auch mithilfe einer Reihe von Abfragetexten abfragen. Chroma berechnet zunächst den Vektor für jeden Abfragetext mithilfe der Einbettungsfunktion der Sammlung und führt dann die Abfrage mithilfe der generierten Textvektoren aus.

await collection.query({
    nResults: 10, // n_results
    where: {"metadata_field": "ist_gleich_diesem"}, // where
    queryTexts: ["dok10", "also sprach zarathustra", ...], // query_text
})

Sie können auch .get verwenden, um Daten aus der Sammlung nach ID abzufragen.

await collection.get({
    ids: ["id1", "id2", "id3", ...], //ids
    where: {"stil": "stil1"} // where
})

.get unterstützt auch where- und where_document-Filter. Wenn keine id bereitgestellt wird, werden alle Daten in der Sammlung zurückgegeben, die den where- und where_document-Filtern entsprechen.

Festlegen zurückgegebener Felder

Beim Verwenden von get oder query können Sie den include-Parameter verwenden, um die zurückzugebenden Datenfelder festzulegen, einschließlich Vektordaten, Dokumente und jegliche Daten in Metadaten. Standardmäßig gibt Chroma Dokumente, Metadaten und Vektorentfernungen zurück. Sie können die zurückzugebenden Felder festlegen, indem Sie ein Array von Feldnamen dem include-Parameter von get oder query übergeben.

collection.get(
    include=["dokumente"]
)

collection.query(
    query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
    include=["dokumente"]
)

Verwendung von Where-Filtern

Chroma unterstützt das Filtern von Abfragen basierend auf Metadaten und Dokumenteninhalt. Der where-Filter wird zum Filtern von Metadaten verwendet, und der where_document-Filter wird zum Filtern des Dokumenteninhalts verwendet. Im Folgenden erklären wir, wie Filterbedingungsausdrücke geschrieben werden.

Filtern nach Metadaten

Um Metadaten zu filtern, muss ein where-Filter-Dictionary für die Abfrage bereitgestellt werden. Das Dictionary muss die folgende Struktur haben:

{
    "metadatenfeld": {
        <Operator>: <Wert>
    }
}

Das Filtern von Metadaten unterstützt die folgenden Operatoren:

  • $eq - Gleich (String, Ganzzahl, Gleitkommazahl)
  • $ne - Ungleich (String, Ganzzahl, Gleitkommazahl)
  • $gt - Größer als (ganze Zahl, Gleitkommazahl)
  • $gte - Größer als oder gleich (ganze Zahl, Gleitkommazahl)
  • $lt - Kleiner als (ganze Zahl, Gleitkommazahl)
  • $lte - Kleiner als oder gleich (ganze Zahl, Gleitkommazahl)

Die Verwendung des $eq-Operators entspricht der Verwendung des where-Filters.

{
    "metadata_field": "Suchwort"
}


{
    "metadata_field": {
        "$eq": "Suchwort"
    }
}

Filtern von Dokumenteninhalt

Um den Dokumenteninhalt zu filtern, muss ein where_document-Filter-Dictionary für die Abfrage bereitgestellt werden. Das Dictionary muss die folgende Struktur haben:

{
    "$contains": "Suchwort"
}

Verwenden von logischen Operatoren

Sie können auch logische Operatoren wie $and und $or verwenden, um mehrere Filter zu kombinieren.

Der $and-Operator gibt Ergebnisse zurück, die allen Filtern in der Liste entsprechen.

{
    "$and": [
        {
            "Metadatenfeld": {
                <Operator>: <Wert>
            }
        },
        {
            "Metadatenfeld": {
                <Operator>: <Wert>
            }
        }
    ]
}

Der $or-Operator gibt Ergebnisse zurück, die einer beliebigen Filterbedingung in der Liste entsprechen.

{
    "$or": [
        {
            "Metadatenfeld": {
                <Operator>: <Wert>
            }
        },
        {
            "Metadatenfeld": {
                <Operator>: <Wert>
            }
        }
    ]
}

Daten aktualisieren

Chroma unterstützt auch die Upsert-Operation, mit der vorhandene Daten aktualisiert und neue Daten eingefügt werden können, wenn die Daten nicht vorhanden sind.

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]],
    metadaten: [{"Kapitel": "3", "Vers": "16"}, {"Kapitel": "3", "Vers": "5"}, {"Kapitel": "29", "Vers": "11"}],
    dokumente: ["dok1", "dok2", "dok3"]
})

Daten löschen

Chroma unterstützt das Löschen von Daten aus der Sammlung anhand der ID mit der Methode .delete.

await collection.delete({
    ids: ["id1", "id2", "id3",...], //IDs
    where: {"Kapitel": "20"} //Bedingung
})