ElasicSearch-搜索相关
一、基于词项和基于全文的搜索
基于词项(Term)的搜索
Term Query 、Range Query 、Exists Query 、Prefix Query
- 对输入不做分词,会将输入作为一个整体,在倒排索引中查找准确的词项,并且使用相关度算分公式为每个包含该词项的文档进行相关度算分。
- 可以通过Constant Score将查询转换成一个Filtering,避免算分,并利用缓存,提高性能。
基于全文(Text)的搜索
Match Query 、Match Phrase Query 、Query String Query
- 查询的时候,会先对输入的查询进行分词,然后每个词项逐个进行底层的查询,最终将结果合并。并为每个文档生成一个算分。
Match Query查询过程

短语搜索(Match Phrase Query)
match_phrase查询首先将查询字符串解析成一个词项列表,然后对这些词进行搜索,但只保留那些包含全部搜索此项,且位置与搜索词项相同的文档。
搜索大小写问题
如果是基于Term的查询,不会转换大小写,但是不能直接去匹配倒排索引的数据,因为倒排索引会把关键字、词做小写处理。
标准的Term应该去匹配指定字段的Keywork子字段
如果是基于Text的查询,不管输入是大小写,对结果都不会有影响,因为ES会对输入进行分词处理,转换为小写,再去倒排索引去进行匹配。
二、搜索的相关性算分
搜索的相关性算分,描述了一个文档和查询语句匹配的程度。ES会对每个匹配查询条件的结构进行算分 _score
打分的本质是排序,需要把最符合用户需求的文档排在前面。在ES5之前,算分的算法是TF-IDF, 现在采用BM25
TF-IDF
TF(Term Frequency):检索词在一篇文档中出现的频率
DF:检索词在所有文档中出现的频率
IDF = log(全部文档数/检索词出现过的文档数)
- TF-IDF实质上就是将TF求和变成了加权求和
BM25
和经典的TF-IDF相比,当TF无限增加时,BM25算分会趋于一个数值
Boosting
Boosting是控制相关度的一种手段
- 当boost > 1时,打分的相关度相对性提升
- 当0<boost<1时,打分的权重相对性降低
- 当boost<0时,负分
如果要单纯地提高某个字段的算分,可以在查询的时候直接指定某个字段的boost的值

比如要提高某个作者的书的算分,可以用boosting里面的positive功能,positive可指定match条件,此时去match作者的名字,则跟作者相关的文档的boost就会相应的增大

三、搜索建议
- 搜索引擎中类似的功能,在Elasticsearch中是通过Suggester API实现的
- 原理:将输入的文本分解成token,然后再索引字典里找到相似的term并返回
- 根据不同的使用场景,Elasticsearch设计了4种类别的Suggesters
- Term & Phrase Suggester
- Complete & Context Suggester
Term Suggester
会根据用户的输入到指定的字段上面去搜索,当无法搜索到结果时,返回建议的词。
相似性算法:改动多少个字符就可以和另外一个词一致
提供的Mode:
- Missing - 如果索引中已经存在,就不提供建议
- Popular - 推荐出现词频更高的词
- Always - 无论是否存在,都提供建议
Phrase Suggester
Phrase Suggester 在 Term Suggester 上增加了了⼀些额外的逻辑
例如:
Max Errors: 最多可以拼错的terms数
Condidence:限制返回的结果数,默认为1
Completion Suggester
- Completion Suggester 提供了“⾃动完成” (Auto Complete) 的功能。⽤用户每输⼊⼀个 字符,就需要即时发送⼀个查询请求到后段查找匹配项
- 对性能要求比较苛刻。Elasticsearch采用了不同的数据结构,并非通过倒排索引来完成。而是将Analyze的数据编码成FST索引一起存放,FST会被ES整个加载进内存,速度很快
- FST只能用于前缀匹配
- 使用Completion Suggester要在定义mapping的时候指定type为completion(增加一个字段)
Context Suggester
- Completion Suggester的扩展
- 可以在搜索中加入更多的上下文信息,例如:输入"star"
- 咖啡相关:建议"starbucks"
- 电影相关:"star wars"
- 在mapping定义搜索建议字段的同事,要加上contexts子字段,存放上下文相应的信息
几种Suggester的精准度和召回率
- 精准度
- Completion > Phrase > Term
- 召回率
- Term > Phrase > Completion
- 性能
- Completion > Phrase > Term
四、分布式查询过程分析
Elasticsearch的搜索,会分两阶段进行
- 第一阶段 - Query
- 第二阶段 - Fetch
Query-then-Fetch
Query阶段

- 用户发出搜索请求到ES节点。节点收到请求后,会以Coordinating节点的身份,在6个主副分片中随机选择3个分片,发送查询请求
- 被选中的分片执行查询,进行排序。然后,每个分片都会返回From+Size个排序后的文档ID和排序值给Coordinating节点
Fetch阶段
- Coordination节点会将Query阶段获取到的文档ID列表进行重新排序,选取From到Form+Size个文档的ID
- 以multi get请求的方式,到相应的分片获取详细的文档数据
Query Then Fetch潜在的问题
- 性能问题
- 每个分片上需要查from+size个文档
- 最终Coordinating节点需要处理number_of_shard * (form + size)
- 深度分页
- 相关性算分
- 每个分片都会基于自己的分片上的数据进行相关度计算。
- 解决算分不准的方法
- 数据量不大的时候,可以将主分片数设置为1
- 使用DFS Query Then Fetch(到个个分片去计算算分,然后进行一个完整性算分,比较消耗CPU和内存)

浙公网安备 33010602011771号