ElasticSearch 是一个分布式搜索和分析引擎,其高效的搜索性能主要依赖于分词(tokenization)和倒排索引(inverted index)这两个核心技术。
分词(Tokenization)
在 ElasticSearch 中,分词通常在索引文档时进行,即在将文档添加到索引之前,先对文档的内容进行分词处理。
- 英文:一个单词一个词,很简单。I am a student,词与词之间空格分隔。
- 中文:我是学生,就不能一个字一个字地分,我-是-学生。这是好分的。还有歧义的,使用户放心,使用-户,使-用户。人很容易看出,机器就难多了。所以市面上有各种各样的分词器, 一个强调的效率一个强调的准确率。
倒排索引(Inverted Index)
倒排索引是一种将文档内容中的词与包含这些词的文档进行关联的数据结构。它主要包括两个部分:
- 词典(Dictionary):存储所有在文档集合中出现过的词。
- 倒排列表(Posting List):对于每个词,记录所有包含该词的文档的ID。
具体流程如下:
- 构建词典:在分词过程中,所有词被加入词典。
- 构建倒排列表:每个词都会对应一个倒排列表,记录哪些文档包含该词,以及该词在文档中的位置。
工作原理
当一个文档被添加到 ElasticSearch 时,它会经过如下步骤:
- 分词:文档内容被分词,生成一系列词。
- 建立倒排索引:每个词被添加到词典,并在相应的倒排列表中记录该词在文档中的位置。
当用户发起搜索请求时,ElasticSearch 会:
- 解析查询:将查询语句分词,生成查询词列表。
- 查找倒排索引:在词典中查找这些词,并获取相应的倒排列表。
- 合并结果:根据倒排列表,将包含查询词的文档ID合并,计算文档的相关性得分,并返回匹配的文档。
示例
假设有两个文档:
- 文档1:“ElasticSearch is a search engine”
- 文档2:“Search engines are important”
在分词阶段,两个文档被处理为词列表:
- 文档1:[ElasticSearch, is, a, search, engine]
- 文档2:[Search, engines, are, important]
建立的倒排索引如下:
词 文档ID
a [1]
are [2]
ElasticSearch [1]
engine [1]
engines [2]
important [2]
is [1]
search [1, 2]
当用户搜索 “search engine” 时,ElasticSearch 会:
- 将查询分词为 [“search”, “engine”]。
- 在词典中查找这些词,并获取倒排列表:
search: [1, 2]
engine: [1] - 合并结果并计算相关性:
文档1 包含所有查询词,相关性较高。
文档2 仅包含一个查询词,相关性较低。
最终返回相关性最高的文档给用户。