• Search 执行的时候实际分两个步骤运作的
    - Query 阶段
    - Fetch 阶段
  • Query-Then-Fetch

Query阶段

es条件计算 es的算法_字段

Fetch阶段

es条件计算 es的算法_倒排索引_02

相关性算分问题

  • 相关性算分在shard与shard间是相互独立的,也就意味着同一个term的IDF值在不同shard上是不同的。文档的相关性算分和他所处的shard相关
  • 在文档数量不多是,会导致相关性算分严重不准的情况发生
  • 解决思路有两个:
    - 一是设置分片数为1个,从根本上排除问题,在问当数量不多的时候可以考虑该方案,比如百万到千万级别的文档数量
    - 二是使用 DFS Query-then-Fetch 查询方式
    - DFS Query-then-Fetch 是在拿到所有文档后再重现完整的计算一次相关性算分,耗费更多的cpu和内存,执行新能底下,一般不建议使用。使用方式如下:

排序

  • es 默认会采用相关性算分排序,用户可以设定sorting 参数来自行设定排序规则
  • 按照字符串排序比较特殊,因为es 有 text和keyword 两种类型,针对text类型排序,如下所示:
  • 针对 keyword类型排序,可以返回预期结果
  • 排序的过程实质是对字段原始内容排序的过程,这个过程中倒排索引无法发挥作用,需要用到正排索引,也是通过文档Id和字段可以快速得到字段原始内容。
  • es对此提供了3种实现方式:
    - fielddata 默认禁用
    - doc values 默认启用,除了 text 类型

Fielddata vs DocValues

es条件计算 es的算法_es条件计算_03

Fielddata

  • Fielddata 默认是关闭的,可以通过如下api开启
    - 此时字符串是按照分词后的term排序,往往结果很难复合预期
    - 一般是在对分词做聚合分析的时候开启

Doc Values

  • Doc Values 默认是启用的,可以在创建索引的时候关闭:
    - 如果后面要再开启 doc values,需要做 reindex 操作
  • 可以通过该字段获取 fielddata 或者 doc values 中存储的内容