2.1 搜索引擎的基本原理

搜索引擎的使用在我们的日常生活中应该已经司空见惯,通常搜索引擎包括数据采集模块、文本分析模块、索引存储模块、搜索模块等,这些模块的协作流程如图2.1所示。

数据采集模块负责采集需要搜索的数据源,很多网络爬虫可以快速地从各种网站上采集结构化的数据。对于Elasticsearch而言,数据采集模块既可以是官方指定的Beats工具,也可以是第三方提供的ETL工具,还可以是使用Java客户端写入的数据。总之,这个模块的目的就是把用户需要搜索的数据采集起来以备写入搜索引擎。为了提高采集数据的效率,可以使用多线程和分布式等手段,再配合一些比较好的采集策略(例如时间戳增量采集)来满足实际项目的需要。

文本分析模块可以把结构化数据中的长文本切分成有实际意义的词,这样当用户把这些切分出来的词用作查询条件时就可搜索到该文本。如果不做文本分析,就要把原始文本全部写入索引才能搜索到需要的文本,这在某些时候可能是必要的,但是对于长篇幅的文本,直接写入原始的文本数据可能没有太大的意义。在创建索引时,你可以根据实际业务的情况来决定是否在文本数据写入索引以前进行分词,关于文本分析的具体方法,本书会在第4章详细地探讨。

图2.1 搜索引擎各模块的协作流程

索引存储模块负责将数据采集模块写入的数据按照定义好的结构写入索引。搜索引擎的索引数据是按照倒排索引的结构进行组织的。倒排索引是一种特殊的数据结构,它保存着每个词在索引中的文档编号以及它们出现在文档的位置。为了直观地表达这个过程,假设现在有3个文档待写入索引,文档内容如表2.1所示。

表2.1 3个待写入的文档

简单起见,假如此时分词器以空格进行分词,把表2.1的3个文档切分成一个个单词,并统计每个单词在文档中出现的位置,就能得到一个简单的倒排索引结构,该结构如表2.2所示。

表2.2 倒排索引结构

Elasticsearch的索引存储模块除了能把写入的数据组织成倒排索引的结构,还管理着数据的存储方式、路由方式、事务日志、索引状态等,关于索引更多、更详细的功能介绍,会在第3章进行讨论。

搜索模块的功能是根据用户输入的查询文本找到索引中匹配的文档,相关度越高的文档排名越靠前。有了倒排索引的结构,搜索会变得很方便。假如用户在搜索时输入了“black phone”这样的文本,文本分析模块会把这个搜索文本拆分成分词“black”和“phone”,然后去倒排索引中寻找包含这两个词的文档。此时很容易查出文档2和文档3都含有这两个文本。在返回最终的搜索结果时,搜索引擎会使用一套相关度计算公式来计算每个搜索结果与搜索文本的相关度分值,然后把搜索结果列表按照相关度分值由高到低进行返回。在这个例子中,由于文档2同时出现了这两个搜索词,所以在搜索结果的列表中它应当在文档3前面返回。