Elasticsearch进阶教程:轻松构造一个全方位的信息检索系统

搜索,已经成为我们生活中必不可少的一个重要部分,无论我们是在网上冲浪、工作办公、还是私人文件的处理,都需要一个搜索框方便我们快速找到所需的信息。而当我们的任务是需要对多个信息渠道中的信息进行梳理和检索时,现有割裂的各个搜索框无法协同的问题,就成了阻碍我们进一步提高效率的痛点。我的日常生活和工作就经常有这样一个场景:

“客户询问一个问题,与这个问题相关的知识点我记忆中在什么地方见过,可能是我读过的某篇文章,或者是某封邮件,甚至是我自己在某个文件里记录了笔记,但我就是记不起来在哪里了,然后就各种翻浏览记录和本地的文件,却依然无法找到”

因此,构建一个全方位的信息检索系统,能够连接多个数据源从日常工作接触的所有渠道上去寻找信息的这样一个工具成了不少企业和个人的强烈需求。而在本文,我们将进行一个简单的展示,通过Elastic Search Platform (我们以前称为Elastic Stack),我们能在一天之内就构建一个涵盖从互联网到本地文件的全方位的信息检索系统。

分步一个全方位的信息检索系统

构建一个全方位的信息检索系统,我们至少需要以下几个步骤:

  • 确定信息检索系统所需的数据源
  • 按照统一的格式,获取/接入所需的数据
  • 数据源的整合
  • 构建方便易用的搜索应用UI
  • 构建以搜索行为数据为基础的搜索优化能力,包括用户行为分析和相关性调优

确定信息检索系统所需的数据源

首先,我们要确定哪些数据应该包含在这个系统当中。

从我个人的需求看,一个全方位的信息检索系统主要包含两个方面的内容一个是本地的文件资料,一个是网络上的有用资源。

所以,在构建的第一步上,我们需要先梳理哪些信息是我们在平时的工作习惯中经常需要接触,并且反复查询的。

以我本身的工作为例,围绕elasticsearch相关的项目、主题,在日常工作中我需要经常进行的工作包括

  • 检索elasticsearch本身的官方文档,以回答用户的具体技术问题
  • 检索以往整理好的项目建设、架构、健康巡检、故障排查、最佳实践等内容,以方便应对场景化的问题并重复利用已有的资源解决相似的问题
  • 检索公司内的共享资源,包括产品团队,开发团队,以及其他架构师整理好的各种产品、销售相关的资料
  • 检索互联网上社区爱好者的各种关于项目应用、疑难杂症相关的博客分享,以广泛了解用户的各种反馈和经验总结

对应的,以上内容主要涉及以下信息:

因此,对于上述的数据,我们需要有针对性的使用能够一次性扫描,定期获取更新的工具将这些数据摄入到检索系统当中

使用Web crawler爬取Elasticsearch相关的网络资源

对于网络上的信息,主要的工具是爬虫,在这个例子中,需要使用爬虫获取的资源包括

在现在的elastic search platform的企业搜索解决方案中,App search应用已经包含了web网络爬虫的应用程序,我们可以在App search中快速创建Web crawler。

这里有一个基础概念:引擎。这是App search里的数据单元,反映在elasticsearch上就是一个包含可搜索数据的索引和一系列相关的元数据索引。通俗点,我们也可以理解为数据库里的有固定数据源的数据表。对应与我们日常的数据导入方式,这里提供了网络爬虫,上传JSON,以及从API写入数据三种方式:

App search的引擎设置

为了获取网络上的这些资源,我们需要定义一个网络爬虫,帮助我们定期获取这些资源的内容更新,并且提供和查询的方式。

因为每个数据源会是一个单独的引擎,因此我们需要分别创建:

在创建引擎时,可以针对不同的源选择不同的引擎语言,对应的,后端在处理时会使用合适的分词器进行分词。这是我们选择以网络爬虫的方式进行数据获取,并且配置入口点(完整的url),爬虫会从入口点推断出域(domain),需要注意目前提供的傻瓜式爬虫不支持跨域爬取,其功能主要是提供一个网站内资源的扫描,作为快速构建网站导航搜索解决方案的核心功能

针对每个被爬取的网站,Elastic App search中提供的web crawler会严格遵守网站具体的robots.txt中声明的爬虫规范,只爬取被允许的扫描的path。

创建爬虫后,我们需要配置爬网规则。我们以elastic中文社区(https://elasticsearch.cn/)为例,我们只希望获取社区讲师分享的精品内容

内容主要在 https://elasticsearch.cn/slides/ 路径下。而对于其他内容,比如论坛的问答:

主要是在/questions、以及/articles等路径下。因此,我们需要通过爬网规则过滤我们不需要的内容

这里通过配置只允许爬取路径包含/slides/[0-9]{1-5}的方式来进行过滤,比如:https://elasticsearch.cn/slides/290

而对于其他的,一律不允许(Regex: .*)。图中我们配置了多条规则,elastic web crawler的工作方式是按顺序从上到下进行规则匹配,直到匹配上一条规则,然后break。

每次爬网的信息

点击开始爬网后,爬虫会定期爬取网页与更新,并且在elasticSAErch中记录状态和日志。

完成之后,我们可以打开一个搜索UI,确认一下内容

使用Fscrawler扫描本地的文件资源

相对于使用标准的、由Elastic原厂提供的web爬虫爬取的网络资源,Elastic原厂尚未提供针对本地文件系统上的资源的连接器,因此还需要依赖一些开源社区提供的工具。这里推荐的是Fscrawler

Fscrawler是由Elastic的员工开源和维护的一个Elasticsearch文件系统爬虫工具。其功能包括

  • 在本地文件系统(或安装的驱动器)上抓取和索引新文件,更新现有文件删除文件
  • 通过 SSH/FTP 抓取的远程文件系统
  • 可通过REST 接口将二进制文档“上传”到 elasticsearch

在这里,我们主要用到的是本地文件系统爬虫的功能。该工具上手非常简易,只需要把应用程序下载到本地,启动的时候提供一个任务名,比如这里的job_name

bin/fscrawler job_name
18:28:58,174 WARN  [f.p.e.c.f.FsCrawler] job [job_name] does not exist
18:28:58,177 INFO  [f.p.e.c.f.FsCrawler] Do you want to create it (Y/N)?
y
18:29:05,711 INFO  [f.p.e.c.f.FsCrawler] Settings have been created in [~/.fscrawler/job_name/_settings.yaml]. Please review and edit before relaunch

fscrawler会自动创建一个文件抓取任务的配置文件,保存在~/.fscrawler/job_name/_settings.yaml,我们只需要在_settings.yaml文件中提供关键信息即可,例如:

---
name: "elastic"
fs:
  url: "/Users/lex.li/Documents/elastic/"
  update_rate: "15m"
  excludes:
  - "*/~*"
  - "*.py"
  - "*.zip"
  - "*.js"
  - "ds_store"
  - "pyc"
  - "console"
  json_support: false
  filename_as_id: false
  add_filesize: true
  remove_deleted: false
  add_as_inner_object: false
  store_source: false
  index_content: true
  attributes_support: false
  raw_Metadata: false
  xml_support: false
  index_folders: false
  lang_detect: false
  continue_on_error: false
  ocr:
    language: "eng"
    enabled: true
    pdf_strategy: "ocr_and_text"
  follow_symlinks: false
elasticsearch:
  username: "elastic"
  password: "your-password"
  nodes:
  - url: "https://lex-demo.es.ap-east-1.aws.elastic-cloud.com"
  bulk_size: 100
  flush_interval: "5s"
  byte_size: "10mb"

这里,我扫描的是本地目录/Users/lex.li/Documents/elastic/,过滤了我不需要的文件

  excludes:
  - "*/~*"
  - "*.py"
  - "*.zip"
  - "*.js"
  - "ds_store"
  - "pyc"
  - "console"

并且指定了我的后端Elasticsearch的信息:

elasticsearch:
  username: "elastic"
  password: "your-password"
  nodes:
  - url: "https://lex-demo.es.ap-east-1.aws.elastic-cloud.com"
  bulk_size: 100
  flush_interval: "5s"
  byte_size: "10mb"

扫描之后的文件信息,会在Elasticsearch中创建一个跟任务同名的信息,并且包含检索信息所需要的所有字段,比如:contentfile.filenamefile.extensionfile.urlfile.filesize等。

我们可以用同样的方式,将本地的官方文档,同样作为一个数据源,添加进来,只需要把本地的官方文档的目录,作为一个新的fscrawler的任务进行一次性的扫描即可。获取离线文档的方式可以参考博文:Elasticsearch进阶教程:生成离线官方文档

数据源的整合

到目前位置,我们已经分别创建了好几个数据源:

  • 官方文档
  • 官方论坛
  • 布道师、架构师的博客
  • 中文论坛中的讲师分享
  • 日常elasticsearch项目相关文档

每个引擎就是一个单独的一个数据集,当通过UI来进行检索时,通常是引擎之间是相互隔离的。但我们希望针对某个主题做更广泛的搜索的时候就需要跨数据源的检索,这时就需要元引擎。

什么是元引擎

元引擎是没有自己的文档的引擎。相反,它结合了多个其他引擎,以便可以将它们一起搜索,就好像它们是单个引擎一样。

构成元引擎的引擎称为源引擎

示例:可以将两个引擎“western-national-parks”和“eastern-national-parks”组合在一个名为“national-parks”的元引擎中,以便将它们作为一个数据集进行搜索

GET <ENTERPRISE_SEARCH_BASE_URL>/api/as/v1/engines/parks/search

{
  "results": [
    {
      "id": "eastern-national-parks|park_shenandoah",
      "_Meta": {
        "id": "park_shenandoah",
        "engine": "eastern-national-parks"
      }
    },
    {
      "id": "western-national-parks|park_yosemite",
      "_Meta": {
        "id": "park_yosemite",
        "engine": "western-national-parks"
      }
    }
  ]
}

在UI上,我们只需要创建一个元引擎,再将源引擎添加进去即可

构建方便易用的搜索应用UI

App search最吸引人的能力之一,就是方便我们快速的构建搜索的体验。当我们创建引擎之后,就可以在界面上创建搜索UI。整个过程非常的简单,这里提供了用于筛选和排序的字段,以及点击搜索结果后的跳转链接字段(URL字段):

你也可以完全都不选择,直接点击生成搜索体验。即可在弹出的窗口上快速体验搜索的UI

如果这个UI觉得还OK,只需要点击右上角的 Download ZIP package 即可获取这个UI的源码,

解压之后,目录如下:

my-documents-react-demo-ui$ tree -L 1
.
├── LICENSE.txt
├── NOTICE.txt
├── README.md
├── bin
├── logo-app-search.png
├── node_modules
├── package-lock.json
├── package.json
├── public
├── scripts
└── src

根据压缩包里提供的README.md, 可以快速的在本地拉起一个搜索应用:

# Run the `cd` command to change the current directory to the
# location of your downloaded Reference UI. Replace the path
# below with the actual path of your project.
cd ~/Downloads/app-search-reference-ui

# Run this to set everything up
npm install

# Run this to start your application and open it up in a new browser window
npm start

或者是参考src中的代码App.js,将UI嵌入到自己的应用当:

└── src
    ├── App.js
    ├── config
    └── index.js

这里提供了一个操作视频:

视频内容

用户行为分析和相关性调优

对于一个搜索服务来说,有几个关键的信息是我们需要掌握的:

  • 用户在搜什么,什么话题最热?
  • 我们提供的搜索结果里面:
    • 有没有客户期望的内容
    • 客户最常点击的是哪个?
    • 哪些搜索结果是没有客户点击的?(准确率为0)
  • 我们如何调整搜索的准确性和相关性?
  • 我们如何调整结果的排序?
  • 我们如何设置同义词?比如,obersavability = o11y, kubernetes = k8s?

对于以上需求,App search已经为我们提供了开箱即用的功能

  • 用户在搜什么,什么话题最热?
  • 我们提供的搜索结果里面:
    • 有没有客户期望的内容
    • 客户最常点击的是哪个?
    • 哪些搜索结果是没有客户点击的?(准确率为0)

我们如何调整搜索的准确性和相关性?

我们如何调整结果的排序?

视频内容

我们如何设置同义词?

视频内容

总结

通过本文我们可以看到,要构建一个涵盖互联网上内容与本地内容的定制化的知识搜索引擎,在缺乏解决方案协助的情况下,我们可能需要耗费大量的时间、精力、人力去进行设计、开发和维护。而使用Elastic Search platform,我们可以在一天之内完成这个项目的构建,不仅大量节约了时间,从效果上,更能帮助我们打通获取知识道路上的壁垒

相关文章

显卡天梯图2024最新版,显卡是电脑进行图形处理的重要设备,...
初始化电脑时出现问题怎么办,可以使用win系统的安装介质,连...
todesk远程开机怎么设置,两台电脑要在同一局域网内,然后需...
油猴谷歌插件怎么安装,可以通过谷歌应用商店进行安装,需要...
虚拟内存这个名词想必很多人都听说过,我们在使用电脑的时候...