你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

教程:使用 .NET SDK 为 Azure SQL 数据编制索引

了解如何将 索引器 配置为从 Azure SQL 数据库提取可搜索数据,并将其发送到 Azure AI 搜索中的搜索索引。

在本教程中,你将使用 C# 和 用于 .NET 的 Azure SDK 来:

  • 创建连接到 Azure SQL 数据库的数据源
  • 创建索引器
  • 运行索引器以将数据载入索引
  • 以验证步骤的形式查询索引

先决条件

注意

可在本教程中使用免费搜索服务。 免费层限制为三个索引、三个索引器和三个数据源。 本教程每样创建一个。 在开始之前,请确保服务中有足够的空间来接受新资源。

下载文件

本教程的源代码位于 Azure-Samples/search-dotnet-getting-started GitHub 存储库中的 DotNetHowToIndexer 文件夹内。

创建服务

本教程使用 Azure AI 搜索来编制索引和查询,将 Azure SQL 数据库用作外部数据源。 如果可能,请在同一区域和资源组中创建这两个服务,使它们相互靠近并易于管理。 在实践中,Azure SQL 数据库可以位于任意区域中。

从 Azure SQL 数据库开始

本教程提供了示例下载中的 hotels.sql 文件来填充数据库。 Azure AI 搜索使用平展行集,例如从视图或查询生成的行集。 示例解决方案中的 SQL 文件创建并填充单个表。

如果有现有的 Azure SQL 数据库资源,可以从 “打开”查询 步骤开始向其添加酒店表。

  1. 创建 Azure SQL 数据库。 数据库的服务器配置非常重要:

    • 选择提示你指定用户名和密码的 SQL Server 身份验证选项。 索引器使用的 ADO.NET 连接字符串需要用到它。

    • 选择公共连接,使本教程更易于完成。 不建议将公共资源用于生产,建议在本教程结束时 删除此资源

    服务器配置的屏幕截图。

  2. 在 Azure 门户中,转到新资源。

  3. 添加允许从客户端访问的防火墙规则。 可以从命令提示符运行 ipconfig 以获取你的 IP 地址。

  4. 使用查询编辑器加载示例数据。 在导航窗格中,选择 “查询编辑器”(预览), 并输入服务器管理员的用户名和密码。

    如果收到访问被拒错误,请从错误消息复制客户端 IP 地址,打开服务器的网络安全页,然后添加允许从你的客户端访问的入站规则。

  5. 在查询编辑器中选择“打开查询”,然后在本地计算机上导航到 hotels.sql 文件所在的位置。

  6. 选择该文件,然后选择“打开”。 此脚本应与以下屏幕截图类似:

    屏幕截图显示查询编辑器窗口中的 SQL 脚本。

  7. 选择“运行”以执行查询。 在“ 结果 ”窗格中,应会看到三行的查询成功消息。

  8. 若要从此表返回一个行集,可执行以下充当验证步骤的查询:

    SELECT * FROM Hotels
    
  9. 复制数据库的 ADO.NET 连接字符串 在“设置连接字符串”>下,复制 ADO.NET 连接字符串,该字符串应类似于以下示例:

    Server=tcp:<YOUR-DATABASE-NAME>.database.windows.net,1433;Initial Catalog=hotels-db;Persist Security Info=False;User ID=<YOUR-USER-NAME>;Password=<YOUR-PASSWORD>;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
    

在下一步中,需要此连接字符串来设置环境。

下一个组件是可以在 Azure 门户中创建的 Azure AI 搜索。 可以使用免费层来完成本教程。

API 调用需要服务 URL 和访问密钥。 搜索服务是使用这二者创建的,因此,如果向订阅添加了 Azure AI 搜索,则请按以下步骤获取必需信息:

  1. 登录到 Azure 门户。 在服务 概述 页上,复制终结点 URL。 示例终结点可能类似于 https://mydemo.search.windows.net

  2. “设置密钥”>上,获取服务完全权限的管理密钥。 有两个可交换的管理员密钥,为保证业务连续性而提供,以防需要滚动一个密钥。 可以在请求中使用主要或辅助密钥来添加、修改和删除对象。

    Azure 门户页面的屏幕截图,其中显示了搜索服务的 HTTP 终结点和访问密钥位置。

设置环境

  1. 启动 Visual Studio 并打开 DotNetHowToIndexers.sln

  2. 在解决方案资源管理器中,打开“appsettings.json”以提供连接信息。

  3. 对于 SearchServiceEndPoint,如果您的服务概述页上的完整 URL 是https://my-demo-service.search.windows.net,请提交该全部 URL。

  4. 对于 AzureSqlConnectionString,字符串格式类似于 "Server=tcp:<your-database-name>.database.windows.net,1433;Initial Catalog=hotels-db;Persist Security Info=False;User ID=<your-user-name>;Password=<your-password>;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"

    {
      "SearchServiceEndPoint": "<placeholder-search-full-url>",
      "SearchServiceAdminApiKey": "<placeholder-admin-key-for-search-service>",
      "AzureSqlConnectionString": "<placeholder-ADO.NET-connection-string",
    }
    
  5. 将 SQL 连接字符串中的用户密码替换为有效的密码。 数据库和用户名将被复制,但您必须手动输入密码。

创建管道

索引器需要数据源对象和索引。 相关代码在两个文件中:

  • hotel.cs 包含定义索引的架构
  • Program.cs 包含用于在服务中创建和管理结构的函数

在 hotel.cs 中

索引架构定义字段集合,包括指定允许作的属性,例如字段是可全文搜索、可筛选还是可排序,如以下字段定义 HotelName所示。 SearchableField 按定义可搜索全文。 其他属性被显式分配。

. . . 
[SearchableField(IsFilterable = true, IsSortable = true)]
[JsonPropertyName("hotelName")]
public string HotelName { get; set; }
. . .

模式还可以包含其他元素,例如用于提升搜索分数的评分配置文件和自定义分析器。 但是,在本教程中,架构是稀疏定义的,只包含示例数据集中找到的字段。

在 Program.cs 中

主程序包含用于创建索引器客户端、索引、数据源和索引器的逻辑。 代码检查并删除同名的现有资源,假设你可能多次运行此程序。

数据源对象是使用特定于 Azure SQL 数据库资源的设置配置的,其中包括部分或增量索引,用于使用 Azure SQL 的内置更改检测功能。 Azure SQL 中的 hotels 源演示数据库包含一个名为 IsDeleted 的“软删除”列。 如果在数据库中将此列设置为 true,则索引器会从 Azure AI 搜索索引中删除相应的文档。

Console.WriteLine("Creating data source...");

var dataSource =
      new SearchIndexerDataSourceConnection(
         "hotels-sql-ds",
         SearchIndexerDataSourceType.AzureSql,
         configuration["AzureSQLConnectionString"],
         new SearchIndexerDataContainer("hotels"));

indexerClient.CreateOrUpdateDataSourceConnection(dataSource);

索引器对象与平台无关,无论源如何,配置、计划和调用都是相同的。 此示例索引器包括一个计划和一个重置选项,用于清除索引器历史记录。 它还调用方法以立即创建并运行索引器。 若要创建或更新索引器,请使用 CreateOrUpdateIndexerAsync

Console.WriteLine("Creating Azure SQL indexer...");

var schedule = new IndexingSchedule(TimeSpan.FromDays(1))
{
      StartTime = DateTimeOffset.Now
};

var parameters = new IndexingParameters()
{
      BatchSize = 100,
      MaxFailedItems = 0,
      MaxFailedItemsPerBatch = 0
};

// Indexer declarations require a data source and search index.
// Common optional properties include a schedule, parameters, and field mappings
// The field mappings below are redundant due to how the Hotel class is defined, but 
// we included them anyway to show the syntax 
var indexer = new SearchIndexer("hotels-sql-idxr", dataSource.Name, searchIndex.Name)
{
      Description = "Data indexer",
      Schedule = schedule,
      Parameters = parameters,
      FieldMappings =
      {
         new FieldMapping("_id") {TargetFieldName = "HotelId"},
         new FieldMapping("Amenities") {TargetFieldName = "Tags"}
      }
};

await indexerClient.CreateOrUpdateIndexerAsync(indexer);

索引器运行通常是计划的,但在开发过程中,你可能希望使用 RunIndexerAsync 立即运行索引器。

Console.WriteLine("Running Azure SQL indexer...");

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

生成解决方案

选择 F5 以生成并运行解决方案。 程序在调试模式下执行。 控制台窗口报告每项操作的状态。

屏幕截图显示程序的控制台输出。

代码将在 Visual Studio 本地运行,连接到 Azure 中的搜索服务,后者又会连接到 Azure SQL 数据库并检索数据集。 由于此处会发生多项操作,因此可能会造成多个故障点。 如果遇到错误,请先检查以下条件:

  • 你提供的搜索服务连接信息是完整的 URL。 如果您只输入服务名称,操作将在创建索引时停止,并出现连接失败错误。

  • appsettings.json 中的数据库连接信息。 它应该是从 Azure 门户获得的 ADO.NET 连接字符串,经修改后包括了适用于数据库的用户名和密码。 用户帐户必须有权检索数据。 你的本地客户端 IP 地址必须能够通过防火墙进行入站访问。

  • 资源限制。 回想一下,免费层仅限三个索引、索引器和数据源。 达到最大限制的服务不能创建新的对象。

使用 Azure 门户验证对象创建,然后使用 搜索资源管理器 查询索引。

  1. 登录到 Azure 门户 并转到搜索服务。 在左窗格中,打开每个页面以验证对象是否已创建。 索引索引器和数据源应分别具有 hotels-sql-idxhotels-sql-indexerhotels-sql-ds

  2. 在“ 索引 ”选项卡上,选择 hotels-sql-idx 索引。 在“酒店”页面上,“搜索浏览器”是第一个选项卡。

  3. 要发出空查询,请选择“搜索”。

    索引中的三个条目以 JSON 文档的形式返回。 搜索浏览器返回 JSON 格式的文档,方便你查看整个结构。

    目标索引的搜索浏览器查询的屏幕截图。

  4. 切换到 JSON 视图 ,以便输入查询参数。

    {
         "search": "river",
         "count": true
    }
    

    此查询调用字词 river的全文搜索。 结果包括匹配文档的计数。 返回匹配文档的计数在测试方案中非常有帮助,尤其是在拥有数千或数百万个文档的大型索引的情况下。 在本示例中,只有一个文档与查询匹配。

  5. 输入将搜索结果限制为感兴趣的字段的参数。

    {
         "search": "river",
         "select": "hotelId, hotelName, baseRate, description",
         "count": true
    }
    

    查询响应范围缩小为选定字段,使输出更简洁。

重置并重新运行

在开发的前期试验阶段,设计迭代的最实用方法是,删除 Azure AI 搜索中的对象,并允许代码重新生成它们。 资源名称是唯一的。 删除某个对象后,可以使用相同的名称重新创建它。

本教程的示例代码将检查现有对象并将其删除,使你能够重新运行代码。

也可以使用 Azure 门户来删除索引、索引器和数据源。

清理资源

在自己的订阅中操作时,最好在项目结束时移除不再需要的资源。 持续运行资源可能会产生费用。 可以逐个删除资源,也可以删除资源组以删除整个资源集。

你可以在 Azure 门户中查找和管理资源,只需使用左侧导航窗格中的“所有资源”或“资源组”链接即可。

后续步骤

熟悉 SQL 数据库索引的基础知识后,请仔细了解索引器配置: