Freigeben über


Tutorial: Indizieren von mehreren Datenquellen mithilfe des .NET SDK

Azure AI Search unterstützt das Importieren, Analysieren und Indizieren von Daten aus mehreren Datenquellen in einen einzigen konsolidierten Suchindex.

In diesem C#-Lernprogramm wird die Azure.Search.Documents-Clientbibliothek im Azure SDK für .NET verwendet, um Beispiel-Hoteldaten aus einer Azure Cosmos DB-Instanz zu indizieren. Anschließend führen Sie die Daten mit Details zu Hotelzimmern zusammen, die aus Azure Blob Storage-Dokumenten abgerufen wurden. Das Ergebnis ist ein kombinierter Hotelsuchindex, der Hoteldokumente enthält, mit Räumen als komplexe Datentypen.

In diesem Tutorial erfahren Sie:

  • Hochladen von Beispieldaten in Datenquellen
  • Ermitteln des Dokumentschlüssels
  • Definieren und Erstellen des Index
  • Indizieren von Hoteldaten aus Azure Cosmos DB
  • Zusammenführen von Hotelraumdaten aus Blob Storage

Übersicht

In diesem Tutorial wird Azure.Search.Documents verwendet, um mehrere Indexer zu erstellen und auszuführen. Sie laden Beispieldaten in zwei Azure-Datenquellen hoch und konfigurieren einen Indexer, der aus beiden Quellen abruft, um einen einzelnen Suchindex aufzufüllen. Die beiden Datasets müssen einen gemeinsamen Wert aufweisen, um die Zusammenführung zu unterstützen. In diesem Tutorial ist das Feld eine ID. Solange ein Feld gemeinsam die Zuordnung unterstützt, kann ein Indexer Daten aus unterschiedlichen Ressourcen zusammenführen: strukturierte Daten aus Azure SQL, unstrukturierte Daten aus Blob Storage oder eine beliebige Kombination von unterstützten Datenquellen in Azure.

Eine fertige Version des Codes in diesem Tutorial finden Sie im folgenden Projekt:

Voraussetzungen

Hinweis

Sie können einen kostenlosen Suchdienst für dieses Tutorial verwenden. Der Free-Tarif ist auf drei Indizes, drei Indexer und drei Datenquellen beschränkt. In diesem Tutorial wird davon jeweils eine Instanz erstellt. Bevor Sie beginnen, stellen Sie sicher, dass Sie Platz auf Ihrem Dienst haben, um die neuen Ressourcen zu akzeptieren.

Vorbereiten von Diensten

In diesem Lernprogramm wird Azure AI Search für die Indizierung und Abfragen, Azure Cosmos DB für den ersten Datensatz und Azure Blob Storage für den zweiten Datensatz verwendet.

Alle Dienste sollten nach Möglichkeit in derselben Region und Ressourcengruppe erstellt werden, um eine möglichst große Nähe zu erreichen und die Verwaltung zu vereinfachen. In der Praxis können sich Ihre Dienste in einer beliebigen Region befinden.

In diesem Beispiel werden zwei kleine Datenmengen verwendet, die sieben fiktive Hotels beschreiben. Ein Satz beschreibt die Hotels selbst und wird in eine Azure Cosmos DB-Datenbank geladen. Der andere Satz enthält Details zu Hotelzimmern und wird als sieben separate JSON-Dateien bereitgestellt, die in Azure Blob Storage hochgeladen werden sollen.

Starten mit Azure Cosmos DB

  1. Melden Sie sich beim Azure-Portal an, und wählen Sie Ihr Azure Cosmos DB-Konto aus.

  2. Wählen Sie im linken Bereich den Daten-Explorer aus.

  3. Wählen Sie Neuer Container>Neue Datenbank aus.

    Erstellen einer neuen Datenbank

  4. Geben Sie "hotel-rooms-db " für den Namen ein. Übernehmen Sie die Standardwerte für die verbleibenden Einstellungen.

    Konfigurieren der Datenbank

  5. Erstellen Sie einen Container, der auf die zuvor erstellte Datenbank ausgerichtet ist. Geben Sie Hotels für den Containernamen und /HotelId für den Partitionsschlüssel ein.

    Hinzufügen eines Containers

  6. Wählen Sie "Hotels>Elemente" und dann auf der Befehlsleiste " Element hochladen " aus.

  7. Laden Sie die JSON-Datei aus dem cosmosdb Ordner in mehreren Datenquellen/v11 hoch.

    Hochladen in die Azure Cosmos DB-Sammlung

  8. Verwenden Sie die Schaltfläche "Aktualisieren", um die Ansicht der Elemente in der Hotelsammlung zu aktualisieren. Daraufhin sollten sieben neue Datenbankdokumente aufgeführt werden.

  9. Wählen Sie im linken Bereich Einstellungen>Schlüssel aus.

  10. Notieren Sie sich eine Verbindungszeichenfolge. Sie benötigen diesen Wert für appsettings.json in einem späteren Schritt. Wenn Sie nicht den vorgeschlagenen Datenbanknamen "hotel-rooms-db " verwendet haben, kopieren Sie auch den Datenbanknamen.

Azure Blob Storage

  1. Melden Sie sich beim Azure-Portal an, und wählen Sie Ihr Azure Storage-Konto aus.

  2. Wählen Sie im linken Bereich "Datenspeichercontainer>" aus.

  3. Erstellen Sie einen Blobcontainer mit dem Namen hotel-rooms zum Speichern der exemplarischen JSON-Hotelzimmerdateien. Sie können die Zugriffsebene auf einen beliebigen gültigen Wert festlegen.

    Erstellen eines Blobcontainers

  4. Öffnen Sie den Container, und wählen Sie dann auf der Befehlsleiste "Hochladen" aus.

  5. Laden Sie die sieben JSON-Dateien aus dem blob Ordner in mehreren Datenquellen/v11 hoch.

    Hochladen von Dateien

  6. Wählen Sie im linken Bereich "Sicherheit +>" aus.

  7. Notieren Sie sich den Kontonamen und eine Verbindungszeichenfolge. Sie benötigen beide Werte für appsettings.json in einem späteren Schritt.

Azure KI-Suche ist die dritte Komponente, die Sie im Azure-Portal erstellen können. Sie können auch in Ihren Azure-Ressourcen nach einem vorhandenen Suchdienst suchen.

Um sich bei Ihrem Suchdienst zu authentifizieren, benötigen Sie die Dienst-URL und einen Zugriffsschlüssel. Ein gültiger Schlüssel stellt eine Vertrauensstellung pro Anforderung zwischen der Anwendung, die die Anforderung sendet, und dem Dienst, der sie verarbeitet, her.

  1. Melden Sie sich beim Azure-Portal an, und wählen Sie Ihren Suchdienst aus.

  2. Wählen Sie im linken Bereich die Option "Übersicht" aus.

  3. Notieren Sie sich die URL, die wie https://my-service.search.windows.net aussehen sollte.

  4. Wählen Sie im linken Bereich Einstellungen>Schlüssel aus.

  5. Notieren Sie sich einen Administratorschlüssel für vollständige Rechte für den Dienst. Es gibt zwei austauschbare Administratorschlüssel – diese wurden zum Zweck der Geschäftskontinuität bereitgestellt, falls Sie einen Rollover für einen Schlüssel durchführen müssen. Sie können einen der Schlüssel für Anforderungen zum Hinzufügen, Ändern und Löschen von Objekten verwenden.

Richten Sie Ihre Umgebung ein

  1. Öffnen Sie die AzureSearchMultipleDataSources.sln Datei aus mehreren Datenquellen/v11 in Visual Studio.

  2. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt und wählen Sie „NuGet-Pakete für Projektmappe verwalten“ aus.

  3. Suchen und installieren Sie auf dem Durchsuchen-Tab die folgenden Pakete:

    • Azure.Search.Documents (Version 11.0 oder höher)

    • Microsoft.Extensions.Configuration

    • Microsoft.Extensions.Configuration.Json

  4. Bearbeiten Sie im Projektmappen-Explorer die appsettings.json Datei mit den Verbindungsinformationen, die Sie in den vorherigen Schritten gesammelt haben.

    {
      "SearchServiceUri": "<YourSearchServiceURL>",
      "SearchServiceAdminApiKey": "<YourSearchServiceAdminApiKey>",
      "BlobStorageAccountName": "<YourBlobStorageAccountName>",
      "BlobStorageConnectionString": "<YourBlobStorageConnectionString>",
      "CosmosDBConnectionString": "<YourCosmosDBConnectionString>",
      "CosmosDBDatabaseName": "hotel-rooms-db"
    }
    

Schlüsselfelder zuordnen

Zum Zusammenführen von Inhalten ist es erforderlich, dass beide Datenströme im Suchindex auf dieselben Dokumente ausgerichtet sind.

In Azure KI Search werden die einzelnen Dokumente durch das Schlüsselfeld eindeutig identifiziert. Jeder Suchindex muss über genau ein Schlüsselfeld vom Typ Edm.Stringverfügen. Dieses Schlüsselfeld muss für jedes Dokument in einer Datenquelle vorhanden sein, die dem Index hinzugefügt wird. (Es ist gleichzeitig das einzige erforderliche Feld.)

Stellen Sie beim Indizieren von Daten aus mehreren Datenquellen sicher, dass jede eingehende Zeile oder jedes Dokument einen gemeinsamen Dokumentschlüssel enthält. Auf diese Weise können Sie Daten aus zwei physisch unterschiedlichen Quelldokumenten in einem neuen Suchdokument im kombinierten Index zusammenführen.

Häufig ist es erforderlich, einen aussagekräftigen Dokumentschlüssel für Ihren Index zu identifizieren und sicherzustellen, dass er in beiden Datenquellen vorhanden ist. In dieser Demo ist der HotelId Schlüssel für jedes Hotel in Azure Cosmos DB auch in den Zimmerdaten-JSON-Blobs im Blob-Speicher enthalten.

Azure KI Search-Indexer können Feldzuordnungen verwenden, um während der Indizierung den Namen und sogar das Format von Datenfeldern zu ändern, damit Quelldaten dem korrekten Indexfeld zugeführt werden können. Beispielsweise wird in der Azure Cosmos DB der Hotelbezeichner HotelId genannt, aber in den JSON-Blob-Dateien für die Hotelzimmer wird der Hotelbezeichner Id genannt. Das Programm behandelt diese Diskrepanz, indem es das Feld Id aus den Blobs dem Schlüsselfeld HotelId im Indexer zuordnet.

Hinweis

In den meisten Fällen sind automatisch erstellte Dokumentschlüssel, wie die von einigen Indexern standardmäßig erzeugten, keine guten Dokumentschlüssel für kombinierte Indexe. Verwenden Sie im Allgemeinen einen aussagekräftigen, eindeutigen Schlüsselwert, der bereits in Ihren Datenquellen vorhanden ist oder einfach hinzugefügt werden kann.

Untersuchen des Codes

Wenn die Daten- und Konfigurationseinstellungen vorhanden sind, sollte das Beispielprogramm AzureSearchMultipleDataSources.sln zum Erstellen und Ausführen bereit sein.

Diese einfache C#/.NET-Konsolen-App führt folgende Aufgaben aus:

  • Erstellt einen neuen Index basierend auf der Datenstruktur der C#Hotel-Klasse, die auch auf die Adress- und Raumklassen verweist.
  • Sie erstellt eine neue Datenquelle und einen Indexer, der Azure Cosmos DB-Daten Indexfeldern zuordnet. Beides sind Objekte in Azure KI Search.
  • Führt den Indexer aus, um Hoteldaten aus Azure Cosmos DB zu laden.
  • Sie erstellt eine zweite Datenquelle und einen Indexer, der JSON-Blobdaten Indexfeldern zuordnet.
  • Führt den zweiten Indexer aus, um Hotelraumdaten aus Blob Storage zu laden.

Bevor Sie das Programm ausführen, nehmen Sie sich eine Minute Zeit, um den Code, die Indexdefinition und die Indexerdefinition zu untersuchen. Der relevante Code befindet sich in zwei Dateien:

  • Hotel.cs enthält das Schema, das den Index definiert.
  • Program.cs enthält Funktionen, die den Azure AI Search-Index, Datenquellen und Indexer erstellen und die kombinierten Ergebnisse in den Index laden.

Erstellen eines Index

In diesem Beispielprogramm wird CreateIndexAsync verwendet, um einen Azure KI Search-Index zu definieren und zu erstellen. Das SDK nutzt die Klasse FieldBuilder, um eine Indexstruktur auf der Grundlage einer C#-Datenmodellklasse zu generieren.

Das Datenmodell wird durch die Klasse „Hotel“ definiert, die auch Verweise auf die Klassen „Address“ und „Room“ enthält. „FieldBuilder“ führt ein Drilldown durch die verschiedenen Klassendefinitionen aus, um eine komplexe Datenstruktur für den Index zu generieren. Mithilfe von Metadatentags werden die Attribute der einzelnen Felder definiert, um beispielsweise anzugeben, ob das Feld durchsuchbar oder sortierbar ist.

Das Programm löscht alle vorhandenen Indexe desselben Namens, bevor Sie das neue erstellen, falls Sie dieses Beispiel mehrmals ausführen möchten.

Die folgenden Codeausschnitte aus der Hotel.cs Datei zeigen einzelne Felder, gefolgt von einem Verweis auf eine andere Datenmodellklasse, Room[], die wiederum in Room.cs der Datei definiert ist (nicht dargestellt).

. . .
[SimpleField(IsFilterable = true, IsKey = true)]
public string HotelId { get; set; }

[SearchableField(IsFilterable = true, IsSortable = true)]
public string HotelName { get; set; }
. . .
public Room[] Rooms { get; set; }
. . .

In der Program.cs Datei wird ein SearchIndex mit einem Namen und einer feldauflistung definiert, die von der FieldBuilder.Build Methode generiert wird, und anschließend wie folgt erstellt:

private static async Task CreateIndexAsync(string indexName, SearchIndexClient indexClient)
{
    // Create a new search index structure that matches the properties of the Hotel class.
    // The Address and Room classes are referenced from the Hotel class. The FieldBuilder
    // will enumerate these to create a complex data structure for the index.
    FieldBuilder builder = new FieldBuilder();
    var definition = new SearchIndex(indexName, builder.Build(typeof(Hotel)));

    await indexClient.CreateIndexAsync(definition);
}

Erstellen der Azure Cosmos DB-Datenquelle und des zugehörigen Indexers

Das Hauptprogramm umfasst Logik zum Erstellen der Azure Cosmos DB-Datenquelle für die Hotelsdaten.

Zunächst verkettet sie den Azure Cosmos DB-Datenbanknamen mit der Verbindungszeichenfolge. Anschließend wird ein SearchIndexerDataSourceConnection -Objekt definiert.

private static async Task CreateAndRunCosmosDbIndexerAsync(string indexName, SearchIndexerClient indexerClient)
{
    // Append the database name to the connection string
    string cosmosConnectString =
        configuration["CosmosDBConnectionString"]
        + ";Database="
        + configuration["CosmosDBDatabaseName"];

    SearchIndexerDataSourceConnection cosmosDbDataSource = new SearchIndexerDataSourceConnection(
        name: configuration["CosmosDBDatabaseName"],
        type: SearchIndexerDataSourceType.CosmosDb,
        connectionString: cosmosConnectString,
        container: new SearchIndexerDataContainer("hotels"));

    // The Azure Cosmos DB data source does not need to be deleted if it already exists,
    // but the connection string might need to be updated if it has changed.
    await indexerClient.CreateOrUpdateDataSourceConnectionAsync(cosmosDbDataSource);

Nachdem die Datenquelle erstellt wurde, richtet das Programm einen Azure Cosmos DB-Indexer mit dem Namen hotel-rooms-cosmos-indexerein.

Das Programm aktualisiert alle vorhandenen Indexer mit demselben Namen und überschreibt den vorhandenen Indexer mit dem Inhalt des vorherigen Codes. Er enthält auch Aktionen zum Zurücksetzen und Ausführen, falls Sie dieses Beispiel mehrmals ausführen möchten.

Im folgenden Beispiel wird ein Zeitplan für den Indexer definiert, sodass er einmal pro Tag ausgeführt wird. Sie können die Zeitplaneigenschaft aus diesem Aufruf entfernen, wenn der Indexer in Zukunft nicht mehr automatisch ausgeführt werden soll.

SearchIndexer cosmosDbIndexer = new SearchIndexer(
    name: "hotel-rooms-cosmos-indexer",
    dataSourceName: cosmosDbDataSource.Name,
    targetIndexName: indexName)
{
    Schedule = new IndexingSchedule(TimeSpan.FromDays(1))
};

// Indexers keep metadata about how much they have already indexed.
// If we already ran the indexer, it "remembers" and does not run again.
// To avoid this, reset the indexer if it exists.
try
{
    await indexerClient.GetIndexerAsync(cosmosDbIndexer.Name);
    // Reset the indexer if it exists.
    await indexerClient.ResetIndexerAsync(cosmosDbIndexer.Name);
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
    // If the indexer does not exist, 404 will be thrown.
}

await indexerClient.CreateOrUpdateIndexerAsync(cosmosDbIndexer);

Console.WriteLine("Running Azure Cosmos DB indexer...\n");

try
{
    // Run the indexer.
    await indexerClient.RunIndexerAsync(cosmosDbIndexer.Name);
}
catch (RequestFailedException ex) when (ex.Status == 429)
{
    Console.WriteLine("Failed to run indexer: {0}", ex.Message);
}

Dieses Beispiel enthält einen einfachen try-catch-Block, um Fehler zu melden, die ggf. bei der Ausführung auftreten.

Nachdem der Azure Cosmos DB-Indexer ausgeführt wurde, enthält der Suchindex einen vollständigen Satz von Beispiel-Hoteldokumenten. Das Zimmerfeld für jedes Hotel ist jedoch ein leeres Array, da die Azure Cosmos DB-Datenquelle Raumdetails ausgelassen. Als Nächstes zieht das Programm Daten aus dem Blob Storage, um die Raumdaten zu laden und zusammenzuführen.

Erstellen von Blob Storage-Datenquellen und Indexer

Um die Raumdetails abzurufen, richtet das Programm zunächst eine Blob Storage-Datenquelle ein, um auf eine Reihe einzelner JSON-Blobdateien zu verweisen.

private static async Task CreateAndRunBlobIndexerAsync(string indexName, SearchIndexerClient indexerClient)
{
    SearchIndexerDataSourceConnection blobDataSource = new SearchIndexerDataSourceConnection(
        name: configuration["BlobStorageAccountName"],
        type: SearchIndexerDataSourceType.AzureBlob,
        connectionString: configuration["BlobStorageConnectionString"],
        container: new SearchIndexerDataContainer("hotel-rooms"));

    // The blob data source does not need to be deleted if it already exists,
    // but the connection string might need to be updated if it has changed.
    await indexerClient.CreateOrUpdateDataSourceConnectionAsync(blobDataSource);

Nachdem die Datenquelle erstellt wurde, richtet das Programm einen BLOB-Indexer mit dem Namen hotel-rooms-blob-indexerein, wie unten dargestellt.

Die JSON-Blobs enthalten anstelle von Id ein Schlüsselfeld namens HotelId . Der Code weist den Indexer mithilfe der FieldMapping-Klasse an, den Wert des Felds Id an den Dokumentschlüssel HotelId im Index weiterzuleiten.

Blob Storage-Indexer können IndexingParameters verwenden, um einen Analysemodus anzugeben. Sie sollten unterschiedliche Analysemodi festlegen, je nachdem, ob Blobs ein einzelnes Dokument oder mehrere Dokumente innerhalb desselben Blob darstellen. In diesem Beispiel stellt jedes Blob ein einzelnes JSON-Dokument dar, weshalb im Code der Analysemodus json verwendet wird. Weitere Informationen zu Indexer-Analyseparametern für JSON-Blobs finden Sie unter Indizieren von JSON-Blobs mit dem Azure Search-Blobindexer.

In diesem Beispiel wird ein Zeitplan für den Indexer definiert, sodass er einmal pro Tag ausgeführt wird. Sie können die Zeitplaneigenschaft aus diesem Aufruf entfernen, wenn der Indexer in Zukunft nicht mehr automatisch ausgeführt werden soll.

IndexingParameters parameters = new IndexingParameters();
parameters.Configuration.Add("parsingMode", "json");

SearchIndexer blobIndexer = new SearchIndexer(
    name: "hotel-rooms-blob-indexer",
    dataSourceName: blobDataSource.Name,
    targetIndexName: indexName)
{
    Parameters = parameters,
    Schedule = new IndexingSchedule(TimeSpan.FromDays(1))
};

// Map the Id field in the Room documents to the HotelId key field in the index
blobIndexer.FieldMappings.Add(new FieldMapping("Id") { TargetFieldName = "HotelId" });

// Reset the indexer if it already exists
try
{
    await indexerClient.GetIndexerAsync(blobIndexer.Name);
    await indexerClient.ResetIndexerAsync(blobIndexer.Name);
}
catch (RequestFailedException ex) when (ex.Status == 404) { }

await indexerClient.CreateOrUpdateIndexerAsync(blobIndexer);

try
{
    // Run the indexer.
    await searchService.Indexers.RunAsync(blobIndexer.Name);
}
catch (CloudException e) when (e.Response.StatusCode == (HttpStatusCode)429)
{
    Console.WriteLine("Failed to run indexer: {0}", e.Response.Content);
}

Da der Index bereits mit Hoteldaten aus der Azure Cosmos DB-Datenbank gefüllt ist, aktualisiert der BLOB-Indexer die vorhandenen Dokumente im Index und fügt die Raumdetails hinzu.

Hinweis

Wenn beide Datenquellen die gleichen schlüsselfremden Felder enthalten und die Daten in diesen Feldern nicht übereinstimmen, enthält der Index die Werte des zuletzt ausgeführten Indexers. In unserem Beispiel enthalten beide Datenquellen ein HotelName Feld. Wenn sich die Daten in diesem Feld aus irgendeinem Grund unterscheiden, ist für Dokumente mit demselben Schlüsselwert die HotelName Daten aus der zuletzt indizierten Datenquelle der im Index gespeicherte Wert.

Nachdem Sie das Programm ausgeführt haben, können Sie den ausgefüllten Suchindex mithilfe des Such-Explorers im Azure-Portal erkunden.

  1. Melden Sie sich beim Azure-Portal an, und wählen Sie Ihren Suchdienst aus.

  2. Wählen Sie im linken Bereich "Suchverwaltungsindizes>" aus.

  3. Wählen Sie aus der Liste der Indizes ein Beispiel für Hotelräume aus.

  4. Geben Sie auf der Registerkarte "Such-Explorer" eine Abfrage für einen Begriff wie Luxury ein.

    In den Ergebnissen sollte mindestens ein Dokument angezeigt werden. Dieses Dokument sollte eine Liste von Raumobjekten in seinem Rooms Array enthalten.

Zurücksetzen und erneut ausführen

In den frühen experimentellen Phasen der Entwicklung ist es am praktischsten, die Objekt aus Azure KI-Suche zu löschen und von Ihrem Code neu erstellen zu lassen. Ressourcennamen sind eindeutig. Wenn Sie ein Objekt löschen, können Sie es unter dem gleichen Namen neu erstellen.

Im Beispielcode wird eine Überprüfung auf vorhandene Objekte durchgeführt. Diese werden dann gelöscht oder aktualisiert, damit Sie das Programm erneut ausführen können. Sie können das Azure-Portal auch verwenden, um Indizes, Indexer und Datenquellen zu löschen.

Bereinigen von Ressourcen

Wenn Sie in Ihrem eigenen Abonnement arbeiten, sollten Sie am Ende eines Projekts die nicht mehr benötigten Ressourcen entfernen. Ressourcen, die weiterhin ausgeführt werden, können Sie Geld kosten. Sie können entweder einzelne Ressourcen oder aber die Ressourcengruppe löschen, um den gesamten Ressourcensatz zu entfernen.

Sie können Ressourcen im Azure-Portal mithilfe des Links "Alle Ressourcen" oder "Ressourcengruppen" im linken Bereich suchen und verwalten.

Nächster Schritt

Nachdem Sie nun mit dem Aufnehmen von Daten aus mehreren Quellen vertraut sind, werfen Sie einen genaueren Blick auf die Indexerkonfiguration, beginnend mit Azure Cosmos DB: