本文将从数据存储和搜索的角度简单分析Elasticsearch的搜索运行机制,主要涉及搜索API、搜索机制、存在问题和解决方案。

4.1 Search API

Search API允许用户执行一个搜索查询并返回匹配查询的搜索命中结果。

Elasticsearch查询主要有两种方式:URI SearchRequest Body Search

  • URI Search:通过URI参数实现搜索,特点是操作简便,仅包含部分查询语法,常用参数如下:

    q:指定查询语句,使用Query String Syntax

    df:默认字段,不指定时,会对所有字段进行查询

    sort:排序

    profile:用于查看查询是如何被执行的

  • Request Body Search:完备的查询语法Query DSL,所以还是建议使用Request Body Search。

4.2 深入了解Search运行机制

建议先参考上篇Elasticsearch核心技术(四):索引原理分析,其中主要介绍了ES的分布式存储架构和原理。

4.2.1 Query-then-Fetch运行机制

Elasticsearch的分布式搜索的运行机制称为Query-then-Fetch。具体分为Query和Fetch两个阶段:

Query阶段

用户发出搜索请求到达ES节点。节点收到请求后,会以协调节点(Coordinating Node)的身份,在6个主副分片中随机选择3个分片,发送查询请求。

被选中的节点,进行排序(根据score值进行排序)。然后每个分片都返回 From+size 个排序后的文档id和排序值给协调节点。 注意这里返回的是文档id。

Fetch阶段

Coordinating节点将Query阶段从每个分片获取的排序的文档id列表重新进行排序,选取 From 到 From+size 个文档的id。

multi get请求的方式,到相应的分片获取详细的文档数据。

4.2.2 为什么需要两阶段才能完成搜索

因为Elasticsearch在查询的时候不知道文档位于哪个分片,因此索引的所有分片都要参与搜索,然后协调节点将结果合并,在根据文档ID获取文档内容。例如现在有5个分片,需要查询匹配度Top10的数据,那么每个分片都要查询出当前分片的Top10的数据,协调节点将5×10个结果再次进行排序,返回Top10的结果给客户端。

4.2.3 Query-then-Fetch存在问题和解决方案

Query-then-Fetch存在问题分为两方面,一个是性能问题,一个是相关性算分问题。

  • 性能问题

性能问题主要表现为深度分页的问题。Elasticsearch数据是分片存储的,数据分布在多台机器上。有这样一个场景,如何获取前1000个文档?当获取从990-1000的文档时候,会在每个分片上面都先获取1000个文档,然后再由协调节点聚合所有分片的结果在排序选取前1000个文档。

这个过程有什么问题吗?当然是有的,页数越深,处理文档越多,占用内存越多,耗时越长。所以要尽量避免深度分页。当然,ES官方也注意了这个问题,所以通过index.max_result_window限定最多到10000条数据。当然我们也可以根据业务需要修改这个参数,这也解释了:为什么Google搜索结果只有相关度最高的17页结果,百度只有76页的结果,原因之一是受限于Elasticsearch深度分页的性能问题。



  • 相关性算分问题

    另外一个问题是相关性算分不准确问题。每个分片都基于自己分片上面的数据进行相关度计算。这会导致打分偏离的情况,特别是数据量很少的时候。相关性算分在分片之间是相互独立。当文档总数很少的情况下,如果主分片大于1,如果主分片数越多,相关性算分会越不准。

  • 如何解决算分不准的问题?

  1. 当数据量不大的时候,将主分片数设置为1;当数据量足够大的时候,只要保证文档均匀分布在各个分片上面,结果一般不会出现偏差
  2. 使用DFS Query Then Fetch

    在搜索的URL中指定参数 _search?search_type=dfs_query_then_fetch ;这样就可以保证每个分片把各个分片的词频和文档频率进行搜集,然后进行一次相关性算分。但是这样会耗费更多的CPU和内存资源,执行性能较低。
  • 如何避免深度分页的问题?

使用Search_After

ES提供实时的下一页文档获取功能,这个功能只能下一页,不能上一页;

不能指定页数,不能使用from参数;

  • 三种分页方式对比:
类型 场景
From/Size 需要实时获取顶部的部分文档,且需要自由翻页
Scroll 需要全部文档,如导出所有数据的功能
Search_After 需要全部文档,不需要自由翻页

4.3 总结

经济基础决定上层建筑,ES的分片存储决定了搜索机制。其实存储和搜索不能分割开来看,只存储不可搜索,这个存储是没有意义的;只搜索没有存储(数据源)是空中楼阁。

Elasticsearch核心技术(五):搜索API和搜索运行机制的更多相关文章

  1. ElasticSearch(十五) _search api 分页搜索及deep paging性能问题

    1.分页搜索 语法: size,from GET /_search?size=10 GET /_search?size=10&from=0 GET /_search?size=10&f ...

  2. 五:理解控件的运行机制(例:基于Control命名空间的简单控件)

    一:先用最简短的话说点理论的1.asp.net中所有的标准控件都可以重写 2.和控件相关的命名空间有 System.Web.UI.Control是所有控件的基类只提供简单的呈现逻辑,不支持样式表 Sy ...

  3. elasticsearch系列四:搜索详解(搜索API、Query DSL)

    一.搜索API 1. 搜索API 端点地址 从索引tweet里面搜索字段user为kimchy的记录 GET /twitter/_search?q=user:kimchy 从索引tweet,user里 ...

  4. Golang 谷歌搜索api 实现搜索引擎(前端 bootstrap + jquery)

    Golang 谷歌搜索api 实现搜索引擎(前端 bootstrap + jquery) 体验 冒号搜索 1. 获取谷歌搜索api 谷歌搜索api教程 2. 后台调用 程序入口 main.go // ...

  5. ES系列五、ES6.3常用api之搜索类api

    1.搜索api 1.1.routing:路由 执行搜索时,它将广播到所有索引/索引分片(副本之间的循环).可以通过提供routing参数来控制将搜索哪些分片.例如,在索引book时,路由值可以是nam ...

  6. ElasticSearch查询 第一篇:搜索API

    <ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...

  7. SpringBoot:elasticSearch 7.2.0 Java High Level REST Client 搜索 API

    Springboot整合最新版elasticSearch参考之前的文章:SpingBoot:整合ElasticSearch 7.2.0 Search API SearchRequest用于与搜索文档, ...

  8. Elasticsearch java api 基本搜索部分详解

    文档是结合几个博客整理出来的,内容大部分为转载内容.在使用过程中,对一些疑问点进行了整理与解析. Elasticsearch java api 基本搜索部分详解 ElasticSearch 常用的查询 ...

  9. ElasticSearch High Level REST API【5】使用模板搜索

    ElasticSearch Rest高级API 提供了多种搜索方式,除了前面讲到的search查询,ElasticSearch 还提供了通过模板搜索查询.我个人比较喜欢这种方式. 我们可以通过脚本预选 ...

随机推荐

  1. 【模板】一般图最大匹配(带花树算法)/洛谷P6113

    题目链接 https://www.luogu.com.cn/problem/P6113 题目大意 给定一个 \(n\) 个点 \(m\) 条边的无向图,求该图的最大匹配. 题目解析 二分图最大匹配,一 ...

  2. C语言中的重要位运算

    1. 常用的等式 :-n = ~(n-1) = ~n + 1. 2. 获取整数n的人进制形式中的最后1个,也就是只保留最后一个1,其余的全部置位0,如1000 0011 --->  0000 0 ...

  3. 学习java的第十二天

    一.今日收获(前两天家里有事,博客都忘了发了,唉) 1.通过看哔哩哔哩看黑马程序员的教学视频,学习了java中的数据类型自动转换.强制转换及注意事项三节 2.简单看了看完全学习手册 二.今日问题 1. ...

  4. 扩展kmp 学习笔记

    学习了一下这个较为冷门的知识,由于从日报开始看起,还是比较绕的-- 首先定义 \(Z\) 函数表示后缀 \(i\) 与整个串的 \(lcp\) 长度 一个比较好的理解于实现方式是类似于 \(manac ...

  5. Can we use function on left side of an expression in C and C++?

    In C, it might not be possible to have function names on left side of an expression, but it's possib ...

  6. 通信协议 HTTP TCP UDP

    TCP   HTTP   UDP: 都是通信协议,也就是通信时所遵守的规则,只有双方按照这个规则"说话",对方才能理解或为之服务. TCP   HTTP   UDP三者的关系: T ...

  7. Tomcat(1):安装Tomcat

    一,安装Tomcat服务器 1,下载tomcat网址: http://tomcat.apache.org/ 2,找到Download 3,下载 4:下载完成后,解压到任意目录 5:解压完成后得到目录 ...

  8. jQuery - 的几种删除方法,还有他们的区别

    1.empty() 清空节点,它能清空元素中的所有后代节点,不能删除自己本身这个节点 2.remove() 该节点与该节点所包含的所有后代节点将同时被删除,提供传递一个筛选的表达式,删除指定合集中的元 ...

  9. 最基础的SSM框架整合篇

    一.简单理解 Spring.Spring MVC和MyBatis的整合主要原理就是将我们在单独使用Spring MVC和MyBatis过程中需要自己实例化的类都交由Ioc容器来管理,过程分为两步: 第 ...

  10. Java基础语法与流程控制

    Java基础语法与流程控制 跟着狂神学Java的第二天O(∩_∩)O~,养成一个总结的习惯 志同道合的小伙伴可以一起学习狂神的视频 本节地址:https://www.kuangstudy.com/co ...