Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Поиск ИИ Azure поддерживает импорт, анализ и индексирование данных из нескольких источников данных в единый консолидированный индекс поиска.
В этом руководстве по C# используется клиентская библиотека Azure.Search.Documents в пакете SDK azure для .NET для индексирования примеров данных отеля из экземпляра Azure Cosmos DB. Затем вы объединяете данные с сведениями о номере отеля, полученными из документов хранилища BLOB-объектов Azure. Результатом является объединенный индекс поиска отелей, содержащий документы отелей, в которых номера представлены как сложные типы данных.
Изучив это руководство, вы:
- Отправка примеров данных в источники данных
- Определение ключа документа
- определение и создание индекса;
- индексирование данных об отелях из Azure Cosmos DB;
- Объединение данных гостиничных номеров из хранилища блобов
Обзор
В этом руководстве используется Azure.Search.Documents для создания и запуска нескольких индексаторов. Вы отправляете примеры данных в два источника данных Azure и настраиваете индексатор, который извлекает из обоих источников для заполнения одного индекса поиска. Для поддержки слияния оба набора данных должны иметь общее значение. В этом руководстве это поле является идентификатором. Если в общем есть поле для поддержки сопоставления, индексатор может объединить данные из разрозненных ресурсов: структурированные данные из SQL Azure, неструктурированные данные из хранилища BLOB-объектов или любое сочетание поддерживаемых источников данных в Azure.
Готовую версию кода для этого руководства можно найти в следующем проекте:
Предварительные требования
- Учетная запись Azure с активной подпиской. Создайте учетную запись бесплатно .
- Учетная запись Azure Cosmos DB для NoSQL.
- Учетная запись хранения Azure.
- Служба поиска ИИ Azure.
- Визуальная студия.
Примечание.
Вы можете использовать бесплатную службу поиска для этого руководства. Уровень "Бесплатный" ограничивается тремя индексами, тремя индексаторами и тремя источниками данных. В этом руководстве создается по одному объекту из каждой категории. Перед началом работы убедитесь, что у вас есть место в службе, чтобы принять новые ресурсы.
Подготовка служб
В этом руководстве используется поиск ИИ Azure для индексирования и запросов, Azure Cosmos DB для первого набора данных и хранилища BLOB-объектов Azure для второго набора данных.
Желательно создать все службы в одном регионе и в одной группе ресурсов, чтобы упростить взаимодействие и управление. На практике ваши услуги могут находиться в любом регионе.
В этом примере используется два небольших набора данных, описывающих семь вымышленных отелей. Один набор описывает сами отели и будет загружен в базу данных Azure Cosmos DB. Другой набор содержит сведения о номере отеля и предоставляется в виде семи отдельных JSON-файлов для отправки в хранилище BLOB-объектов Azure.
Начало работы с Azure Cosmos DB
Перейдите к учетной записи Azure Cosmos DB на портале Azure.
В левой области выберите Обозреватель данных.
Выберите Новый контейнер>Новую базу данных.
Введите hotel-rooms-db для имени. Примите значения по умолчанию для остальных параметров.
Создайте контейнер, предназначенный для созданной ранее базы данных. Введите отели для имени контейнера и /HotelId для ключа секции.
Выберите отели>"Элементы", а затем нажмите кнопку "Отправить элемент " на панели команд.
Загрузите файл JSON из папки
cosmosdbв multiple-data-sources/v11.
Нажмите кнопку обновления, чтобы обновить представление элементов в коллекции отелей. Вы увидите в списке семь новых документов базы данных.
На левой панели выберите Настройки>Ключи.
Запишите строку подключения. Это значение необходимо для appsettings.json на следующем шаге. Если вы не использовали предлагаемое имя базы данных hotel-rooms-db , скопируйте имя базы данных.
Хранилище BLOB-объектов Azure
Перейдите к учетной записи хранения Azure на портале Azure.
В левой области выберитеконтейнеры> данных.
Создайте контейнер больших двоичных объектов с именем hotel-rooms, в котором будут храниться JSON-файлы с примерами данных о номерах отелей. Уровень доступа можно задать для любого допустимого значения.
Откройте контейнер и нажмите кнопку "Отправить " на панели команд.
Отправьте семь JSON-файлов из папки
blobв каталоге multiple-data-sources/v11.
В левой области выберите Безопасность и сеть>Ключи доступа.
Запишите имя учетной записи и строку подключения. Эти значения нужны для appsettings.json на следующем шаге.
Поиск с использованием ИИ Azure
Третий компонент — поиск ИИ Azure, который можно создать в портал Azure или найти существующую службу поиска в ресурсах Azure.
Копирование ключа администратора и URL-адреса для поиска искусственного интеллекта Azure
Чтобы выполнить проверку подлинности в службе поиска, вам потребуется URL-адрес службы и ключ доступа. Наличие валидного ключа устанавливает доверие для каждого запроса между приложением, отправляющим запрос, и службой, обрабатывающей его.
Перейдите в службу поиска в портал Azure.
В левой области выберите "Обзор".
Запишите URL-адрес, который должен выглядеть следующим
https://my-service.search.windows.netобразом.На левой панели выберите Настройки>Ключи.
Запишите ключ администратора для полного доступа к службе. Существуют два взаимозаменяемых ключа администратора, предназначенных для обеспечения непрерывности бизнес-процессов на случай, если вам потребуется сменить один из них. Вы можете использовать любой ключ для запросов на добавление, изменение и удаление объектов.
Настройка среды
Откройте
AzureSearchMultipleDataSources.slnфайл из multiple-data-sources/v11 в Visual Studio.В обозревателе решений щелкните проект правой кнопкой мыши и выберите пункт "Управление пакетами NuGet для решения...".
На вкладке "Обзор" найдите и установите следующие пакеты:
Azure.Search.Documents (версия 11.0 или более поздняя версия)
Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.Json
В обозревателе решений измените файл с данными
appsettings.jsonо подключении, собранными на предыдущих шагах.{ "SearchServiceUri": "<YourSearchServiceURL>", "SearchServiceAdminApiKey": "<YourSearchServiceAdminApiKey>", "BlobStorageAccountName": "<YourBlobStorageAccountName>", "BlobStorageConnectionString": "<YourBlobStorageConnectionString>", "CosmosDBConnectionString": "<YourCosmosDBConnectionString>", "CosmosDBDatabaseName": "hotel-rooms-db" }
Ключевые поля карты
Для объединения содержимого требуется, чтобы оба потока данных использовали одни и те же документы в индексе поиска.
В поиске ИИ Azure ключевое поле однозначно идентифицирует каждый документ. Каждый индекс поиска должен содержать только одно поле ключа типа Edm.String. Это поле ключа должно присутствовать в источнике данных для каждого документа, который добавляется к индексу. (Фактически, это единственное обязательное для заполнения поле.)
При индексировании данных из нескольких источников данных убедитесь, что каждая входящая строка или документ содержит общий ключ документа. Это позволяет объединить данные из двух физически разных исходных документов в новый документ поиска в объединенном индексе.
Часто требуется предварительное планирование, чтобы определить значимый ключ документа для вашего индекса и удостовериться, что он присутствует в обоих источниках данных. В этой демонстрации HotelId ключ для каждого отеля в Azure Cosmos DB также присутствует в JSON-объектах в хранилище Blob.
Индексаторы поиска ИИ Azure могут использовать сопоставления полей для переименования и даже переформатирования полей данных во время процесса индексирования, чтобы исходные данные могли быть перенаправлены в правильное поле индекса. Например, в Azure Cosmos DB идентификатор отеля называется HotelId, но в BLOB-файлах JSON для номеров отеля идентификатор отеля называется Id. Программа обрабатывает это несоответствие путем сопоставления Id поля из больших двоичных объектов с HotelId ключевым полем индексатора.
Примечание.
В большинстве случаев автоматически сгенерированные ключи документов, такие как создаваемые по умолчанию некоторыми индексаторами, не подходят в качестве ключей документов для комбинированных индексов. Как правило, используйте понятное, уникальное значение ключа, которое уже существует в источниках данных или можно легко добавить.
Изучение кода
При наличии параметров данных и конфигурации пример программы AzureSearchMultipleDataSources.sln должен быть готов к сборке и запуску.
Это простое консольное приложение для C#/.NET выполняет следующие задачи:
- Создает новый индекс на основе структуры данных класса C# Hotel, который также ссылается на классы Address и Room.
- создает источник данных и индексатор, который сопоставляет данные в Azure Cosmos DB с полями индекса Это оба объекта в поиске ИИ Azure.
- Запускает индексатор для загрузки данных отеля из Azure Cosmos DB.
- Создает второй источник данных и индексатор, который сопоставляет данные JSON-объектов с полями индекса.
- Запускает второй индексатор для загрузки данных о номерах отеля из хранилища Blob.
Прежде чем запустить программу, изучите код, определение индекса и определение индексатора. Соответствующий код находится в двух файлах:
-
Hotel.csсодержит схему, определяющую индекс. -
Program.csсодержит функции, которые создают индекс поиска ИИ Azure, источники данных и индексаторы, а также загружают объединенные результаты в индекс.
Создание индекса
В этом примере программы для определения и создания индекса поиска ИИ Azure используется CreateIndexAsync . Она использует класс FieldBuilder для создания структуры индекса из класса модели данных на C#.
Модель данных определяется классом Hotel, который также содержит ссылки на классы Address и Room. FieldBuilder углубляется в структуру определений нескольких классов, создавая на их основе сложную структуру данных для индекса. Теги метаданных применяются для определения атрибутов каждого поля, например сведений о поддержке поиска или сортировки.
Программа удаляет любой существующий индекс того же имени перед созданием нового, если вы хотите запустить этот пример несколько раз.
В следующих фрагментах файла Hotel.cs отображаются отдельные поля, за которым следует ссылка на другой класс модели данных, Room[], который, в свою очередь, определен в Room.cs файле (не показан).
. . .
[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; }
. . .
В файле Program.cs определяется SearchIndex с именем и коллекцией полей, создаваемой методом FieldBuilder.Build, а затем создается следующим образом:
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);
}
Создание источника данных и индексатора Azure Cosmos DB
Основная программа включает логику создания источника данных Azure Cosmos DB для данных отелей.
Во-первых, он объединяет имя базы данных Azure Cosmos DB со строкой подключения. Затем он определяет объект SearchIndexerDataSourceConnection .
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);
После создания источника данных программа настраивает индексатор Azure Cosmos DB с именем hotel-rooms-cosmos-indexer.
Программа обновляет все существующие индексаторы с тем же именем, перезаписав существующий индексатор с содержимым предыдущего кода. Она также включает действия сброса и запуска, если вы хотите несколько раз выполнить этот пример.
В следующем примере определяется расписание индексатора, поэтому оно выполняется один раз в день. Вы можете удалить свойство расписания из этого вызова, если вам не нужно, чтобы индексатор автоматически запускался в дальнейшем.
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);
}
Этот пример содержит простой блок try-catch, чтобы информировать о любых ошибках в процессе выполнения.
После запуска индексатора Azure Cosmos DB индексатор поиска содержит полный набор примеров документов отеля. Однако поле номеров для каждого отеля является пустым массивом, так как источник данных Azure Cosmos DB не содержит сведений о номере. Затем программа извлекает данные из облачного хранилища Blob, чтобы загрузить и объединить данные комнаты.
Создайте источник данных для Хранилище BLOB-объектов и индексатор.
Чтобы получить сведения о помещении, программа сначала настраивает источник данных хранилища Blob для ссылки на набор отдельных объектов JSON-blob.
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);
После создания источника данных программа настраивает индексатор BLOB-объектов с именем hotel-rooms-blob-indexer, как показано ниже.
Блобы в формате JSON содержат ключевое поле с именем Id вместо HotelId. В коде используется класс FieldMapping, сообщающий индексатору о необходимости направить значения поля Id в ключ документа HotelId в индексе.
Индексаторы хранилища BLOB-объектов могут использовать IndexingParameters для указания режима синтаксического анализа. Необходимо задать разные режимы синтаксического анализа в зависимости от того, представляют ли большие двоичные объекты один документ или несколько документов в одном большом двоичном объекте. В нашем примере каждый большой двоичный объект представляет один документ JSON, поэтому в коде используется режим анализа json. Дополнительные сведения о параметрах индексатора для анализа больших двоичных объектов JSON см. в этой статье.
В этом примере определяется расписание индексатора, поэтому оно выполняется один раз в день. Вы можете удалить свойство расписания из этого вызова, если вам не нужно, чтобы индексатор автоматически запускался в дальнейшем.
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);
}
Поскольку индекс уже заполнен данными о гостиницах из базы данных Azure Cosmos DB, индексатор BLOB обновляет существующие документы в индексе и добавляет к ним сведения о комнатах.
Примечание.
Если в обоих ваших источниках данных есть одинаковые неключевые поля, а данные в этих полях не совпадают, индекс содержит значения из того индексатора, который выполнялся последним. В нашем примере оба источника данных содержат HotelName поле. Если по какой-то причине данные в этом поле отличаются, для документов с одинаковым значением ключа данные из последнего индексированного источника данных — это значение, HotelName хранящееся в индексе.
Искать
После запуска программы можно просмотреть заполненный индекс поиска с помощью обозревателя поиска на портале Azure.
Перейдите в службу поиска в портал Azure.
В левой области выберите управление поиском>индексы.
Выберите пример номера отеля из списка индексов.
На вкладке обозревателя поиска введите запрос для термина, например
Luxury.В результатах должен отображаться по крайней мере один документ. Этот документ должен содержать список объектов комнаты в своем
Roomsмассиве.
Сброс и повторный запуск
На ранних экспериментальных этапах разработки наиболее эффективный способ итерации проектирования заключается в удалении объектов из службы "Поиск ИИ Azure", чтобы позволить вашему коду перестроить их. Имена ресурсов уникальны. Удаление объекта позволяет воссоздать его с использованием того же имени.
Пример кода проверяет наличие объектов и удаляет или обновляет их, так чтобы вы могли повторно выполнить программу. Вы также можете использовать портал Azure для удаления индексов, индексаторов и источников данных.
Очистка ресурсов
При работе с собственной подпиской в конце проекта рекомендуется удалить ресурсы, которые больше не нужны. Оставленные работающими ресурсы могут стоить вам денег. Вы можете удалить ресурсы по отдельности либо удалить всю группу ресурсов.
Ресурсы на портале Azure можно найти и управлять ими, используя ссылку "Все ресурсы" или "Группы ресурсов" в левой области.
Следующий шаг
Теперь, когда вы знакомы с приемом данных из нескольких источников, ознакомьтесь с конфигурацией индексатора, начиная с Azure Cosmos DB: