• @Elasticsearch之深度应用及原理剖析--文档搜索机制剖析



    title: ElasticSearch之深度应用及原理剖析
    author: Xoni
    tags:

    • 搜索引擎
    • Elasticsearch
      categories:
    • 搜索引擎
    • Elasticsearch
      abbrlink: 5a1f6e0b

    第5节 Query文档搜索机制剖析

    在这里插入图片描述

    Elasticsearch的搜索类型(SearchType类型)

    2.0之前四种 QUERY_AND_FETCH, DFS_QUERY_AND_FETCH, QUERY_THEN_FETCH,DFS_QUERY_THEN_FETCH
    2.0版本之后 只有两种了。

    public enum SearchType { 
      DFS_QUERY_THEN_FETCH((byte)0), 
      QUERY_THEN_FETCH((byte)1);
    public static final SearchType DEFAULT = QUERY_THEN_FETCH;
    public static final SearchType[] CURRENTLY_SUPPORTED = new SearchType[] {
      QUERY_THEN_FETCH, DFS_QUERY_THEN_FETCH
    };
    }
    

    可以通过java的API 设置

    SearchRequest searchRequest = new SearchRequest(POSITION_INDEX); 
    searchRequest.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
    

    1)query and fetch

    向索引的所有分片 ( shard)都发出查询请求, 各分片返回的时候把元素文档 ( document)和计算后的排名信息一起返回。
    这种搜索方式是最快的。
    优点:这种搜索方式是最快的。因为相比后面的几种es的搜索方式,这种查询方法只需要去shard查询一次。
    缺点:返回的数据量不准确, 可能返回(N*分片数量)的数据并且数据排名也不准确,同时各个shard返回的结果的数量之和可能是用户要求的size的n倍。

    2) DFS query and fetch

    这个D是Distributed,F是frequency的缩写,至于S是Scatter的缩写,整个DFS是分布式词频率和文档频率散发的缩写。 DFS 其实就是在进行真正的查询之前, 先把各个分片的词频率和文档频率收集一下, 然后进行词搜索的时候, 各分片依据全局的词频率和文档频率进行搜索和排名。这种方式比第一种方式多了一个 DFS 步骤(初始化散发(initial scatter)),可以更精确控制搜索打分和排名。也就是在进行查询之前,先对所有分片发送请求, 把所有分片中的词频和文档频率等打分依据全部汇总到一块,再执行后面的操作。

    优点:数据排名准确
    **缺点:**性能一般返回的数据量不准确, 可能返回(N*分片数量)的数据

    3) query then fetch(es 默认的搜索方式)

    如果你搜索时, 没有指定搜索方式, 默认使用的这种搜索方式。 这种搜索方式, 大概分两个步骤:
    第一步, 先向所有的 shard 发出请求, 各分片只返回文档 id(注意, 不包括文档 document)和排名相关的信息(也就是文档对应的分值), 然后按照各分片返回的文档的分数进行重新排序和排名, 取前size 个文档。
    第二步, 根据文档 id 去相关的 shard 取 document。 这种方式返回的 document 数量与用户要求的大小是相等的。

    详细过程:
    1.发送查询到每个shard
    2.找到所有匹配的文档,并使用本地的Term/Document Frequency信息进行打分
    3.对结果构建一个优先队列(排序,标页等)
    4.返回关于结果的元数据到请求节点。注意,实际文档还没有发送,只是分数
    5.来自所有shard的分数合并起来,并在请求节点上进行排序,文档被按照查询要求进行选择
    6.最终,实际文档从他们各自所在的独立的shard上检索出来
    7.结果被返回给用户

    优点:返回的数据量是准确的。
    缺点:性能一般,并且数据排名不准确。

    4) DFS query then fetch

    比第 3 种方式多了一个 DFS 步骤。
    也就是在进行查询之前, 先对所有分片发送请求, 把所有分片中的词频和文档频率等打分依据全部汇总到一块, 再执行后面的操作。

    详细步骤:
    1.预查询每个shard,询问Term和Document frequency
    2.发送查询到每个shard
    3.找到所有匹配的文档,并使用全局的Term/Document Frequency信息进行打分
    4.对结果构建一个优先队列(排序,标页等)
    5.返回关于结果的元数据到请求节点。注意,实际文档还没有发送,只是分数
    6.来自所有shard的分数合并起来,并在请求节点上进行排序,文档被按照查询要求进行选择
    7.最终,实际文档从他们各自所在的独立的shard上检索出来
    8.结果被返回给用户

    优点

    • 返回的数据量是准确的
    • 数据排名准确

    缺点

    • 性能最差【 这个最差只是表示在这四种查询方式中性能最慢, 也不至于不能忍受。如果对查询性能要求不是非常高, 而对查询准确度要求比较高的时候可以考虑这个】

  • 相关阅读:
    【Elasticsearch管理】节点角色及发现机制
    怎么用docker将项目打包成镜像并导出给别人适用 (dockerfile)
    4个顶点的无向完全图一共有多少个生成树
    易灸灸的微商模式,新零售全案运营,裂变营销与代理模式
    【跟小嘉学 Rust 编程】二十七、Rust 异步编程(Asynchronous Programming)
    Lua顺序执行循环
    异构混合阶多智能体系统编队控制的分布式优化
    JDK 自带的服务发现框架 ServiceLoader 好用吗?
    [Ant Design Vue 树控件Tree]内存溢出报错
    SSO 基于token vue + element ui spring boot前端分离
  • 原文地址:https://blog.csdn.net/weixin_45992021/article/details/127095371