Elasticsearch 的结构化文档配置 - 递归分块实践

今天我发表的一篇文章 "在 Elasticsearch 中为结构化文档配置递归分块" 看着很简单。可能很多开发者还是不能得其要领,特别是在最新的版本中,我们的向量在默认的情况下是不在 source 里进行展示的。很难理解其中精髓。我在这篇文章里,使用一个具体的例子来进行展示。

例子

我们可以参考官方文档 "Inference integrations" 来进行展示。首先,我们选择系统自带的 ELSER 模型来进行展示。我们必须安装好 ELSER 模型:

首先我们定义如下的一个 inference endpoint:

bash 复制代码
`

1.  PUT _inference/sparse_embedding/recursive_markdown_chunks
2.  {
3.    "service": "elasticsearch",
4.    "service_settings": {
5.      "model_id": ".elser_model_2",
6.      "num_allocations": 1,
7.      "num_threads": 1
8.    },
9.    "chunking_settings": {
10.      "strategy": "recursive",
11.      "max_chunk_size": 25,
12.      "separators": [
13.        "\n# ",
14.        "\n## "
15.      ]
16.    }
17.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

我们可以参考文档来了解 recursive 是如何工作的。递归策略根据可配置的分隔符模式列表(例如换行符或 Markdown 标题)拆分输入文本。分块器按顺序应用这些分隔符,递归地拆分超过 max_chunk_size 单词限制的任何分块。如果没有分隔符生成足够小的分块,该策略将退回到句子级拆分。

在上面,我们使用了 custom separator group:也就是基于第一第二级的 heading 来进行分隔提前。

接下来,我们定义一个索引:

bash 复制代码
`

1.  PUT recursive_markdown_vectors
2.  {
3.    "mappings": {
4.      "properties": {
5.        "content": {
6.          "type": "text",
7.          "copy_to": "inference_field"
8.        },
9.        "inference_field": {
10.          "type": "semantic_text",
11.          "inference_id": "recursive_markdown_chunks"
12.        }
13.      }
14.    }
15.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

然后,我们写入文档:

less 复制代码
`

1.  POST recursive_markdown_vectors/_doc/1
2.  {
3.    "content": "# First Header
4.  This first test sentence has ten total words in it.

6.  ## Second header
7.  This second test sentence has ten total words in it.

9.  # Third Header
10.  This third test sendtence has ten total words in it.

12.  ## Fourth Header
13.  This Fourth test sendtence has ten total words in it.

16.  ## Fifth Header
17.  This fifth test sentence has ten total words in it. This sixth test sentence has ten total words in it. This seventh test sentence has ten total words in it."
18.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

这样我们就大功告成了。

我们可以使用如下的查询来进行展示:

bash 复制代码
`

1.  GET recursive_markdown_vectors/_search?filter_path=**.hits
2.  {
3.    "fields": [
4.      {
5.        "field": "inference_field",
6.        "format": "chunks"
7.      }
8.    ]
9.  }

`AI写代码

注意:上面的 fields 只对 9.2+ 及以上版本起作用。

我们可以看到如下的查询结果:

从上面的结果中,我们可以看到有 3 个 chunks。

我们接下来把 max_chunk_size 设置为 10,看看最后的结果:

bash 复制代码
`

1.  PUT _inference/sparse_embedding/recursive_markdown_chunks
2.  {
3.    "service": "elasticsearch",
4.    "service_settings": {
5.      "model_id": ".elser_model_2",
6.      "num_allocations": 1,
7.      "num_threads": 1
8.    },
9.    "chunking_settings": {
10.      "strategy": "recursive",
11.      "max_chunk_size": 10,
12.      "separators": [
13.        "\n# ",
14.        "\n## "
15.      ]
16.    }
17.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

很显然,它和我们之前的分块还是有点不一样。我们可以试试不同的值来看看。

bash 复制代码
`

1.  PUT _inference/sparse_embedding/recursive_markdown_chunks
2.  {
3.    "service": "elasticsearch",
4.    "service_settings": {
5.      "model_id": ".elser_model_2",
6.      "num_allocations": 1,
7.      "num_threads": 1
8.    },
9.    "chunking_settings": {
10.      "strategy": "recursive",
11.      "max_chunk_size": 35,
12.      "separators": [
13.        "\n# ",
14.        "\n## "
15.      ]
16.    }
17.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

我们也可以尝试使用 "separator_group": "markdown":

bash 复制代码
`

1.  PUT _inference/sparse_embedding/recursive_markdown_chunks
2.  {
3.    "service": "elasticsearch",
4.    "service_settings": {
5.      "model_id": ".elser_model_2",
6.      "num_allocations": 1,
7.      "num_threads": 1
8.    },
9.    "chunking_settings": {
10.      "strategy": "recursive",
11.      "max_chunk_size": 25,
12.      "separator_group": "markdown"
13.    }
14.  }

`AI写代码![](https://csdnimg.cn/release/blogv2/dist/pc/img/runCode/icon-arrowwhite.png)

可以看出来,它的结果和我们之前第一个结果的没有什么不一样的,这是因为 markdown 所包含的 separators 里也是对 heading 进行分段的。

相关推荐
Elasticsearch3 天前
Elastic Observability 的跨项目搜索:通过一个查询搜索所有关联项目
elasticsearch
Elasticsearch3 天前
Elasticsearch 中的 agentic 工作流:暂停 AI agent 等待人工审批,72 小时后恢复
elasticsearch
Elastic 中国社区官方博客3 天前
jina-ocr-v1:在低成本 GPU 上实现更快速的文档解析
大数据·数据库·elasticsearch·搜索引擎·全文检索·jina
vx-程序开发4 天前
【计算机毕设】django校园跑腿服务系统83141
java·数据库·vue.js·spring boot·spring·elasticsearch·django
Elasticsearch4 天前
jina-ocr-v1:在低成本 GPU 上实现更快速的文档解析
elasticsearch
深海鱼肝油ya4 天前
向量数据库Elasticsearch(四)搜索文档——各种方式
人工智能·elasticsearch·向量数据库·es搜索文档·只能体·非结构化数据库
Elasticsearch4 天前
SNAP 支付错误检测:Elastic 如何帮助美国各州应对 FY2028 的处罚
elasticsearch
Elastic 中国社区官方博客4 天前
使用 Elasticsearch 和 Jina 进行 AI 视频搜索:精准找到你需要的视频片段秒数
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
Elasticsearch4 天前
2026 年唯一获得满分 Endpoint Prevention and Response(EPR)评分的是 Elastic
elasticsearch
Elasticsearch5 天前
没有小到无法记录的日志文件:Elastic Agent 如何跟踪低于 1 KiB 阈值的文件
elasticsearch