干货 | 知识库全文检索的最佳实践

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 1、题记这是stackoverflow上一篇精彩的问答。原文不大好理解,我做了梳理+图解;原文是ES早期版本,部分写法已不适用,所有DSL我在6.X上进行了重写和验证;针对原文内容做了扩展。

2、知识库全文检索问题抛出

重新审视一个停滞不前的项目,并寻求建议,对数千个“旧”文档进行现代化改造,


最终期望效果:通过网络访问这些文档。

文档以各种格式存在,有些已经过时:

- .doc,

- PageMaker,

- 硬拷贝hardcopy (OCR),

- PDF


- ……

很多文档已经被转化成扫描版的PDF,之前我们认为PDF类型是最终的文档格式,现在看来,我们想听听建议(比如:xml是不是更好呢?)


核心需求点:


1、一旦所有文档都采用通用格式,我们希望通过网页界面提供其内容并提供搜索服务。


2、我们希望通过搜索,能够灵活地只返回整个文档的部分页面(我相信的Lucene / elasticsearch使这成为可能?!?)


3、如果所有文档是XML是否会更加灵活?


4、如何存储、在哪里存储XML?是直接存储在数据库中还是存储成文件系统中的文件?关于文档中的嵌入式图像/图表呢?


以上,希望得到回复。


注解:xml只是提问者的当时初步的理解。


3、精彩回复

我将推荐ElasticSearch,我们先解决这个问题并讨论如何实现它:


这有几个部分:


从文档中提取文本以使它们可以索引(indexable),以备检索;

以全文搜索形式提供此文本;

高亮显示文档片段;

知道文档中的哪些段落可用于分页;

返回完整的文档。

ElasticSearch可以提供什么:


ElasticSearch(如Solr)使用Tika从各种文档格式中提取文本和元数据;

Elasticsearch提供了强大的全文搜索功能。它可以配置为以适当的语言分析每个文档,它可以借助boost提高某些字段的权重(例如,标题比内容更重要),ngrams分词等标准Lucene操作;

Elasticsearch可以高亮显示搜索结果;

Elasticsearch不知道这些片段在您的文档中出现的位置;

Elasticsearch可以将原始文档存储为附件,也可以存储并返回提取的文本。但它会返回整个文档,而不是一个页面。

【直译】您可以将整个文档作为附件发送到ElasticSearch,并且可以进行全文搜索。但是关键点在于上面的(4)和(5):知道你文档中的位置,并返回文档的某些部分。存储单个页面可能足以满足您的“我在哪里”的目的,但是您希望将它们分组,以便在搜索结果中返回文档,即使搜索关键字出现在不同的页面上。


任务分解:


3.1、索引部分——将文档存储在ElasticSearch中。

使用Tika(或任何你喜欢的)来从每个文档中提取文本。将其保留为纯文本或HTML格式以保留一些格式。

(忘记XML,不需要它)。


每个文档提取元数据:标题,作者,章节,语言,日期等。


将原始文档存储在您的文件系统中,并记录路径,以便以后可以使用。


在ElasticSearch中,索引包含所有元数据和可能的章节列表的“doc”文档。


将每个页面索引为“page”文档,其中包含:

- 包含“doc”文档ID的父字段(请参阅下面的“父子关系”)

- 文本

- 页码

- 也许章节标题或编号

- 您想要搜索的任何元数据


存储必备——父子文档关系:


通常,在ES(和大多数NoSQL解决方案)中,每个文档/对象都是独立的 - 没有真正的关系。


通过建立“doc”和“page”之间的父子关系,ElasticSearch确保子文档(即“页面”)与父文档(“doc”)存储在同一分片上。


这使您能够运行has_child等的查询方式,它将根据“page”的内容找到最匹配的“doc”。


图解示例:

image.png

二、检索部分——

现在进行搜索。


你如何做到这一点取决于你想如何展示你的结果


按页面page分组,

按文档doc分组。

通过页面的结果很容易。


此查询返回匹配页面的列表(每个页面全部返回)以及页面中高亮显示的片段列表。


举例如下:


POST /my_index/page/_search?pretty=1

{

  "query" : {

     "match" : {

        "text" : "interesting keywords"

     }

  },

    "highlight": {

   "pre_tags": [

     "<span style=\"color:red\">"

   ],

   "post_tags": [

     "</span>"

   ],

   "require_field_match": true,

   "fields": {

     "title": {}

   }

 }

  }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

显示包含文本高亮字段的“doc”分组有点棘手。 它不能用一个单一的查询来完成。


一种方法可能是:


第1步:通过对其子(“页面”)查询,返回最匹配的父级(“doc”)。


POST /my_index/doc/_search?pretty=1

{

 "query": {

   "has_child": {

     "type": "page",

     "query": {

       "bool": {

         "must": [

           {

             "match": {

               "text": "interesting keywords"

             }

           },

           {

             "term": {

               "type": "page"

             }

           },

           {

             "term": {

               "factor": "5"

             }

           }

         ]

       }

     },

     "score_mode": "sum"

   }

 }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

第2步:从上述查询中收集“doc”ID 发出新查询,从匹配的“页面”文档中获取片段。


GET /my_index/page/_search?pretty=1

{

  "query" : {

     "bool" : {

       "must":{

        "query" : {

           "match" : {

              "text" : "interesting keywords"

           }

        }},

        "filter" : {

           "terms" : {

              "doc_id" : [1,2,3]

           }

        }

     }

  },

  "highlight" : {

     "fields" : {

        "text" : {}

     }

  }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

第3步:在您的应用程序中,将上述查询的结果按doc分组并显示出来。


使用第二个查询的搜索结果,您已经拥有了可供显示的页面的全文。要转到下一页,您可以搜索它:


GET /my_index/page/_search?pretty=1

{

  "query" : {

     "constant_score" : {

        "filter" :

           [

              {

                 "term" : {

                    "doc_id" : 1

                 }

              },

              {

                 "term" : {

                    "page" : 2

                 }

              }

           ]

     }

  },

  "size" : 1

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

或者,给“页面”文档提供一个由doc_id _doc_id _ page_num(例如123_2)组成的ID,然后您可以通过如下的检索获取该页面:


curl -XGET'http://127.0.0.1:9200/my_index/page/123_2

1

3、扩展

Tika是一个内容分析工具,自带全面的parser工具类,能解析基本所有常见格式的文件,得到文件的metadata,content等内容,返回格式化信息。总的来说可以作为一个通用的解析工具。特别对于搜索引擎的数据抓去和处理步骤有重要意义。


Tika是Apache的Lucene项目下面的子项目,在lucene的应用中可以使用tika获取大批量文档中的内容来建立索引,非常方便,也很容易使用。


Apache Tika toolkit可以自动检测各种文档(如word,ppt,xml,csv,ppt等)的类型并抽取文档的元数据和文本内容。


Tika集成了现有的文档解析库,并提供统一的接口,使针对不同类型的文档进行解析变得更简单。Tika针对搜索引擎索引、内容分析、转化等非常有用。


4、有没有现成的开源实现呢?

https://github.com/RD17/ambar


Ambar是一个开源文搜索引擎,具有自动抓取,OCR识别,标签分类和即时全文搜索功能。


Ambar定义了在工作流程中实现全文本文档搜索的新方法:


轻松部署Ambar和一个单一的docker-compose文件

通过文档和图像内容执行类似Google的搜索

Ambar支持所有流行的文档格式,如果需要的话可以执行OCR

标记您的文件

使用简单的REST

Api将Ambar集成到您的工作流程中

参考:


http://t.cn/R1gTMw4

http://t.cn/8FYfhE2

http://t.cn/R1gTK3M

http://t.cn/R1gT6GY

http://t.cn/RaPOswu

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
索引 存储 数据格式
干货 | 知识库全文检索的最佳实践
这是stackoverflow上一篇精彩的问答。
1240 0
|
6月前
|
机器学习/深度学习 自然语言处理 机器人
【RAG实践】基于LlamaIndex和Qwen1.5搭建基于本地知识库的问答机器人
LLM会产生误导性的 “幻觉”,依赖的信息可能过时,处理特定知识时效率不高,缺乏专业领域的深度洞察,同时在推理能力上也有所欠缺。
|
1月前
|
机器学习/深度学习 数据采集 人工智能
文档智能 & RAG 让AI大模型更懂业务 —— 阿里云LLM知识库解决方案评测
随着数字化转型的深入,企业对文档管理和知识提取的需求日益增长。阿里云推出的文档智能 & RAG(Retrieval-Augmented Generation)解决方案,通过高效的内容清洗、向量化处理、精准的问答召回和灵活的Prompt设计,帮助企业构建强大的LLM知识库,显著提升企业级文档管理的效率和准确性。
|
12天前
|
存储 人工智能 自然语言处理
基于LLamaIndex构建企业级私有知识库:RAG Workflow工作流详解
【11月更文挑战第12天】随着生成式AI的快速发展,企业对智能化信息检索和生成的需求日益增加。传统的知识库系统往往局限于静态的数据存储和查询,难以满足复杂多变的业务需求。而检索增强生成(RAG, Retrieval-Augmented Generation)技术的出现,为企业级私有知识库的建设提供了新的解决方案。LLamaIndex作为专为LLMs(大型语言模型)设计的私有知识索引工具,结合RAG Workflow工作流,能够构建高效、智能的企业级私有知识库,满足企业对于知识管理和智能问答的多样化需求。
39 4
|
1月前
|
存储 人工智能 算法
精通RAG架构:从0到1,基于LLM+RAG构建生产级企业知识库
为了帮助更多人掌握大模型技术,尼恩和他的团队编写了《LLM大模型学习圣经》系列文档,包括《从0到1吃透Transformer技术底座》、《从0到1精通RAG架构,基于LLM+RAG构建生产级企业知识库》和《从0到1吃透大模型的顶级架构》。这些文档不仅系统地讲解了大模型的核心技术,还提供了实战案例和配套视频,帮助读者快速上手。
精通RAG架构:从0到1,基于LLM+RAG构建生产级企业知识库
|
28天前
|
机器学习/深度学习 数据采集 人工智能
文档智能和检索增强生成(RAG)——构建LLM知识库
本次体验活动聚焦于文档智能与检索增强生成(RAG)结合构建的LLM知识库,重点测试了文档内容清洗、向量化、问答召回及Prompt提供上下文信息的能力。结果显示,系统在自动化处理、处理效率和准确性方面表现出色,但在特定行业术语识别、自定义向量化选项、复杂问题处理和Prompt模板丰富度等方面仍有提升空间。
66 0
|
1月前
|
机器学习/深度学习 数据采集 人工智能
大模型体验报告:阿里云文档智能 & RAG结合构建LLM知识库
大模型体验报告:阿里云文档智能 & RAG结合构建LLM知识库
|
3月前
|
自然语言处理 前端开发 Go
5 大场景上手通义灵码企业知识库 RAG
大家好,我是通义灵码,你的智能编程助手!今天就跟大家分享下企业知识库能帮开发者做些什么。
|
4月前
|
自然语言处理 前端开发 Go
5 大场景上手通义灵码企业知识库问答
通义灵码在企业版里还引入了一个超酷的新技能:RAG(Retrieval-Augmented Generation)检索增强生成的能力,本文就跟大家分享下企业知识库能帮开发者做些什么。
1222 13
|
5月前
|
机器学习/深度学习 存储 SQL
一文彻底搞定 RAG、知识库、 Llama-3
Llama-3 用于 RAG,增强大语言模型的性能,整合外部知识。关键组件包括:1) 自定义知识库,存储更新的信息;2) 分块处理,拆解文本便于管理;3) 嵌入模型,转化多模态数据为数值向量;4) 向量数据库,快速检索相似性;5) 用户聊天界面,交互平台;6) 查询引擎,获取上下文生成响应;7) 提示词模板,结合查询与知识生成提示。整个流程确保了 RAG 系统的有效性和响应能力。本文为转载,来自:https://mp.weixin.qq.com/s/Xue-9FKMMVKBSzIZC3JJdA

热门文章

最新文章