在 Azure AI 搜索中创建索引
本文介绍定义搜索索引架构并将其推送至搜索服务的步骤。 创建索引会在搜索服务上建立物理数据结构。 一旦索引存在,将在单独的任务中加载索引。
先决条件
以搜索服务参与者或管理员 API 密钥的身份写入权限,以进行基于密钥的身份验证。
了解要编制索引的数据。 搜索索引基于要使其可搜索的外部内容。 可搜索内容以字段形式存储在索引中。 应该清楚了解要使哪些源字段在 Azure AI 搜索上可搜索、可检索、可筛选、可查找和可排序。 有关指南,请参阅架构清单。
还必须在源数据中具有唯一字段,该字段可用作索引中的文档键(或 ID)。
稳定的索引位置。 目前不支持将现有索引移到其他搜索服务。 回顾应用程序要求,并确保现有的搜索服务(容量和区域)足以满足你的需求。 如果依赖于 Azure AI 服务或 Azure OpenAI,选择提供所有必要资源的区域。
最后,所有服务层对可创建的对象数量都有索引限制。 例如,如果要试用免费层,则你在任何时候都只能有三个索引。 在索引本身,有矢量限制,对简单和复杂字段的数量也有索引限制。
文档键
搜索索引创建有两个要求:索引在搜索服务上必须具有唯一名称,并且必须具有文档键。 字段上的布尔 key
属性可以设置为 true,以指示哪个字段提供文档键。
文档键是搜索文档的唯一标识符,搜索文档是完整描述某项内容的字段集合。 例如,如果要为电影数据集建立索引,则搜索文档需要包含单个电影的标题、类型和持续时间。 影片名称在此数据集中是唯一的,因此可以使用电影名称作为文档键。
在 Azure AI 搜索中,文档键是字符串,并且必须源自提供要索引的内容的数据源中的唯一值。 作为一般规则,搜索服务不会生成键值,但在某些情况下(例如 Azure 表索引器),它会合成现有值,为要编制索引的文档创建唯一键。 另一种方案是分块或分区数据的一对多索引,在这种情况下,会为每个区块生成文档键。
在增量索引编制中(会对新的和更新的内容编制索引),将添加包含新键的传入文档,同时合并或覆盖包含现有键的传入文档,具体取决于索引字段是 Null 还是已填充。
有关文档键的要点包括:
- 键字段中值的最大长度为 1,024 个字符。
- 每个索引中的一个顶级字段必须选择为键字段,并且必须为
Edm.String
类型。 - 对于简单字段,
key
属性的默认值为 false,复杂字段的默认值为 null。
键字段可用于直接查找文档并更新或删除特定文档。 查找或索引文档时,键字段的值以区分大小写的方式进行处理。 有关详细信息,请参阅 GET 文档 (REST) 和 索引文档 (REST)。
架构清单
使用此清单来帮助针对搜索索引做出设计决策。
查看命名约定,以便索引和字段名称符合命名规则。
查看受支持的数据类型。 数据类型会影响字段的使用方式。 例如,数值内容是可筛选的,但不是全文可搜索的。 最常见的数据类型是用于可搜索文本的
Edm.String
,它使用全文搜索引擎进行标记和查询。 矢量字段最常见的数据类型是Edm.Single
,但你也可以使用其他类型。标识文档键。 文档键是索引要求。 它是单个字符串字段,从包含唯一值的源数据字段填充。 例如,如果从 Blob 存储进行索引,则元数据存储路径通常用作文档键,因为它唯一标识容器中的每个 blob。
标识数据源中参与索引中可搜索内容的字段。
可搜索的非矢量内容包括使用全文搜索引擎查询的短字符串或长字符串。 如果内容十分冗长(少量短语或长段内容),请试用不同的分析器来查看文本是如何被标记的。
可搜索的矢量内容可以是以数学表示形式存在的图像或文本(任何语言)。 可以使用窄数据类型或矢量压缩来缩小矢量字段。
在
retrievable
或filterable
字段上设置的属性决定搜索行为和索引在搜索服务上的物理表示形式。 对于许多开发人员来说,确定应如何属性化字段是一个迭代过程。 若要加快迭代速度,请从示例数据开始,这样就可以轻松删除和重新生成索引。确定哪些源字段可用作筛选器。 数值内容和短文本字段(尤其是那些具有重复值的字段)是不错的选择。 使用筛选器时,请记住:
筛选器可用于矢量和非矢量查询,但筛选器本身应用于索引中的字母数字(非矢量)字段。
可以选择在分面导航中使用可筛选字段。
可筛选字段以任意顺序返回,并且不进行相关性评分,因此请考虑也对其进行排序。
对于矢量字段,请指定矢量搜索配置以及用于创建导航路径和填充嵌入空间的算法。 有关更多信息,请参阅添加矢量字段。
矢量字段具有非矢量字段所没有的额外属性,例如要使用哪些算法和矢量压缩。
矢量字段会忽略对矢量数据无用的属性,例如排序、筛选和查找。
对于非矢量字段,确定是使用默认分析器 (
"analyzer": null
) 还是其他分析器。 分析器用于在索引和执行查询期间标记文本字段。对于多语言字符串,请考虑语言分析器。
对于带连字符的字符串或特殊字符,请考虑专用分析器。 例如,将整个字段内容视为单个令牌的关键字。 此行为可用于邮政编码、ID 和某些产品名称等数据。 有关详细信息,请参阅部分字词搜索和包含特殊字符的模式。
注意
全文搜索是通过索引期间标记的字词进行的。 如果查询未能返回预期的结果,请测试词汇切分以验证搜索的字符串是否确实存在。 可以对字符串尝试不同的分析器,以了解如何为各种分析器生成令牌。
配置字段定义
字段集合定义搜索文档的结构。 所有字段都具有名称、数据类型和属性。
将字段设置为可搜索、可筛选、可排序或可分面对索引大小和查询性能具有影响。 不要在查询表达式中不打算引用的字段上设置这些属性。
如果字段未设置为可搜索、可筛选、可排序或可分面,则不能在任何查询表达式中引用该字段。 这适用于不在查询中使用但在搜索结果中需要的字段。
REST API 具有基于数据类型的默认归因,导入向导也在 Azure 门户中使用。 Azure SDK 没有默认值,但它们具有包含属性和行为的字段子类,例如用于字符串的 SearchableField,用于基元的 SimpleField。
下表汇总了 REST API 的默认字段属性。
Data type | 可搜索 | 可检索 | 可筛选 | 可分面 | 可排序 | 存储函数 |
---|---|---|---|---|---|---|
Edm.String |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Collection(Edm.String) |
✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
Edm.Boolean |
❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
Edm.Int32 ,Edm.Int64 ,Edm.Double |
❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
Edm.DateTimeOffset |
❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
Edm.GeographyPoint |
✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
Edm.ComplexType |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Collection(Edm.Single) 和其他所有向量字段类型 |
✅ | ✅ 或 ❌ | ❌ | ❌ | ❌ | ✅ |
还可以选择与分析器和同义词映射关联字符串字段。 Edm.String
类型的可筛选、可排序或可查找字段的长度最多可以是 32 千字节。 这是因为,此类字段的值将被视为单个搜索词,而在 Azure AI 搜索中,一个字词的最大长度为 32 KB。 如果需要在单个字符串字段中存储多于此大小的文本,则应在索引定义中将可筛选、可排序和分面显式设置为 false
。
矢量字段必须与维度和矢量配置文件相关联。 如果使用导入和矢量化向导在门户中添加矢量字段,则可检索默认值为 true,否则如果使用 REST API,则为 false。
下表描述了字段属性。
属性 | 描述 |
---|---|
name | 必需。 设置字段的名称,该名称在索引或父字段的字段集合中必须唯一。 |
type | 必需。 设置字段的数据类型。 字段可以是简单的,也可以是复杂的。 简单字段是基元类型,例如文本 Edm.String 或整数 Edm.Int32 。 复杂字段可以具有简单或复杂的子字段。 这样,便可以对对象和对象的数组进行建模,这样就可以将大多数 JSON 对象结构上传到索引。 有关受支持类型的列表,请参阅受支持的数据类型。 |
key | 必需。 将此属性设置为 true,以指定字段的值唯一标识索引中的文档。 有关详细信息,请参阅本文中的文档密钥。 |
可检索 | 指示是否可以在搜索结果中返回此字段。 当希望将某个字段用作筛选器、排序或评分机制,但不希望该字段显示给最终用户时,请将此属性设置为 false 。 对于键字段,此属性必须为 true ,对于复杂字段,此属性必须为 null 。 可以在现有字段上更改此属性。 将可检索设置为 true 不会导致索引存储要求增加。 对于简单字段,默认值为 true ,对于复杂字段,默认值为 null 。 |
searchable | 指示字段是否可全文搜索,并且可以在搜索查询中引用。 这意味着它会在索引期间受到分词之类的词法分析。 如果将某个可搜索字段设置为“Sunny day”之类的值,在内部它将规范化为单独的标记“sunny”和“day”。 这实现了对这些词的全文搜素。 Edm.String 或 Collection(Edm.String) 类型的字段默认可搜索。 对于其他非字符串数据类型的简单字段,此属性必须为 false ,对于复杂字段,此属性必须为 null 。 可搜索字段在索引中占用额外的空间,因为 Azure AI 搜索处理这些字段的内容,并在辅助数据结构中组织这些字段,以便执行搜索。 如果要节省索引中的空间,并且不需要在搜索中包含字段,请将可搜索设置为 false 。 有关详细信息,请参阅 Azure AI 搜索中全文搜索的工作原理。 |
filterable | 指示是否启用 $filter 查询中引用的字段。 在字符串的处理方式中,可筛选不同于可搜索。 Edm.String 或 Collection(Edm.String) 类型的可筛选字段,不进行词法分析,因此,比较仅用于查找完全匹配项。 例如,如果将此类字段 f 设置为“Sunny day”,则 $filter=f eq 'sunny' 找不到任何匹配项,但 $filter=f eq 'Sunny day' 可找到。 对于复杂字段,此属性必须为 null 。 对于简单字段,默认值为 true ,对于复杂字段,默认值为 null 。 若要减小索引大小,在不会筛选的字段上,请将此属性设置为 false 。 |
sortable | 指示是否启用 $orderby 表达式中引用的字段。 默认情况下,Azure AI 搜索按计分为结果排序,但在许多情况下,用户希望按文档中的字段排序。 仅当简单字段是单值字段(父文档的作用域中具有单个值)时,才能进行排序。 简单集合字段无法进行排序,因为它们是多值。 复杂集合的简单子字段也是多值,因此无法排序。 无论是直接父字段还是上级字段,都是如此,这就是复杂的集合。 复杂字段不能可排序,并且对于这类字段,可排序属性必须为 null 。 对于单值简单字段,可排序的默认值为 true ,对于多值简单字段,可排序的默认值为 false ,对于复杂字段,可排序的默认值为 null 。 |
facetable | 指示是否启用分面查询中引用的字段。 通常在按类别包含命中次数的搜索结果展示中使用(例如,搜索数码相机并按品牌、像素、价格等查看命中)。 对于复杂字段,此属性必须为 null 。 无法分面 Edm.GeographyPoint 或 Collection(Edm.GeographyPoint) 类型的字段。 对于所有其他简单字段,默认值为 true 。 若要减小索引大小,在不会分面的字段上,请将此属性设置为 false 。 |
分析器 | 设置用于在索引和查询操作期间标记字符串的词法分析器。 此属性的有效值包括语言分析器、内置分析器,以及自定义分析器。 默认为 standard.lucene 。 此属性只能用于可搜索字符串字段,并且无法与 searchAnalyzer 或 indexAnalyzer 一起设置。 选择分析器并在索引中创建字段后,无法更改该字段。 对于复杂字段,必须为 null 。 |
searchAnalyzer | 将此属性与 indexAnalyzer 一起设置,为索引和查询指定不同的词法分析器。 如果使用此属性,请将分析器设置为 null ,并确保 indexAnalyzer 设置为允许的值。 此属性的有效值包括内置分析器,以及自定义分析器。 此属性只能与可搜索字段一起使用。 可以在现有字段上更新搜索分析器,因为它仅在查询时使用。 对于复杂字段,必须为 null 。 |
indexAnalyzer | 将此属性与 searchAnalyzer 一起设置,为索引和查询指定不同的词法分析器。 如果使用此属性,请将分析器设置为 null ,并确保 searchAnalyzer 设置为允许的值。 此属性的有效值包括内置分析器,以及自定义分析器。 此属性只能与可搜索字段一起使用。 选择索引分析器后,无法为字段更改它。 对于复杂字段,必须为 null 。 |
synonymMaps | 要与此字段关联的同义词映射的名称列表。 此属性只能与可搜索字段一起使用。 目前每个字段仅支持一个同义词映射。 将同义词映射分配给字段可确保使用同义词映射中的规则在查询时扩展针对该字段的查询词。 可以在现有字段上更改此属性。 对于复杂字段,必须为 null 或空集合。 |
字段 | 如果这是 Edm.ComplexType 或 Collection(Edm.ComplexType) 类型的字段,则为子字段的列表。 对于简单字段,必须为 null 或为空。 请参阅如何在 Azure AI 搜索中为复杂数据类型建模,了解有关如何、何时使用子字段的详细信息。 |
创建索引
准备好创建索引时,请使用可发送请求的搜索客户端。 可以使用 Azure 门户或 REST API 进行早期开发和概念验证测试,否则通常使用 Azure SDK。
在开发过程中,规划频繁的重新生成。 由于物理结构是在服务中创建的,因此许多修改都需要删除和重新创建索引。 可以考虑使用一部分数据来加快重新生成的速度。
通过门户设计的索引可强制实施针对特定数据类型的要求和架构规则,例如,对数值字段禁用全文搜索功能。
登录到 Azure 门户。
检查空间。 搜索服务受最大索引数量(因服务层而异)的限制。 确保你有第二个索引的空间。
在搜索服务概述页面中,选择以下任一选项来创建搜索索引:
- “添加索引”是一种嵌入式编辑器,用于指定索引架构
- 导入向导
该向导是一个端到端工作流,用于创建索引器、数据源和已完成的索引。 它还会加载数据。 如果它对你来说大材小用,请改用“添加索引”。
以下屏幕截图突出显示了“添加索引”、“导入数据”和“导入和矢量化数据”在命令栏上的具体位置。
创建索引后,可以在左侧导航窗格中“索引”页上再次找到该索引。
提示
在门户中创建索引后,可以复制 JSON 表示形式并将其添加到应用程序代码中。
为跨源查询设置 corsOptions
索引架构包含用于设置 corsOptions
的部分。 默认情况下,客户端 JavaScript 无法调用任何 API,因为浏览器将阻止所有跨域请求。 若要允许对索引进行跨域查询,请通过设置 corsOptions 来启用 CORS(跨域资源共享)。 出于安全原因,只有查询 API 才支持 CORS。
"corsOptions": {
"allowedOrigins": [
"*"
],
"maxAgeInSeconds": 300
可为 CORS 设置以下属性:
allowedOrigins(必需):这是允许访问索引的源列表。 允许从这些源提供的 JavaScript 代码查询索引(假设调用方提供有效的密钥或具有权限)。 每个来源通常采用
protocol://<fully-qualified-domain-name>:<port>
格式,不过往往会省略<port>
。若要允许访问所有来源,请将
*
作为单个项目包含在 allowedOrigins 数组中。 不建议对生产搜索服务采用这种做法,但它在开发和调试中却很有用。maxAgeInSeconds(可选):浏览器使用此值确定缓存 CORS 预检响应的持续时间(以秒为单位)。 此值必须是非负整数。 较长的缓存周期可提供更好的性能,但它延长了 CORS 策略生效所需的时间。 如果未设置此值,则使用默认持续时间为 5 分钟。
允许更新现有索引
创建索引会在搜索服务上创建物理数据结构(文件和倒排索引)。 创建索引后,能否使用创建或更新索引进行更改取决于修改是否会使这些物理结构无效。 在索引中创建了字段后,大多数字段属性就无法更改。
若要最大程度地减少应用程序代码中的改动,可以创建一个索引别名,用作搜索索引的稳定引用。 可以更新索引别名以指向较新的索引版本,而不是使用索引名称更新代码。
为了最大限度地减少设计过程中的流失,下表描述了架构中哪些元素是固定的以及哪些元素是灵活的。 更改固定元素需要重新生成索引,而灵活元素可以在不影响物理实现的情况下随时更改。 有关详细信息,请参阅更新或重新生成索引。
元素 | 是否可以进行更新? |
---|---|
名称 | 否 |
密钥 | 否 |
字段名称和类型 | 否 |
字段属性(可搜索、可筛选、可查找、可排序) | 否 |
字段属性(可检索) | 是 |
已存储(适用于矢量) | 否 |
Analyzer | 可以在索引中添加和修改自定义分析器。 对于字符串字段的分析器分配,只能修改 searchAnalyzer 。 所有其他分配和修改都需要重新生成。 |
为配置文件评分 | 是 |
建议器 | 否 |
跨域资源共享 (CORS) | 是 |
加密 | 是 |
同义词映射 | 是 |
后续步骤
使用以下链接了解可添加到索引的专用功能:
使用这些链接加载或更新索引: