java api示例:
SearchRequestBuilder request = getTransportClient().prepareSearch(indexName).setTypes(type).setRouting(routing)     .setSearchType(SearchType.DFS_QUERY_THEN_FETCH).setPreference("_primary_first").setFrom(0).setSize(100).setQuery(queryBuilder);

分片查询优先级:
elasticsearch可以使用preference参数来指定分片查询的优先级,使用时就是在请求url上加上preference参数,如:http://ip:host/index/_search?preference=_primary
java的调用接口翻译为:client.prepareSearch(“index”).setPreference(“_primary”)。

1:randomizeacross shards
随机选择分片查询数据,es的默认方式

2:_local
优先在本地节点上的分片查询数据然后再去其他节点上的分片查询,本地节点没有IO问题但有可能造成负载不均问题。数据量是完整的。

3:_primary
只在主分片中查询不去副本查,一般数据完整。

4:_primary_first
优先在主分片中查,如果主分片挂了则去副本查,一般数据完整。

5:_only_node
只在指定id的节点中的分片中查询,数据可能不完整。

6:_prefer_node
优先在指定你给节点中查询,一般数据完整。

7:_shards
在指定分片中查询,数据可能不完整。

8:_only_nodes
可以自定义去指定的多个节点查询,es不提供此方式需要改源码。

   /*** 指定分片 查询*/@Testpublic void testPreference(){SearchResponse searchResponse = transportClient.prepareSearch(index).setTypes("add")//.setPreference("_local")//.setPreference("_primary")//.setPreference("_primary_first")//.setPreference("_only_node:ZYYWXGZCSkSL7QD0bDVxYA")//.setPreference("_prefer_node:ZYYWXGZCSkSL7QD0bDVxYA").setPreference("_shards:0,1,2").setQuery(QueryBuilders.matchAllQuery()).setExplain(true).get();SearchHits hits = searchResponse.getHits();System.out.println(hits.getTotalHits());SearchHit[] hits2 = hits.getHits();for(SearchHit h : hits2){System.out.println(h.getSourceAsString());}}

搜索类型SearchType:
参考:
https://www.cnblogs.com/donlianli/p/3857500.html
https://www.elastic.co/blog/understanding-query-then-fetch-vs-dfs-query-then-fetch
https://www.jianshu.com/p/c7529b98993e
https://blog.csdn.net/wangmaohong0717/article/details/53433146
https://blog.csdn.net/caipeichao2/article/details/46418413

es在查询时,可以指定搜索类型为
QUERY_THEN_FETCH,QUERY_AND_FEATCH,DFS_QUERY_THEN_FEATCH和DFS_QUERY_AND_FEATCH(SACN,COUNT都已不建议使用)。那么这4种搜索类型有什么区别?

elasticsearch java api中还有个default

public static final SearchType DEFAULT = QUERY_THEN_FETCH; 

分布式搜索背景介绍:
ES天生就是为分布式而生,但分布式有分布式的缺点。比如要搜索某个单词,但是数据却分别在5个分片(Shard)上面,这5个分片可能在5台主机上面。因为全文搜索天生就要排序(按照匹配度进行排名),但数据却在5个分片上,如何得到最后正确的排序呢?ES是这样做的,大概分两步。

step1. ES客户端会将这个搜索词同时向5个分片发起搜索请求,这叫Scatter,
step2. 这5个分片基于本Shard独立完成搜索,然后将符合条件的结果全部返回,这一步叫Gather。
客户端将返回的结果进行重新排序和排名,最后返回给用户。也就是说,ES的一次搜索,是一次scatter/gather过程(这个跟mapreduce也很类似).

然而这其中有两个问题:
第一、数量问题。比如,用户需要搜索”双黄连”,要求返回最符合条件的前10条。但在5个分片中,可能都存储着双黄连相关的数据。所以ES会向这5个分片都发出查询请求,并且要求每个分片都返回符合条件的10条记录。当ES得到返回的结果后,进行整体排序,然后取最符合条件的前10条返给用户。这种情况,ES5个shard最多会收到10*5=50条记录,这样返回给用户的结果数量会多于用户请求的数量。

第二、排名问题。上面搜索,每个分片计算分值都是基于自己的分片数据进行计算的。计算分值使用的词频率和其他信息都是基于自己的分片进行的,而ES进行整体排名是基于每个分片计算后的分值进行排序的,这就可能会导致排名不准确的问题。如果我们想更精确的控制排序,应该先将计算排序和排名相关的信息(词频率等)从5个分片收集上来,进行统一计算,然后使用整体的词频率去每个分片进行查询。

这两个问题,估计ES也没有什么较好的解决方法,最终把选择的权利交给用户,方法就是在搜索的时候指定query type。
1、query and fetch
向索引的所有分片(shard)都发出查询请求,各分片返回的时候把元素文档(document)和计算后的排名信息一起返回。这种搜索方式是最快的。因为相比下面的几种搜索方式,这种查询方法只需要去shard查询一次。但是各个shard返回的结果的数量之和可能是用户要求的size的n倍。

2、query then fetch(默认的搜索方式)
如果你搜索时,没有指定搜索方式,就是使用的这种搜索方式。这种搜索方式,大概分两个步骤,第一步,先向所有的shard发出请求,各分片只返回排序和排名相关的信息(注意,不包括文档document),然后按照各分片返回的分数进行重新排序和排名,取前size个文档。然后进行第二步,去相关的shard取document。这种方式返回的document可能是用户要求的size的n倍

3、DFS query and fetch
这种方式比第一种方式多了一个初始化散发(initial scatter)步骤,有这一步,据说可以更精确控制搜索打分和排名。这种方式返回的document与用户要求的size是相等的。

4、DFS query then fetch
比第2种方式多了一个初始化散发(initial scatter)步骤。这种方式返回的document与用户要求的size是相等的。

DSF是什么缩写?初始化散发是一个什么样的过程?
从es的官方网站我们可以指定,初始化散发其实就是在进行真正的查询之前,先把各个分片的词频率和文档频率收集一下,然后进行词搜索的时候,各分片依据全局的词频率和文档频率进行搜索和排名。显然如果使用DFS_QUERY_THEN_FETCH这种查询方式,效率是最低的,因为一个搜索,可能要请求3次分片。但,使用DFS方法,搜索精度应该是最高的。
至于DFS是什么缩写,没有找到相关资料,这个D可能是Distributed,F可能是frequency的缩写,至于S可能是Scatter的缩写,整个单词可能是分布式词频率和文档频率散发的缩写。
总结一下,从性能考虑QUERY_AND_FETCH是最快的,DFS_QUERY_THEN_FETCH是最慢的。从搜索的准确度来说,DFS要比非DFS的准确度更高。

query_and_fetch下的from和size:
举个例子,如果在搜索的时候指定search_type为query_and_fetch,再指定size为10,那么就会返回50个结果。这是为什么呢?原来,在fetch的时候就已经把from和size参数用掉了,导致每个分片都返回了10个文档,如果有5个分片的话,那么最后合并的结果就是50个。
如果query_and_fetch情况下这两和参数的作用和query_then_fetch的行为一样。那么一次就要取出from+size个文档。如果from比较大,那么取出的文档足以撑爆内存。而如果在fetch阶段就直接使用这两个参数,每个分片最多就取出size个文档,from稍微大一些也没有关系。因此,这种行为的设计也是可以理解的。

最后来看下源码:

public enum SearchType {/*** Same as {@link #QUERY_THEN_FETCH}, except for an initial scatter phase which goes and computes the distributed* term frequencies for more accurate scoring.*/DFS_QUERY_THEN_FETCH((byte) 0),/*** The query is executed against all shards, but only enough information is returned (not the document content).* The results are then sorted and ranked, and based on it, only the relevant shards are asked for the actual* document content. The return number of hits is exactly as specified in size, since they are the only ones that* are fetched. This is very handy when the index has a lot of shards (not replicas, shard id groups).*/QUERY_THEN_FETCH((byte) 1),/*** Same as {@link #QUERY_AND_FETCH}, except for an initial scatter phase which goes and computes the distributed* term frequencies for more accurate scoring.*/DFS_QUERY_AND_FETCH((byte) 2),/*** The most naive (and possibly fastest) implementation is to simply execute the query on all relevant shards* and return the results. Each shard returns size results. Since each shard already returns size hits, this* type actually returns size times number of shards results back to the caller.*/QUERY_AND_FETCH((byte) 3),/*** Performs scanning of the results which executes the search without any sorting.* It will automatically start scrolling the result set.* @deprecated will be removed in 3.0, you should do a regular scroll instead, ordered by `_doc`*/@DeprecatedSCAN((byte) 4),/*** Only counts the results, will still execute aggregations and the like.* @deprecated does not any improvements compared to {@link #QUERY_THEN_FETCH} with a `size` of {@code 0}*/@DeprecatedCOUNT((byte) 5);/*** The default search type ({@link #QUERY_THEN_FETCH}.*/

Elasticsearch查询相关参数相关推荐

  1. Elasticsearch查询相关总结以及timestamp和时区问题

    ES查询相关 参考:https://www.cnblogs.com/qdhxhz/p/11493677.html 如果想筛选出特定时间段的event,可以在查询语句里使用post_filter POS ...

  2. 【Elasticsearch】Elasticsearch查询参数batched_reduce_size的解释

    1.概述 当我们使用Elasticsearch查询数据时,如果数据量非常大时,会命中大量分片中的大量数据,可能会造成集群内存异常,此时可以通过一个高级参数batched_reduce_size进行控制 ...

  3. Go Elasticsearch 查询快速入门

    文章目录 0.前言 1.根据 ID 查询 2.精确匹配单个字段 3.精确匹配单个字段的多个值 4.全文查询 5.范围查询 6.判断某个字段是否存在 7.bool 组合查询 must filter sh ...

  4. Elasticsearch:Elasticsearch 查询示例 - 动手练习(一)

    在我之前的文章文章: Elasticsearch:有用的 Elasticsearch 查询示例 开始使用 Elasticsearch (2) 我列举了很多关于 Elasticsearch 查询的例子. ...

  5. Elasticsearch:Elasticsearch 查询示例 - 动手练习(二)

    这是继上一篇文章 "Elasticsearch:Elasticsearch 查询示例 - 动手练习(一)" 的续篇. Compound Queries 到目前为止,在本教程中,我们 ...

  6. ElasticSearch查询学习笔记章节5——geo_distance,geo_bounding_box,geo_polygon地图检索geo查询

    ElasticSearch查询笔记目录   涉及的常用查询内容较多,将分多个章节进行笔记整理,具体如下: ElasticSearch查询学习笔记章节1--term,terms,match,id查询   ...

  7. Linux TCP队列相关参数的总结

    作者:阿里技术保障锋寒 原文:https://yq.aliyun.com/articles/4252 摘要: 本文尝试总结TCP队列缓冲相关的内核参数,从协议栈的角度梳理它们,希望可以更容易的理解和记 ...

  8. MySQL8常见客户端和启动相关参数

    MySQL8常见客户端和启动相关参数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL常见的客户端 1>.使用MySQL服务自带的mysql连接工具 2>. ...

  9. es查询语句拼接 java_JAVA使用ElasticSearch查询in和not in的实现方式

    JAVA使用ElasticSearch查询in和not in的实现方式 发布时间:2020-08-22 16:03:11 来源:脚本之家 阅读:119 作者:执笔记忆的空白 ElasticSearch ...

最新文章

  1. AAAI 2021论文接收列表放出! 1692篇论文都在这儿了!
  2. java中怎样创建多个对象,java中StringBuilder.appent方法创建几个对象
  3. 串口使用stream_使用SerialPort库进行Node物联网项目开发
  4. java 同步的方法_关于Java中的同步方法
  5. Java hibernate假外键_JAVA基础:Hibernate外键关联与HQL语法
  6. 收集:Programer Jokes
  7. Echarts制作动态K线图和分时图
  8. BGP 自动路由聚合
  9. 服务器server怎么显示后缀名,window7系统怎么显示文件后缀名(图文)
  10. Qt QChartView class
  11. NGUI的长按事件以及检测按钮点击事件的常用方法
  12. 使用Eclipse搭建STM32嵌入式开发环境
  13. 行测资料分析之三角形权重图
  14. 中式装修之美,呈现出东方的诗意与唯美
  15. [因子背包] CF1647D Madoka and the Best School in Russia
  16. PyTorch入门: Kaggle 泰坦尼克幸存者预测
  17. Cocos Creator基础(十二) sp.Skeleton骨骼动画组件使用
  18. 零基础学习硬件安全技术
  19. 三零二计算机网络有限公司,计算机网络技术仿真试题第二套答案3
  20. 【硬刚大数据】企业级大数据平台建设参考 | 淘宝滴滴美团360快手京东

热门文章

  1. vue v-html scoped,基于vue中的scoped坑点解说
  2. 这个平台展示了如何使用AI预测股市走向
  3. AGV机器人是如何工作的
  4. 程序员如何在情人节脱单?
  5. Java 各种形状的面积与周长(继承)
  6. vue集成px2rem
  7. 传智播客 python 东哥_记录与传智播客的py交易(AI+python)
  8. AI落地步入深水区 , 旷视、依图、云从、商汤该学会赚钱了
  9. netbsd源码分析(1)
  10. 使用python发送邮件和企业微信