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和内存)

 

posted @ 2020-11-16 18:34  下山打老虎i  阅读(118)  评论(0)    收藏  举报