Python Chromadb Detaillierte Entwickleranleitung

Installation

pip install chromadb

Persistieren von Chromadb-Daten

import chromadb

Sie können den Speicherpfad für die Chroma-Datenbankdatei angeben. Wenn die Daten vorhanden sind, wird die Datenbankdatei beim Start des Programms automatisch geladen.

client = chromadb.PersistentClient(path="/data/tizi365.db")

Der Parameter path ist der Pfad zur Chroma-Datenbankdatei.

Hinweis: Für eine Chroma-Datenbank genügt es, einmal ein Client-Objekt zu erstellen. Das Laden und Speichern mehrerer Clients im gleichen Pfad kann zu unerwartetem Verhalten führen, einschließlich Datenlöschung. In der Regel sollte in der Anwendung nur ein Chroma-Client erstellt werden.

Einige häufig verwendete Funktionen des Client-Objekts:

client.reset()  # Löscht und setzt die Datenbank vollständig zurück

Sammlungsoperationen

Chromadb verwendet das collection-Prinzip zur Verwaltung von Vektordaten, das mit Tabellen in MYSQL verglichen werden kann.

Erstellen, Anzeigen und Löschen von Sammlungen

Chromadb 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 einem Kleinbuchstaben oder einer Zahl beginnen und enden, und kann Punkte, Bindestriche und Unterstriche dazwischen enthalten.
  • Der Name darf keine beiden aufeinander folgenden Punkte enthalten.
  • Der Name kann keine gültige IP-Adresse sein.

Um eine Sammlung zu erstellen, müssen Sie den Sammlungsnamen und eine optionale Vektorberechnungsfunktion (auch als Einbettungsfunktion bekannt) angeben. Falls eine Einbettungsfunktion bereitgestellt wird, muss sie jedes Mal bereitgestellt werden, wenn auf die Sammlung zugegriffen wird.

Hinweis: Der Zweck der Vektorberechnungsfunktion (Einbettungsfunktion) besteht darin, den Textvektor zu berechnen.

collection = client.create_collection(name="my_collection", embedding_function=emb_fn)
collection = client.get_collection(name="my_collection", embedding_function=emb_fn)

Die Einbettungsfunktion nimmt Text als Eingabe und gibt einen berechneten Vektor zurück.

Hinweis: Anfänger können mehr über Texteinbettungsmodell-Tutorials erfahren.

Sie können auf eine vorhandene Sammlung mit der .get_collection-Funktion verweisen und mit .delete_collection eine Sammlung löschen. Sie können auch .get_or_create_collection verwenden, um auf eine Sammlung zu verweisen (falls sie existiert) oder sie zu erstellen, wenn sie nicht existiert.

collection = client.get_collection(name="tizi365")
collection = client.get_or_create_collection(name="tizi365")
client.delete_collection(name="tizi365")

Weitere häufig verwendete Sammlungsoperationen:

collection.peek() # Gibt eine Liste der ersten 10 Daten in der Sammlung zurück
collection.count() # Gibt die Gesamtanzahl der Daten in der Sammlung zurück
collection.modify(name="neuer_name") # Benennt die Sammlung um

Spezifizierung der Vektorabstandsberechnungsmethode

Die create_collection-Funktion enthält auch einen optionalen Metadatenparameter. Durch das Setzen des Werts von hnsw:space kann die Berechnungsmethode des Vektorraumabstands angepasst werden.

Hinweis: Vektordaten stellen die Ähnlichkeit zwischen Vektoren durch die Berechnung des räumlichen Abstands zwischen Vektoren dar. Je näher der Abstand, desto höher die Ähnlichkeit, und umgekehrt.

collection = client.create_collection(
        name="collection_name",
        metadata={"hnsw:space": "cosine"} # l2 ist die Standardberechnungsmethode
    )

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

Hinzufügen von Daten zu einer Sammlung

Verwenden Sie die Methode .add, um Daten zu Chroma hinzuzufügen.

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

collection.add(
    documents=["Lorem Ipsum...", "Dokument 2", "Dokument 3", ...],
    metadaten=[{"Kapitel": "3", "Vers": "16"}, {"Kapitel": "3", "Vers": "5"}, {"Kapitel": "29", "Vers": "11"}, ...],
    ids=["id1", "id2", "id3", ...]
)

Wenn Chroma eine Liste von Dokumenten erhält, verwendet es automatisch die Einbettungsfunktion der Sammlung, um die Vektoren für die Dokumente zu berechnen (wenn bei der Erstellung der Sammlung keine Einbettungsfunktion angegeben wurde, wird der Standardwert verwendet). Chroma speichert auch die Dokumente selbst. Wenn ein Dokument aufgrund seiner Größe nicht mit der ausgewählten Einbettungsfunktion berechnet werden kann, tritt eine Ausnahme auf.

Jedes Dokument muss eine eindeutige ID (ids) haben. Das Hinzufügen derselben ID zweimal führt lediglich zur Speicherung des ursprünglichen Werts. Optional können Sie eine Liste von Metadaten-Dictionarys (metadaten) für jedes Dokument bereitstellen, um zusätzliche Informationen zu speichern, die bei Abfragen zur Datenfilterung verwendet werden können.

Alternativ können Sie direkt eine Liste der mit dem Dokument verbundenen Vektordaten bereitstellen, und Chroma wird die von Ihnen bereitgestellten Vektordaten ohne automatische Berechnung der Vektoren verwenden.

collection.add(
    documents=["Dokument 1", "Dokument 2", "Dokument 3", ...],
    einbettungen=[[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"}, ...],
    ids=["id1", "id2", "id3", ...]
)

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

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

collection.add(
    einbettungen=[[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"}, ...],
    ids=["id1", "id2", "id3", ...]
)

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 notwendige Filterattribute in der Vektordatenbank zu speichern. Andere Daten, wie beispielsweise Artikelinhalte, können in Datenbanken wie MYSQL gespeichert werden, solange sie über IDs verknüpft sind.

Abfrage von Sammlungsdaten

Die Methode .query kann verwendet werden, um Chroma-Datensätze auf vielfältige Weise abzufragen.

Sie können mithilfe von Abfrage-Einbettungen (Vektordaten) abfragen.

Tipp: In realen Entwicklungsszenarien werden Abfrage-Einbettungen in der Regel erst durch die Berechnung des Vektors der Benutzerabfrage mithilfe eines Texteinbettungsmodells erhalten und dann verwendet, um ähnliche Inhalte abzufragen.

collection.query(
    query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
    n_results=10,
    where={"metadata_field": "ist_gleich_diesem"},
    where_document={"$contains":"suchbegriff"}
)

Die Abfrage gibt die n_results Ergebnisse zurück, die am besten zu jedem Abfragevektor (query_embedding) passen. Optional kann ein Filter-Dictionary (where) bereitgestellt werden, um Ergebnisse basierend auf Metadaten, die jedem Dokument zugeordnet sind, zu filtern. Zusätzlich kann ein optionales where_document-Filter-Dictionary bereitgestellt werden, um Ergebnisse basierend auf dem Dokumenteninhalt zu filtern.

Wenn die bereitgestellten Abfrage-Einbettungen nicht mit den Dimensionen der Sammlung übereinstimmen, tritt eine Ausnahme auf. Verwenden Sie das gleiche Texteinbettungsmodell, um konsistente Vektordimensionen zu gewährleisten.

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 unter Verwendung der generierten Textvektoren durch.

collection.query(
    query_texts=["Dokument10", "Also sprach Zarathustra", ...],
    n_results=10,
    where={"metadata_field": "ist_gleich_diesem"},
    where_document={"$contains":"suchbegriff"}
)

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

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

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

Festlegen von Rückgabefeldern

Bei der Verwendung von get oder query können Sie den include-Parameter verwenden, um die zurückzugebenden Daten--Einbettungen, Dokumente oder Metadaten zu spezifizieren, und für Abfragen müssen Distanzdaten zurückgegeben werden. Standardmäßig gibt Chroma Dokumente und Metadaten zurück und gibt bei Abfragen Distanzdaten zurück, während "ids" immer zurückgibt. Sie können die zurückzugebenden Felder spezifizieren, indem Sie ein Array von Feldnamen an den include-Parameter der query- oder get-Methode ü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 Dokumentinhalt. Der where-Filter wird verwendet, um Metadaten zu filtern, und der where_document-Filter wird verwendet, um den Dokumentinhalt zu filtern, und im Folgenden wird erläutert, wie Filterbedingungsausdrücke geschrieben werden.

Filtern nach Metadaten

Um Metadaten zu filtern, müssen Sie eine where-Filter-Dictionary für die Abfrage bereitstellen. Das Dictionary muss die folgende Struktur haben:

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

Die Filterung von Metadaten unterstützt die folgenden Operatoren:

  • $eq - gleich (String, Integer, Float)
  • $ne - ungleich (String, Integer, Float)
  • $gt - größer als (Integer, Float)
  • $gte - größer als oder gleich (Integer, Float)
  • $lt - kleiner als (Integer, Float)
  • $lte - kleiner als oder gleich (Integer, Float)

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

{
    "metadata_field": "suchbegriff"
}

{
    "metadata_field": {
        "$eq": "suchbegriff"
    }
}

Filtern des Dokumentinhalts

Um den Dokumentinhalt zu filtern, müssen Sie ein where_document-Filter-Dictionary für die Abfrage bereitstellen. Das Dictionary muss die folgende Struktur haben:

{
    "$contains": "suchbegriff"
}

Verwendung von logischen Operatoren

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

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

{
    "$and": [
        {
            "metadata_field": {
                <Operator>: <Value>
            }
        },
        {
            "metadata_field": {
                <Operator>: <Value>
            }
        }
    ]
}

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

{
    "$or": [
        {
            "metadata_field": {
                <Operator>: <Value>
            }
        },
        {
            "metadata_field": {
                <Operator>: <Value>
            }
        }
    ]
}

Aktualisierung von Daten in einer Sammlung

Mit .update können Sie Eigenschaften der Daten in einer Sammlung aktualisieren.

collection.update(
    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", ...],
)

Wenn eine ID nicht in der Sammlung gefunden wird, wird ein Fehler aufgezeichnet und das Update ignoriert. Wenn das bereitgestellte Dokument keinen entsprechenden Vektor hat, wird die Einbettungsfunktion der Sammlung verwendet, um den Vektor zu berechnen.

Wenn die bereitgestellten Vektordaten eine andere Dimension haben als die Sammlung, tritt eine Ausnahme auf.

Chroma unterstützt auch die Upsert-Operation, die vorhandene Daten aktualisieren und neue Daten einfügen kann, wenn sie nicht vorhanden sind.

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", ...],
)

Löschen von Sammlungsdaten

Chroma unterstützt die Verwendung von .delete, um Daten aus einer Sammlung anhand der id zu entfernen. Die Vektoren, Dokumente und Metadaten, die mit jedem Datensatz verbunden sind, werden ebenfalls gelöscht.

collection.delete(
    ids=["id1", "id2", "id3",...],
    where={"Kapitel": "20"}
)

.delete unterstützt auch einen where-Filter. Wenn keine ID bereitgestellt wird, löscht es alle Elemente in der Sammlung, die dem where-Filter entsprechen.