Teilen über


Index- und Abfragevektoren in Azure Cosmos DB for NoSQL in .NET.

GILT FÜR: NoSQL

Die Vektorsuche in Azure Cosmos DB for NoSQL ist derzeit ein Vorschaufeature. Sie müssen sich vor der Verwendung für die Vorschau registrieren. In diesem Artikel werden die folgenden Schritte behandelt:

  1. Registrieren für die Vorschau der Vektorsuche in Azure Cosmos DB for NoSQL
  2. Einrichten des Azure Cosmos DB-Containers für die Vektorsuche
  3. Richtlinie zum Erstellen von Vektoreinbettung
  4. Hinzufügen von Vektorindizes zur Containerindizierungsrichtlinie
  5. Erstellen eines Containers mit Vektorindizes und Vektoreinbettungsrichtlinie
  6. Durchführen einer Vektorsuche für die gespeicherten Daten.
  7. Dieser Leitfaden führt Sie durch den Prozess zum Erstellen und Indizieren von Vektordaten sowie zum anschließenden Abfragen dieser Daten in einem Container.

Voraussetzungen

Registrieren für die Vorschau

Für die Vektorsuche für Azure Cosmos DB for NoSQL ist eine Vorschau-Featureregistrierung erforderlich. Führen Sie die folgenden Schritte aus, um sich zu registrieren:

  1. Navigieren Sie zu Ihrer Azure Cosmos DB for NoSQL-Ressourcenseite.

  2. Wählen Sie den Bereich "Features" unter dem Menüelement "Einstellungen" aus.

  3. Wählen Sie für "Vektorsuche in Azure Cosmos DB for NoSQL" aus.

  4. Lesen Sie die Beschreibung des Features, um zu bestätigen, dass Sie sich in der Vorschau registrieren möchten.

  5. Wählen Sie "Aktivieren" aus, um sich bei der Vorschau zu registrieren.

Hinweis

Die Registrierungsanforderung wird automatisch genehmigt, es kann jedoch mehrere Minuten dauern, bis sie wirksam wird.

Bei den folgenden Schritten wird davon ausgegangen, dass Sie wissen, wie Sie ein Cosmos DB NoSQL-Konto einrichten und eine Datenbank erstellen. Das Vektorsuchfeature wird derzeit für die vorhandenen Container nicht unterstützt. Daher müssen Sie einen neuen Container erstellen und die Vektor-Vektoreinbettungsrichtlinie und die Vektorindizierungsrichtlinie zum Zeitpunkt der Containererstellung angeben.

Sehen wir uns ein Beispiel für das Erstellen einer Datenbank für eine internetbasierte Buchhandlung an, und Sie speichern Titel, Autor, ISBN und Beschreibung für jedes Buch. Außerdem definieren wir zwei Eigenschaften, die Vektoreinbettungen enthalten sollen. Die erste ist die Eigenschaft "contentVector", die Texteinbettungen enthält, die aus dem Textinhalt des Buchs generiert werden (z. B. Verketten der Eigenschaften "title" "author" "isbn" und "description" vor dem Erstellen des Einbettens). Die zweite ist "coverImageVector", die aus Bildern des Bucheinbands generiert wird.

  1. Erstellen und speichern Sie Vektoreinbettungen für die Felder, für die Sie die Vektorsuche ausführen möchten.
  2. Geben Sie die Pfade zum Einbetten von Vektoren in die Vektoreinbettungsrichtlinie an.
  3. Fügen Sie alle gewünschten Vektorindizes in die Indizierungsrichtlinie für den Container ein.

Für nachfolgende Abschnitte dieses Artikels betrachten wir die folgende Struktur für die in unserem Container gespeicherten Elemente:

{
"title": "book-title", 
"author": "book-author", 
"isbn": "book-isbn", 
"description": "book-description", 
"contentVector": [2, -1, 4, 3, 5, -2, 5, -7, 3, 1], 
"coverImageVector": [0.33, -0.52, 0.45, -0.67, 0.89, -0.34, 0.86, -0.78] 
} 

Erstellen einer Vektoreinbettungsrichtlinie für Ihren Container.

Als Nächstes müssen Sie eine Containervektorrichtlinie definieren. Diese Richtlinie enthält Informationen, die verwendet werden, um das Azure Cosmos DB-Abfragemodul darüber zu informieren, wie Vektoreigenschaften in den VectorDistance-Systemfunktionen behandelt werden. Diese Richtlinie informiert auch die Vektorindizierungsrichtlinie über die erforderlichen Informationen, wenn Sie eine angeben möchten. Die folgenden Informationen sind in der enthaltenen Vektorrichtlinie enthalten:

  • "path": Der Eigenschaftspfad, der Vektoren enthält
  • "datatype": Der Typ der Elemente des Vektors (Standard Float32)
  • "dimensions": Die Länge jedes Vektors im Pfad (Standard 1536)
  • „distanceFunction“: Die Metrik, die zum Berechnen der Entfernung/Ähnlichkeit verwendet wird (Standard: Kosinus)

Für unser Beispiel mit Buchdetails kann die Vektorrichtlinie wie das JSON-Beispiel unten aussehen:

  Database db = await client.CreateDatabaseIfNotExistsAsync("vector-benchmarking");
  List<Embedding> embeddings = new List<Embedding>()
  {
      new Embedding()
      {
          Path = "/coverImageVector",
          DataType = VectorDataType.Float32,
          DistanceFunction = DistanceFunction.Cosine,
          Dimensions = 8,
      },
      new Embedding()
      {
          Path = "/contentVector",
          DataType = VectorDataType.Float32,
          DistanceFunction = DistanceFunction.Cosine,
          Dimensions = 10,
      }
  };

Erstellen eines Vektorindexes in der Indizierungsrichtlinie

Sobald die Vektoreinbettungspfade festgelegt wurden, müssen Vektorindizes der Indizierungsrichtlinie hinzugefügt werden. Derzeit wird das Vektorsuchfeature für Azure Cosmos DB for NoSQL nur für neue Container unterstützt, sodass Sie die Vektorrichtlinie während des Zeitpunkts der Containererstellung anwenden müssen und sie später nicht geändert werden kann. In diesem Beispiel würde die Indizierungsrichtlinie etwa wie folgt aussehen:

    Collection<Embedding> collection = new Collection<Embedding>(embeddings);
    ContainerProperties properties = new ContainerProperties(id: "vector-container", partitionKeyPath: "/id")
    {   
        VectorEmbeddingPolicy = new(collection),
        IndexingPolicy = new IndexingPolicy()
        {
            VectorIndexes = new()
            {
                new VectorIndexPath()
                {
                    Path = "/vector",
                    Type = VectorIndexType.QuantizedFlat,
                }
            }
        },
    };
    properties.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });    
    properties.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/vector/*" });

Wichtig

Dieser Vektorpfad wurde dem Abschnitt „excludedPaths“ der Indizierungsrichtlinie hinzugefügt, um eine optimierte Leistung für das Einfügen sicherzustellen. Wenn der Vektorpfad nicht zu „excludedPaths“ hinzugefügt wird, führt dies zu einer höheren RU-Belastung und Latenz für Vektoreinfügungen.

Wichtig

Derzeit wird die Vektorsuche in Azure Cosmos DB for NoSQL nur für neue Container unterstützt. Sie müssen sowohl die Containervektorrichtlinie als auch jede Vektorindizierungsrichtlinie während des Zeitpunkts der Containererstellung festlegen, da sie später nicht geändert werden kann. Beide Richtlinien können in einer zukünftigen Verbesserung des Previewfeatures geändert werden.

Ausführen einer Suchabfrage zur Vektorähnlichkeit

Nachdem Sie einen Container mit der gewünschten Vektorrichtlinie erstellt und Vektordaten in den Container eingefügt haben, können Sie eine Vektorsuche mithilfe der Vektordistanz-Systemfunktion in einer Abfrage durchführen. Angenommen, Sie möchten nach Büchern über Lebensmittelrezepte suchen, indem Sie sich die Beschreibung ansehen. Sie müssen dann zuerst die Einbettungen für Ihren Abfragetext abrufen. In diesem Fall möchten Sie möglicherweise Einbettungen für den Abfragetext "Lebensmittelrezept" generieren. Sobald Sie die Einbettung für Ihre Suchabfrage haben, können Sie sie in der VectorDistance-Funktion in der Vektorsuchabfrage verwenden und alle Elemente abrufen, die Ihrer Abfrage ähnlich sind, wie hier gezeigt:

SELECT TOP 10 c.title, VectorDistance(c.contentVector, [1,2,3,4,5,6,7,8,9,10]) AS SimilarityScore   
FROM c  
ORDER BY VectorDistance(c.contentVector, [1,2,3,4,5,6,7,8,9,10])   

Diese Abfrage ruft die Buchtitel zusammen mit Ähnlichkeitsbewertungen in Bezug auf Ihre Abfrage ab. Hier ist ein Beispiel für .NET:

  float[] embedding = {1f,2f,3f,4f,5f,6f,7f,8f,9f,10f};
  var queryDef = new QueryDefinition(
      query: $"SELECT c.title, VectorDistance(c.contentVector,@embedding) AS SimilarityScore FROM c ORDER BY VectorDistance(c.contentVector,@embedding)"
      ).WithParameter("@embedding", embedding);
  using FeedIterator<Object> feed = container.GetItemQueryIterator<Object>(
      queryDefinition: queryDef
  );
  while (feed.HasMoreResults) 
  {
      FeedResponse<Object> response = await feed.ReadNextAsync();
      foreach ( Object item in response)
      {
          Console.WriteLine($"Found item:\t{item}");
      }
  }

Nächste Schritte