你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
在 Azure AI 搜索中为 Markdown Blob 和文件编制索引
注意
此功能目前处于公开预览状态。 此预览版没有附带服务级别协议,建议不要用于生产工作负载。 某些功能可能不受支持或者受限。 有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款。
在 Azure AI 搜索中,适用于 Azure Blob 存储、Azure 文件存储和 OneLake 的索引器均支持 Markdown 文件的 markdown
分析模式。 Markdown 文件可以通过两种方式编制索引:
- 一对多分析模式,每个 Markdown 文件创建多个搜索文档
- 一对一分析模式,每个 Markdown 文件创建一个搜索文档
先决条件
支持的数据源包括:Azure Blob 存储、Azure 文件存储以及 Microsoft Fabric 中的 OneLake。
对于 OneLake,请确保满足 OneLake 索引器的所有要求。
用于 Blob 索引器和文件索引器的 Azure 存储是一种标准性能(常规用途 v2)实例,支持热访问层、冷访问层和寒访问层。
Markdown 分析模式参数
在创建或更新索引器时,可以在索引器定义中指定分析模式参数。
POST https://[service name].search.windows.net/indexers?api-version=2024-11-01-preview
Content-Type: application/json
api-key: [admin key]
{
"name": "my-markdown-indexer",
"dataSourceName": "my-blob-datasource",
"targetIndexName": "my-target-index",
"parameters": {
"configuration": {
"parsingMode": "markdown",
"markdownParsingSubmode": "oneToMany",
"markdownHeaderDepth": "h6"
}
},
}
Blob 索引器提供了一个 submode
参数,用于确定搜索文档的结构输出。 Markdown 分析模式提供以下子模式选项:
parsingMode | 子模式 | 搜索文档 | 说明 |
---|---|---|---|
markdown |
oneToMany |
每个 Blob 有多个 | (默认)将 Markdown 拆分成多个搜索文档,每个文档表示 Markdown 文件中的一个内容(非标题)节。 除非你想要进行一对一分析,否则可以省略子模式。 |
markdown |
oneToOne |
每个 Blob 各有一个 | 将 Markdown 分析为一个搜索文档,其中的各节映射到 Markdown 文件中的特定标题。 |
对于 oneToMany
子模式,应查阅为一个 Blob 编制索引以生成多个搜索文档,了解对于从同一 Blob 生成的多个搜索文档,Blob 索引器如何消除文档键的歧义。
后面的各个部分更详细地介绍了每个子模式。 如果你不熟悉索引器客户端和概念,请参阅创建搜索索引器。 还应熟悉基本 blob 索引器配置的详细信息,这在此不予重复。
可选的 Markdown 分析参数
参数区分大小写。
参数名称 | 允许的值 | 说明 |
---|---|---|
markdownHeaderDepth |
h1 、h2 、h3 、h4 、h5 、h6(default) |
此参数决定了分析时考虑的最深层级标题,以灵活处理文档结构(例如,当 markdownHeaderDepth 设置为 h1 时,分析程序仅识别以“#”开头的顶级标题,所有较低级别的标题都被视为纯文本)。 如果未指定,则默认为 h6 。 |
此设置可以在初始创建索引器后进行更改,但根据 Markdown 内容的不同,生成的搜索文档结构可能会发生变化。
支持的 Markdown 元素
Markdown 分析仅根据标题拆分内容。 所有其他元素(如列表、代码块、表等)都被视为纯文本,并传入内容字段。
Markdown 内容示例
以下是本页面示例中使用的 Markdown 内容:
# Section 1
Content for section 1.
## Subsection 1.1
Content for subsection 1.1.
# Section 2
Content for section 2.
使用一对多分析模式
一对多分析模式将 Markdown 文件分析为多个搜索文档,每个文档对应 Markdown 文件中的特定内容节,具体根据文档中该点的标题元数据进行映射。 Markdown 根据标题分析为包含以下内容的搜索文档:
content
:一个字符串,其中包含基于文档中该点处的标题元数据在特定位置找到的原始 Markdown。sections
:一个对象,其中包含标题元数据的子字段,最高为所需的标题级别。 例如,当markdownHeaderDepth
设置为h3
时,包含字符串字段h1
、h2
和h3
。 这些字段通过镜像索引中的此结构或通过格式为/sections/h1
、sections/h2
等的字段映射编制索引。有关上下文中的示例,请参阅以下示例中的索引和索引器配置。 包含的子字段有:h1
- 一个包含 h1 标题值的字符串。 如果在文档中此点处未设置,则为空字符串。- (可选)
h2
- 一个包含 h2 标题值的字符串。 如果在文档中此点处未设置,则为空字符串。 - (可选)
h3
- 一个包含 h3 标题值的字符串。 如果在文档中此点处未设置,则为空字符串。 - (可选)
h4
- 一个包含 h4 标题值的字符串。 如果在文档中此点处未设置,则为空字符串。 - (可选)
h5
- 一个包含 h5 标题值的字符串。 如果在文档中此点处未设置,则为空字符串。 - (可选)
h6
- 一个包含 h6 标题值的字符串。 如果在文档中此点处未设置,则为空字符串。
ordinal_position
:一个整数值,指示该节在文档层次结构中的位置。 此字段用于按原始顺序对文档中的各节进行排序,从序号位置 1 开始,每个标题的序号依次递增。
用于一对多分析的索引架构
示例索引配置可能如下所示:
{
"name": "my-markdown-index",
"fields": [
{
"name": "id",
"type": "Edm.String",
"key": true
},
{
"name": "content",
"type": "Edm.String",
},
{
"name": "ordinal_position",
"type": "Edm.Int32"
},
{
"name": "sections",
"type": "Edm.ComplexType",
"fields": [
{
"name": "h1",
"type": "Edm.String"
},
{
"name": "h2",
"type": "Edm.String"
}]
}]
}
用于一对多分析的索引器定义
如果字段名称和数据类型一致,Blob 索引器可以在请求中没有显式字段映射的情况下推断映射,因此,与提供的索引配置对应的索引器配置可能如下所示:
POST https://[service name].search.windows.net/indexers?api-version=2024-11-01-preview
Content-Type: application/json
api-key: [admin key]
{
"name": "my-markdown-indexer",
"dataSourceName": "my-blob-datasource",
"targetIndexName": "my-target-index",
"parameters": {
"configuration": { "parsingMode": "markdown" }
},
}
注意
此处不需要显式设置 submode
,因为 oneToMany
是默认值。
用于一对多分析的索引器输出
由于有三个内容节,此 Markdown 文件在编制索引后将生成三个搜索文档。 从提供的 Markdown 文档的第一个内容节生成的搜索文档将包含以下 content
、sections
、h1
和 h2
的值:
{
{
"content": "Content for section 1.\r\n",
"sections": {
"h1": "Section 1",
"h2": ""
},
"ordinal_position": 1
},
{
"content": "Content for subsection 1.1.\r\n",
"sections": {
"h1": "Section 1",
"h2": "Subsection 1.1"
},
"ordinal_position": 2
},
{
"content": "Content for section 2.\r\n",
"sections": {
"h1": "Section 2",
"h2": ""
},
"ordinal_position": 3
}
}
在搜索索引中映射一对多字段
如果字段名称和类型不相同,则字段映射将源字段与目标字段相关联。 不过,字段映射还可用于匹配 Markdown 文档的各个部分,并将这些部分“提升”到搜索文档的顶级字段。
以下示例对此方案进行了说明。 有关一般字段映射的详细信息,请参阅“字段映射”。
假设某个搜索索引包含以下字段:Edm.String
类型的 raw_content
、Edm.String
类型的 h1_header
,以及 Edm.String
类型的 h2_header
。 要将 Markdown 映射到所需的形状,请使用以下字段映射:
"fieldMappings" : [
{ "sourceFieldName" : "/content", "targetFieldName" : "raw_content" },
{ "sourceFieldName" : "/sections/h1", "targetFieldName" : "h1_header" },
{ "sourceFieldName" : "/sections/h2", "targetFieldName" : "h2_header" },
]
索引中生成的搜索文档将如下所示:
{
{
"raw_content": "Content for section 1.\r\n",
"h1_header": "Section 1",
"h2_header": "",
},
{
"raw_content": "Content for section 1.1.\r\n",
"h1_header": "Section 1",
"h2_header": "Subsection 1.1",
},
{
"raw_content": "Content for section 2.\r\n",
"h1_header": "Section 2",
"h2_header": "",
}
}
使用一对一分析模式
在一对一分析模式中,整个 Markdown 文档作为单个搜索文档编制索引,保留原始内容的层次结构和结构。 当要编制索引的文件共享相同的结构时,此模式最有用,可以利用这种通用结构在索引中使相关字段可搜索。
在索引器定义中,将 parsingMode
设置为 "markdown"
,并使用可选的 markdownHeaderDepth
参数定义用于分块的最大标题深度。 如果未指定,则默认为 h6
,捕获所有可能的标题深度。
Markdown 根据标题分析为包含以下内容的搜索文档:
document_content
:包含完整 Markdown 文本作为单个字符串。 此字段作为输入文档的原始表示形式。sections
:一个对象数组,其中包含 Markdown 文档中各节的分层表示形式。 每节表示为此数组中的一个对象,并以与标题及其相应内容对应的嵌套方式捕获文档的结构。 通过引用路径(例如/sections/content
),可以通过字段映射访问这些字段。 此数组中的对象具有以下属性:header_level
:一个字符串,指示 Markdown 语法中的标题级别(h1
、h2
、h3
等)。 此字段有助于理解内容的层次结构和组织方式。header_name
:一个字符串,其中包含在 Markdown 文档中显示的标题的文本。 此字段提供相应节的标签或标题。content
:一个字符串,其中包含紧跟标题之后的文本内容,直到下一个标题为止。 此字段捕获与标题关联的详细信息或描述。 如果标题下没有内容,则这是一个空字符串。ordinal_position
:一个整数值,指示该节在文档层次结构中的位置。 此字段用于按原始顺序对文档中的各节进行排序,从序号位置 1 开始,每个内容块的序号依次递增。sections
:一个数组,其中包含表示嵌套在当前节下的小节的对象。 此数组遵循与顶级sections
数组相同的结构,允许表示多级嵌套内容。 每个子节对象也包括header_level
、header_name
、content
和ordinal_position
属性,实现递归结构,展现 Markdown 内容的层级关系。
下面是用于解释围绕每个分析模式设计的索引架构的示例 Markdown。
# Section 1
Content for section 1.
## Subsection 1.1
Content for subsection 1.1.
# Section 2
Content for section 2.
用于一对一分析的索引架构
如果不利用字段映射,索引的形状应反映 Markdown 内容的形状。 鉴于示例 Markdown 的结构,其中包含两个节和单个小节,索引应类似于以下示例:
{
"name": "my-markdown-index",
"fields": [
{
"name": "document_content",
"type": "Edm.String",
{
"name": "sections",
"type": "Edm.ComplexType",
"fields": [
{
"name": "header_level",
"type": "Edm.String",
},
{
"name": "header_name",
"type": "Edm.String",
},
{
"name": "content",
"type": "Edm.String"
},
{
"name": "ordinal_position",
"type": "Edm.Int"
},
{
"name": "sections",
"type": "Edm.ComplexType",
"fields": [
{
"name": "header_level",
"type": "Edm.String",
},
{
"name": "header_name",
"type": "Edm.String",
},
{
"name": "content",
"type": "Edm.String"
},
{
"name": "ordinal_position",
"type": "Edm.Int"
}]
}]
}
}
用于一对一分析的索引器定义
POST https://[service name].search.windows.net/indexers?api-version=2024-11-01-preview
Content-Type: application/json
api-key: [admin key]
{
"name": "my-markdown-indexer",
"dataSourceName": "my-blob-datasource",
"targetIndexName": "my-target-index",
"parameters": {
"configuration": {
"parsingMode": "markdown",
"markdownParsingSubmode": "oneToOne",
}
}
}
用于一对一分析的索引器输出
由于要编制索引的 Markdown 只到达深度 h2
(“##”),因此需要将 sections
字段嵌套到深度 2 以与之匹配。 此配置将导致索引中的数据如下所示:
"document_content": "# Section 1\r\nContent for section 1.\r\n## Subsection 1.1\r\nContent for subsection 1.1.\r\n# Section 2\r\nContent for section 2.\r\n",
"sections": [
{
"header_level": "h1",
"header_name": "Section 1",
"content": "Content for section 1.",
"ordinal_position": 1,
"sections": [
{
"header_level": "h2",
"header_name": "Subsection 1.1",
"content": "Content for subsection 1.1.",
"ordinal_position": 2,
}]
}],
{
"header_level": "h1",
"header_name": "Section 2",
"content": "Content for section 2.",
"ordinal_position": 3,
"sections": []
}]
}
如你所见,序号位置根据内容在文档中的位置递增。
还应注意,如果内容中跳过了标题级别,则生成的文档结构反映的是 Markdown 内容中存在的标题,而不一定包含连续的 h6
至 h1
的嵌套节。 例如,当文档从 h2
开始时,顶级节数组中的第一个元素是 h2
。
在搜索索引中映射一对一字段
如果要从文档中提取具有自定义名称的字段,可以使用字段映射来实现。 以之前的 Markdown 示例为例,考虑以下索引配置:
{
"name": "my-markdown-index",
"fields": [
{
"name": "document_content",
"type": "Edm.String",
},
{
"name": "document_title",
"type": "Edm.String",
},
{
"name": "opening_subsection_title"
"type": "Edm.String",
}
{
"name": "summary_content",
"type": "Edm.String",
}
]
}
从经过分析的 Markdown 中提取特定字段的过程与文档路径在 outputFieldMappings 中的处理方式类似,区别在于路径以 /sections
开始,而不是 /document
。 例如,/sections/0/content
将映射到节数组中位置为 0 的项下的内容。
一个强有力的用例示例可能是:所有 Markdown 文件在第一个 h1
中都有文档标题、在第一个 h2
中有小节标题,最终段落中的总结内容位于最后一个 h1
下。 可以使用以下字段映射来仅为该内容编制索引:
"fieldMappings" : [
{ "sourceFieldName" : "/content", "targetFieldName" : "raw_content" },
{ "sourceFieldName" : "/sections/0/header_name", "targetFieldName" : "document_title" },
{ "sourceFieldName" : "/sections/0/sections/header_name", "targetFieldName" : "opening_subsection_title" },
{ "sourceFieldName" : "/sections/1/content", "targetFieldName" : "summary_content" },
]
在这种情况下,只能从该文档中提取相关部分。 为了更有效地使用此功能,你计划编制索引的文档应共享相同的分层标题结构。
索引中生成的搜索文档将如下所示:
{
"content": "Content for section 1.\r\n",
"document_title": "Section 1",
"opening_subsection_title": "Subsection 1.1",
"summary_content": "Content for section 2."
}
注意
这些示例展示了完全使用或不使用字段映射的分析模式应用,但在适合你的需求的情况下,也可以在同一场景中同时使用两者。