Elasticsearch 搜索类型
当我们在使用es时,多多少少会用到分页,因为es数据量往往是庞大的,如果一次性取出所有的数据的话接口的响应时间要比想象中的要慢的多。如果你在开发时也遇到了这样的问题 ,单次返回量巨大而且接口的响应时间没有达到自己的预期,不妨看看我下面的操作。
在开始之前,我们先介绍一下es:
es天生就是为分布式而生的,分布式的好处我们就不提了,相信大家都懂得,我们来说说它的缺点,众所周知es将数据存储在分片上, 而每个分片都有一个自己的一个备份分片,备份分片的作用是当主分片不能用时,可以立马替代主分片工作。我们来看一下这个场景,比如我们要所有一个单词 hello,但是这个单词呢却分别在5个分片中。如果我们要搜索出现hello这个单词的前五个地方,es会怎么做吗?大致上会分为两步:
第一步:es会向五个分片发起搜索hello这个单词的搜索请求,五个分片会根据请求返回数据,因为请求的是前五个带hello的数据,所以每个分片都返回了五个数据。
第二步:es的客户端拿到了25个数据,由于用户要的是五个数据,所以es客户端对25个数据进行了重新排序,取出最符合的条件的五个数据来进行返回。
完成这上面两个步骤会产生两个问题,问题一、数量问题,这个问题是在第一步暴露出来的问题,你可能会发现客户端实际收到的数据量远远大于预期的数量,这不得不让客户端进行重新排序。说到了排序就引出来第二个问题,es对每个数据都有一个打分机制,而每个分片是独立执行,所以在做上诉搜索时,每个分片的计算分值都是基于自己所在分片来进行的计算,如果我们想要获取到准确的排名,就需要将五个分片的数据全部搜集上来然后进行统一排序。
这里我们可以通过设置es的query type来提高对应的性能问题。
-
query and fetch
向索引的所有分片都发出查询请求,然后各分片会将元素文档和计算后的排名一起返回。这种搜索方式是最快的。相对于下面的几种查询方式,这种查询方式只需要一次查询即可完成所有的操作,但是有个缺点就是返回的数据量不够精准。如果你希望快速的拿出所有的数据, 不考虑排名的话,建议使用的这个搜索项,同时搭配使用游标可以大大提升你查询速度。
-
query then fetch(es 默认的搜索方式)
es 客户端会默认使用这种搜索方式来进行数据的检索,这种搜索方式相对于上面那种搜索方式比较麻烦一点,具体的操作如下:
第一步:向所有的分片发出请求,各分片返回文档的id和排名相关的信息,然后按照各分片的返回的文档分数进行重新排序和排名,取出你想要的数量。
第二步:根据文档ID去相关的分片取出对应的文档。
这种方式可以取出与要求的一直的数据量,但是性能一般
-
DFS query and fetch
这种方式比第一种方式多了一个DFS步骤,有这一步,可以更精确控制搜索打分和排名。也就是在进行查询之前,先对所有分片发送请求,把所有分片中的词频和文档频率等打分依据汇总到一块,再执行后面的操作。 相对于第一种方式来讲数据排名更准确,但是性能不如第一种快,同样数据量也是不准确的。
-
DFS query then fetch
同样这种方式是比第二种方式多了一个DFS的步骤,其他的和第二种是一模一样的,这种方式不推荐使用,它是四种方式种最慢的一个。
总结
如果需要特别高性能的查询效率,建议使用第一种, 如果要求搜索的准确度比较高,那DFS 要比非DFS准确度要高的多。