Samouczek: indeksowanie z wielu źródeł danych przy użyciu zestawu .NET SDK

Usługa Azure AI Search umożliwia importowanie, analizowanie i indeksowanie danych z wielu źródeł danych do jednego skonsolidowanego indeksu wyszukiwania.

Ten samouczek w języku C# używa biblioteki klienta Azure.Search.Documents w zestawie Azure SDK dla platformy .NET do indeksowania przykładowych danych hotelowych z wystąpienia usługi Azure Cosmos DB i scala je ze szczegółami pokoju hotelowego pochodzącymi z dokumentów usługi Azure Blob Storage. Wynikiem jest połączony indeks wyszukiwania hotelowego zawierający dokumenty hotelowe z pokojami jako złożonymi typami danych.

W tym samouczku wykonasz następujące zadania:

  • Przekazywanie przykładowych danych i tworzenie źródeł danych
  • Identyfikowanie klucza dokumentu
  • Definiowanie i tworzenie indeksu
  • Indeksowanie danych hotelowych z usługi Azure Cosmos DB
  • Scalanie danych pokoju hotelowego z magazynu obiektów blob

Jeśli nie masz subskrypcji platformy Azure, przed rozpoczęciem utwórz bezpłatne konto.

Omówienie

W tym samouczku użyto elementu Azure.Search.Documents do utworzenia i uruchomienia wielu indeksatorów. W tym samouczku skonfigurujesz dwa źródła danych platformy Azure, aby można było skonfigurować indeksator ściągający z obu tych źródeł w celu wypełnienia pojedynczego indeksu wyszukiwania. Dwa zestawy danych muszą mieć wspólną wartość do obsługi scalania. W tym przykładzie to pole jest identyfikatorem. Jeśli istnieje pole wspólne do obsługi mapowania, indeksator może scalić dane z różnych zasobów: dane ustrukturyzowane z usługi Azure SQL, dane bez struktury z usługi Blob Storage lub dowolną kombinację obsługiwanych źródeł danych na platformie Azure.

Ukończona wersja kodu w tym samouczku można znaleźć w następującym projekcie:

Wymagania wstępne

Uwaga

W tym samouczku możesz użyć bezpłatnej usługi wyszukiwania. Warstwa Bezpłatna ogranicza do trzech indeksów, trzech indeksatorów i trzech źródeł danych. W ramach tego samouczka tworzony jest jeden element każdego z tych typów. Przed rozpoczęciem upewnij się, że masz pokój w usłudze, aby zaakceptować nowe zasoby.

1 — Tworzenie usług

W tym samouczku użyto usługi Azure AI Search do indeksowania i zapytań, usługi Azure Cosmos DB dla jednego zestawu danych i usługi Azure Blob Storage dla drugiego zestawu danych.

Jeśli to możliwe, utwórz wszystkie usługi w tym samym regionie i grupie zasobów w celu zapewnienia zbliżenia i możliwości zarządzania. W praktyce usługi mogą znajdować się w dowolnym regionie.

W tym przykładzie użyto dwóch małych zestawów danych, które opisują siedem fikcyjnych hoteli. Jeden zestaw opisuje same hotele i zostanie załadowany do bazy danych usługi Azure Cosmos DB. Drugi zestaw zawiera szczegóły pokoju hotelowego i jest dostarczany jako siedem oddzielnych plików JSON do przekazania do usługi Azure Blob Storage.

Rozpoczynanie pracy z usługą Azure Cosmos DB

  1. Zaloguj się do witryny Azure Portal, a następnie przejdź do strony Przegląd konta usługi Azure Cosmos DB.

  2. Wybierz pozycję Eksplorator danych, a następnie wybierz pozycję Nowa baza danych.

    Tworzenie nowej bazy danych

  3. Wprowadź nazwę hotel-rooms-db. Zaakceptuj wartości domyślne pozostałych ustawień.

    Konfigurowanie bazy danych

  4. Tworzenie nowego typu kontenera. Użyj utworzonej właśnie istniejącej bazy danych. Wprowadź ciąg hotels dla nazwy kontenera i użyj /HotelId dla klucza partycji.

    Dodawanie kontenera

  5. Wybierz pozycję Elementy w obszarze hoteli, a następnie wybierz pozycję Przekaż element na pasku poleceń. Przejdź do folderu projektu, a następnie wybierz plik cosmosdb/HotelsDataSubset_CosmosDb.json .

    Przekazywanie do kolekcji usługi Azure Cosmos DB

  6. Użyj przycisku Odśwież, aby odświeżyć widok elementów w kolekcji hoteli. Powinny zostać wyświetlone siedem nowych dokumentów bazy danych.

  7. Skopiuj parametry połączenia ze strony Klucze do Notatnik. Ta wartość będzie potrzebna dla appsettings.json w późniejszym kroku. Jeśli nie użyto sugerowanej nazwy bazy danych "hotel-rooms-db", skopiuj również nazwę bazy danych.

Azure Blob Storage

  1. Zaloguj się do witryny Azure Portal, przejdź do konta usługi Azure Storage, wybierz pozycję Obiekty blob, a następnie wybierz pozycję + Kontener.

  2. Utwórz kontener obiektów blob o nazwie hotel-rooms do przechowywania przykładowych plików JSON pokoju hotelowego. Poziom dostępu publicznego można ustawić na dowolną z prawidłowych wartości.

    Tworzenie kontenera obiektów blob

  3. Po utworzeniu kontenera otwórz go i wybierz pozycję Przekaż na pasku poleceń. Przejdź do folderu zawierającego przykładowe pliki. Wybierz wszystkie z nich, a następnie wybierz pozycję Przekaż.

    Przekaż pliki

  4. Skopiuj nazwę konta magazynu i parametry połączenia ze strony Klucze dostępu do Notatnik. Obie wartości będą potrzebne dla appsettings.json w późniejszym kroku.

Trzecim składnikiem jest usługa Azure AI Search, którą można utworzyć w portalu lub znaleźć istniejącą usługę wyszukiwania w zasobach platformy Azure.

Aby uwierzytelnić się w usłudze wyszukiwania, potrzebny jest adres URL usługi i klucz dostępu.

  1. Zaloguj się do witryny Azure Portal i na stronie Przegląd usługi wyszukiwania uzyskaj adres URL. Przykładowy punkt końcowy może wyglądać podobnie jak https://mydemo.search.windows.net.

  2. W Ustawienia> Keys uzyskaj klucz administratora dla pełnych praw w usłudze. Istnieją dwa zamienne klucze administratora, które zapewniają ciągłość działania na wypadek konieczności przerzucania jednego. Możesz użyć klucza podstawowego lub pomocniczego na żądaniach dodawania, modyfikowania i usuwania obiektów.

    Uzyskiwanie nazwy usługi oraz kluczy administracyjnych i zapytań

Prawidłowy klucz ustanawia relację zaufania dla danego żądania między aplikacją wysyłającą żądanie i usługą, która je obsługuje.

2 — Konfigurowanie środowiska

  1. Uruchom program Visual Studio i w menu Narzędzia wybierz pozycję NuGet Menedżer pakietów, a następnie pozycję Zarządzaj pakietami NuGet dla rozwiązania....

  2. Na karcie Przeglądaj znajdź i zainstaluj plik Azure.Search.Documents (wersja 11.0 lub nowsza).

  3. Wyszukaj pakiety NuGet Microsoft.Extensions.Configuration i Microsoft.Extensions.Configuration.Json i zainstaluj je również.

  4. Otwórz plik rozwiązania /v11/AzureSearchMultipleDataSources.sln.

  5. W Eksplorator rozwiązań edytuj plik appsettings.json, aby dodać informacje o połączeniu.

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

Pierwsze dwa wpisy to adres URL i klucze administratora usługi wyszukiwania. Użyj pełnego punktu końcowego, na przykład: https://mydemo.search.windows.net.

Następne wpisy określają nazwy kont i parametry połączenia informacje dotyczące źródeł danych usługi Azure Blob Storage i Azure Cosmos DB.

3 — Mapowanie pól klucza

Scalanie zawartości wymaga, aby oba strumienie danych dotyczyły tych samych dokumentów w indeksie wyszukiwania.

W usłudze Azure AI Search pole klucza jednoznacznie identyfikuje każdy dokument. Każdy indeks wyszukiwania musi mieć dokładnie jedno pole klucza typu Edm.String. To pole klucza musi być obecne dla każdego dokumentu w źródle danych dodanym do indeksu. (W rzeczywistości jest to jedyne wymagane pole).

Podczas indeksowania danych z wielu źródeł danych upewnij się, że każdy przychodzący wiersz lub dokument zawiera wspólny klucz dokumentu umożliwiający scalanie danych z dwóch fizycznie odrębnych dokumentów źródłowych do nowego dokumentu wyszukiwania w połączonym indeksie.

Często wymaga to planowania z góry, aby zidentyfikować znaczący klucz dokumentu dla indeksu i upewnić się, że istnieje on w obu źródłach danych. W tym pokazie HotelId kluczem dla każdego hotelu w usłudze Azure Cosmos DB są również obiekty blob JSON w usłudze Blob Storage.

Indeksatory usługi Azure AI Search mogą używać mapowań pól do zmieniania nazw, a nawet ponownego formatowania pól danych podczas procesu indeksowania, dzięki czemu dane źródłowe mogą być kierowane do poprawnego pola indeksu. Na przykład w usłudze Azure Cosmos DB identyfikator hotelu nosi nazwę HotelId. Jednak w plikach obiektów blob JSON dla pokoi hotelowych identyfikator hotelu nosi nazwę Id. Program obsługuje tę rozbieżność, mapując Id pole z obiektów blob na HotelId pole klucza w indeksatorze.

Uwaga

W większości przypadków automatycznie generowane klucze dokumentów, takie jak te utworzone domyślnie przez niektórych indeksatorów, nie tworzą dobrych kluczy dokumentów dla połączonych indeksów. Ogólnie rzecz biorąc, warto użyć znaczącej, unikatowej wartości klucza, która już istnieje lub można ją łatwo dodać do źródeł danych.

4 — Eksplorowanie kodu

Po wprowadzeniu ustawień danych i konfiguracji przykładowy program w pliku /v11/AzureSearchMultipleDataSources.sln powinien być gotowy do skompilowania i uruchomienia.

Ta prosta aplikacja konsolowa C#/.NET wykonuje następujące zadania:

  • Tworzy nowy indeks na podstawie struktury danych klasy hotelowej języka C# (która również odwołuje się do klas Address i Room).
  • Tworzy nowe źródło danych i indeksator mapujący dane usługi Azure Cosmos DB na pola indeksowania. Są to oba obiekty w usłudze Azure AI Search.
  • Uruchamia indeksator, aby załadować dane hotelowe z usługi Azure Cosmos DB.
  • Tworzy drugie źródło danych i indeksator mapujący dane obiektu blob JSON na pola indeksowania.
  • Uruchamia drugi indeksator, aby załadować dane rooms z usługi Blob Storage.

Przed uruchomieniem programu zapoznaj się z kodem oraz definicjami indeksatora i indeksatora dla tego przykładu. Odpowiedni kod znajduje się w dwóch plikach:

  • Hotel.cs zawiera schemat definiujący indeks
  • Program.cs zawiera funkcje, które tworzą indeks usługi Azure AI Search, źródła danych i indeksatory oraz ładują połączone wyniki do indeksu.

Tworzenie indeksu

Ten przykładowy program używa metody CreateIndexAsync do definiowania i tworzenia indeksu usługi Azure AI Search. Korzysta z klasy FieldBuilder, aby wygenerować strukturę indeksu na podstawie klasy modelu danych języka C#.

Model danych jest definiowany przez klasę Hotel, która zawiera również odwołania do klas Address i Room. Obiekt FieldBuilder przechodzi do szczegółów wielu definicji klas, aby wygenerować złożoną strukturę danych dla indeksu. Tagi metadanych służą do definiowania atrybutów każdego pola, takich jak możliwość wyszukiwania lub sortowania.

Program usunie dowolny istniejący indeks o tej samej nazwie przed utworzeniem nowego, jeśli chcesz uruchomić ten przykład więcej niż raz.

Poniższe fragmenty kodu z pliku Hotel.cs pokazują pojedyncze pola, a następnie odwołanie do innej klasy modelu danych Room[], które z kolei jest zdefiniowane w pliku Room.cs (nie pokazano).

. . .
[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; }
. . .

W pliku Program.cs indeks wyszukiwania jest definiowany z nazwą i kolekcją pól wygenerowaną przez FieldBuilder.Build metodę, a następnie utworzoną w następujący sposób:

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);
}

Tworzenie źródła danych i indeksatora usługi Azure Cosmos DB

Następnie główny program zawiera logikę tworzenia źródła danych usługi Azure Cosmos DB dla danych hoteli.

Najpierw łączy nazwę bazy danych usługi Azure Cosmos DB z parametry połączenia. Następnie definiuje obiekt SearchIndexerDataSource Połączenie ion.

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);

Po utworzeniu źródła danych program konfiguruje indeksator usługi Azure Cosmos DB o nazwie hotel-rooms-cosmos-indexer.

Program zaktualizuje wszystkie istniejące indeksatory o tej samej nazwie, zastępując istniejący indeksator zawartością powyższego kodu. Obejmuje również akcje resetowania i uruchamiania, jeśli chcesz uruchomić ten przykład więcej niż raz.

W poniższym przykładzie zdefiniowano harmonogram indeksatora, aby był uruchamiany raz dziennie. Możesz usunąć właściwość schedule z tego wywołania, jeśli indeksator nie ma automatycznie uruchamiać ponownie w przyszłości.

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);
}

Ten przykład zawiera prosty blok try-catch umożliwiający zgłaszanie błędów, które mogą wystąpić podczas wykonywania.

Po uruchomieniu indeksatora usługi Azure Cosmos DB indeks wyszukiwania będzie zawierać pełny zestaw przykładowych dokumentów hotelowych. Jednak pole pokoi dla każdego hotelu będzie pustą tablicą, ponieważ źródło danych usługi Azure Cosmos DB pomija szczegóły pokoju. Następnie program ściągnie z usługi Blob Storage, aby załadować i scalić dane pomieszczenia.

Tworzenie źródła danych i indeksatora usługi Blob Storage

Aby uzyskać szczegóły pomieszczenia, program najpierw konfiguruje źródło danych usługi Blob Storage w celu odwołwania się do zestawu pojedynczych plików obiektów blob JSON.

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);

Po utworzeniu źródła danych program konfiguruje indeksator obiektów blob o nazwie hotel-rooms-blob-indexer, jak pokazano poniżej.

Obiekty blob JSON zawierają pole klucza o nazwie Id zamiast HotelId. Kod używa FieldMapping klasy do przekazania indeksatorowi Id wartości pola do HotelId klucza dokumentu w indeksie.

Indeksatory usługi Blob Storage mogą używać indeksowaniaParametry do określania trybu analizowania. Należy ustawić różne tryby analizowania w zależności od tego, czy obiekty blob reprezentują pojedynczy dokument, czy wiele dokumentów w ramach tego samego obiektu blob. W tym przykładzie każdy obiekt blob reprezentuje pojedynczy dokument JSON, więc kod używa json trybu analizowania. Aby uzyskać więcej informacji na temat parametrów analizowania indeksatora dla obiektów blob JSON, zobacz Indeksowanie obiektów blob JSON.

W tym przykładzie zdefiniowano harmonogram indeksatora, aby był uruchamiany raz dziennie. Możesz usunąć właściwość schedule z tego wywołania, jeśli indeksator nie ma automatycznie uruchamiać ponownie w przyszłości.

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);
}

Ponieważ indeks został już wypełniony danymi hotelowymi z bazy danych usługi Azure Cosmos DB, indeksator obiektów blob aktualizuje istniejące dokumenty w indeksie i dodaje szczegóły pokoju.

Uwaga

Jeśli masz te same pola inne niż kluczowe w obu źródłach danych, a dane w tych polach nie są zgodne, indeks będzie zawierać wartości z tego, z których indeksator był ostatnio uruchamiany. W naszym przykładzie oba źródła danych zawierają pole HotelName . Jeśli z jakiegoś powodu dane w tym polu są inne, w przypadku dokumentów o tej samej wartości klucza dane HotelName ze źródła danych, które zostało ostatnio indeksowane, będą wartością przechowywaną w indeksie.

Po uruchomieniu programu możesz eksplorować wypełniony indeks wyszukiwania przy użyciu Eksploratora wyszukiwania w portalu.

W witrynie Azure Portal otwórz stronę Przegląd usługi wyszukiwania i znajdź indeks hotel-rooms-sample na liście Indeksy.

Lista indeksów usługi Azure AI Search

Wybierz indeks hotel-rooms-sample na liście. Zobaczysz interfejs Eksploratora wyszukiwania dla indeksu. Wprowadź zapytanie dotyczące terminu takiego jak "Luksus". Powinien zostać wyświetlony co najmniej jeden dokument w wynikach, a ten dokument powinien zawierać listę obiektów pomieszczeń w tablicy pomieszczeń.

Resetowanie i ponowne uruchamianie

Na wczesnym etapie eksperymentalnym programowania najbardziej praktycznym podejściem do iteracji projektowej jest usunięcie obiektów z usługi Azure AI Search i umożliwienie ponownego kompilowania kodu. Nazwy zasobów są unikatowe. Usunięcie obiektu umożliwia jego ponowne utworzenie przy użyciu tej samej nazwy.

Przykładowy kod sprawdza istniejące obiekty i usuwa lub aktualizuje je, aby można było ponownie uruchomić program.

Za pomocą portalu można również usuwać indeksy, indeksatory i źródła danych.

Czyszczenie zasobów

Gdy pracujesz we własnej subskrypcji, na końcu projektu warto usunąć zasoby, których już nie potrzebujesz. Uruchomione zasoby mogą generować koszty. Zasoby możesz usuwać pojedynczo lub jako grupę zasobów, usuwając cały zestaw zasobów.

Zasoby można znaleźć w portalu i zarządzać nimi, korzystając z linku Wszystkie zasoby lub Grupy zasobów w okienku nawigacji po lewej stronie.

Następne kroki

Teraz, gdy znasz już koncepcję pozyskiwania danych z wielu źródeł, przyjrzyjmy się bliżej konfiguracji indeksatora, zaczynając od usługi Azure Cosmos DB.