教程:使用 .NET SDK 为 Azure SQL 数据编制索引
教程:使用 .NET SDK 为 Azure SQL 数据编制索引
本教程将指导你使用C#和Azure SDK为Azure SQL数据库创建索引器,以便将数据加载到Azure AI搜索服务中。通过本教程,你将学习如何创建数据源、索引器,并运行索引器以将数据加载到索引中。
先决条件
- 使用SQL Server身份验证的Azure SQL数据库
- Visual Studio
- Azure订阅(如果没有,请先创建一个试用版订阅)
注意:本教程可以在免费搜索服务中完成。免费层限制为三个索引、三个索引器和三个数据源。本教程每样创建一个。在开始之前,请确保服务中有足够的空间可接受新资源。
下载文件
本教程的源代码位于Azure-Samples/search-dotnet-getting-started GitHub存储库中的DotNetHowToIndexer文件夹内。
1 - 创建服务
本教程使用Azure AI搜索进行索引编制和查询,使用Azure SQL数据库作为外部数据源。如果可能,请在同一区域和资源组中创建这两个服务,使它们相互靠近并易于管理。在实践中,Azure SQL数据库可以位于任意区域中。
从Azure SQL数据库开始
本教程在示例下载中提供了hotels.sql文件来填充数据库。Azure AI搜索使用平展行集,例如从视图或查询生成的行集。示例解决方案中的SQL文件创建并填充单个表。
如果你有现有的Azure SQL数据库资源,可在其中添加hotels表,从“打开查询”步骤开始。
创建Azure SQL数据库
使用快速入门:创建单一数据库中的说明创建Azure SQL数据库。数据库的服务器配置很重要:
- 选择提示你指定用户名和密码的SQL Server身份验证选项。索引器使用的ADO.NET连接字符串需要用到它。
- 选择一个公共连接。它会使本教程更易于完成。不建议将公共连接用于生产,建议在本教程结束时删除此资源。
配置防火墙规则
在Azure门户中,转到新资源。使用快速入门:在Azure门户中创建服务器级防火墙规则中的说明添加防火墙规则以允许从你的客户端访问。可以从命令提示符运行ipconfig
以获取你的IP地址。
加载示例数据
使用查询编辑器加载示例数据。在导航窗格中,选择“查询编辑器(预览版)”并输入服务器管理员的用户名和密码。如果收到访问被拒错误,请从错误消息复制客户端IP地址,打开服务器的网络安全页,然后添加允许从你的客户端访问的入站规则。
在查询编辑器中选择“打开查询”,然后在本地计算机上导航到hotels.sql文件所在的位置。选择该文件,然后选择“打开”。此脚本应与以下屏幕截图类似:
选择“运行”以执行查询。在“结果”窗格中,应会看到一条三行内容的消息,指示查询成功。
若要从此表返回一个行集,可执行以下充当验证步骤的查询:
SELECT * FROM Hotels
复制数据库的ADO.NET连接字符串。在“设置”>“连接字符串”下,复制类似于以下示例的ADO.NET连接字符串:
Server=tcp:<YOUR-DATABASE-NAME>.database.chinacloudapi.cn,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 AI搜索
下一个组件是可以在Azure门户中创建的Azure AI搜索。可以使用免费层完成本演练。
获取Azure AI搜索的管理API密钥和URL
API调用需要服务URL和访问密钥。搜索服务是使用这二者创建的,因此,如果向订阅添加了Azure AI搜索,则请按以下步骤获取必需信息:
- 登录到Azure门户,在搜索服务的“概览”页中获取URL。示例终结点可能类似于
https://mydemo.search.azure.cn
。 - 在“设置”>“密钥”中,获取有关该服务的完全权限的管理员密钥。有两个可交换的管理员密钥,为保证业务连续性而提供,以防需要滚动一个密钥。可以在请求中使用主要或辅助密钥来添加、修改和删除对象。
2 - 设置环境
- 启动Visual Studio并打开DotNetHowToIndexers.sln。
- 在解决方案资源管理器中,打开“appsettings.json”以提供连接信息。
- 对于
SearchServiceEndPoint
,如果服务概述页面上的完整URL为“https://my-demo-service.search.azure.cn"”,则要提供的值为整个URL。 - 对于
AzureSqlConnectionString
,字符串格式如下所示:
{
"SearchServiceEndPoint": "<placeholder-search-full-url>",
"SearchServiceAdminApiKey": "<placeholder-admin-key-for-search-service>",
"AzureSqlConnectionString": "<placeholder-ADO.NET-connection-string",
}
将SQL连接字符串中的用户密码替换为有效的密码。数据库名称和用户名可以复制,但密码必须手动输入。
3 - 创建管道
索引器需要数据源对象和索引。相关代码在两个文件中:
- 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);
}
4 - 生成解决方案
按F5生成并运行解决方案。程序在调试模式下执行。控制台窗口报告每项操作的状态。
代码将在Visual Studio本地运行,连接到Azure中的搜索服务,后者又会连接到Azure SQL数据库并检索数据集。由于此处会发生多项操作,因此可能会造成多个故障点。如果遇到错误,请先检查以下条件:
- 你提供的搜索服务连接信息是完整的URL。如果只输入了服务名,则操作会停在索引创建阶段,出现“无法连接”错误。
- appsettings.json中的数据库连接信息。它应该是从Azure门户获得的ADO.NET连接字符串,经修改后包括了适用于数据库的用户名和密码。用户帐户必须有权检索数据。你的本地客户端IP地址必须能够通过防火墙进行入站访问。
- 资源限制。回想一下,免费层仅限三个索引、索引器和数据源。达到最大限制的服务不能创建新的对象。
5 - 搜索
使用Azure门户验证对象的创建,然后使用“搜索资源管理器”查询索引。
- 登录到Azure门户,在你的搜索服务左导航窗格中,轮流打开每个页面,以验证对象是否已创建。索引、索引器和数据源将分别具有“hotels-sql-idx”、“hotels-sql-indexer”和“hotels-sql-ds”。
- 在“索引”选项卡上,选择hotels-sql-idx索引。在hotels页上,“搜索资源管理器”是第一个选项卡。
- 选择“搜索”,发出空查询。索引中的三个条目以JSON文档的形式返回。搜索浏览器返回JSON格式的文档,方便你查看整个结构。
- 接下来,切换到JSON视图,以便输入查询参数:
{
"search": "river",
"count": true
}
此查询调用river
一词的全文搜索,结果包含匹配文档的计数。在索引很大且文档成千上万甚至数百万的测试方案中,返回匹配文档的计数很有用。在本示例中,只有一个文档与查询匹配。
- 最后,输入将搜索结果限定为感兴趣的字段的参数:
{
"search": "river",
"select": "hotelId, hotelName, baseRate, description",
"count": true
}
查询响应范围缩小为选定字段,使输出更简洁。
重置并重新运行
在开发的前期试验阶段,设计迭代的最实用方法是,删除Azure AI搜索中的对象,并允许代码重新生成它们。资源名称是唯一的。删除某个对象后,可以使用相同的名称重新创建它。
本教程的示例代码将检查现有对象并将其删除,使你能够重新运行代码。也可以使用Azure门户来删除索引、索引器和数据源。
清理资源
在自己的订阅中操作时,最好在项目结束时删除不再需要的资源。持续运行资源可能会产生费用。可以逐个删除资源,也可以删除资源组以删除整个资源集。
你可以在Azure门户中查找和管理资源,只需使用左侧导航窗格中的“所有资源”或“资源组”链接即可。
后续步骤
熟悉SQL数据库索引编制的基础知识后,接下来让我们更详细地了解索引器配置。配置SQL数据库索引器