查询选择副本分片的倾向性(即在一个复制组中选择副本的分片值。默认状况下,es以未指定的顺序从可用的碎片副本中进行选择,副本之间的路由将在集群章节更加详细的介绍 。能够经过该字段指定分片倾向与选择哪一个副本。preference可选值:java
是否解释各分数是如何计算的。node
1GET /_search 2{ 3 "explain": true, 4 "query" : { 5 "term" : { "user" : "kimchy" } 6 } 7}
若是设置为true,则返回每一个命中文档的当前版本号。web
1GET /_search 2{ 3 "version": true, 4 "query" : { 5 "term" : { "user" : "kimchy" } 6 } 7}
当搜索多个索引时,容许为每一个索引配置不一样的boost级别。当来自一个索引的点击率比来自另外一个索引的点击率更重要时,该属性则很是方便。
使用示例以下:数组
1GET /_search 2{ 3 "indices_boost" : [ 4 { "alias1" : 1.4 }, 5 { "index*" : 1.3 } 6 ] 7}
指定返回文档的最小评分,若是文档的评分低于该值,则不返回。微信
1GET /_search 2{ 3 "min_score": 0.5, 4 "query" : { 5 "term" : { "user" : "kimchy" } 6 } 7}
每一个过滤器和查询均可以在其顶级定义中接受_name。搜索响应中每一个匹配文档中会增长matched_queries结构体,记录该文档匹配的查询名称。查询和筛选器的标记只对bool查询有意义。
java示例以下:session
1public static void testNamesQuery() { 2 RestHighLevelClient client = EsClient.getClient(); 3 try { 4 SearchRequest searchRequest = new SearchRequest(); 5 searchRequest.indices("esdemo"); 6 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 7 sourceBuilder.query( 8 QueryBuilders.boolQuery() 9 .should(QueryBuilders.termQuery("context", "fox").queryName("q1")) 10 .should(QueryBuilders.termQuery("context", "brown").queryName("q2")) 11 ); 12 searchRequest.source(sourceBuilder); 13 SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT); 14 System.out.println(result); 15 } catch (Throwable e) { 16 e.printStackTrace(); 17 } finally { 18 EsClient.close(client); 19 } 20 }
返回结果以下:app
1{ 10 "hits":{ 19 "_source":{ 20 "context":"My quick brown as fox eats rabbits on a regular basis.", 21 "title":"Keeping pets healthy" 22 }, 23 "matched_queries":[ 24 "q1", 25 "q2" 26 ] 27 } 41 ] 42 } 43}
正如上面所说,每一个匹配文档中都包含matched_queries,代表该文档匹配的是哪一个查询条件。运维
用于定义内部嵌套层的返回规则,其inner hits支持以下选项:elasticsearch
容许根据字段值折叠搜索结果。折叠是经过在每一个折叠键上只选择排序最高的文档来完成的。有点相似于聚合分组,其效果相似于按字段进行分组,默认命中的文档列表第一层由该字段的第一条信息,也能够经过容许根据字段值折叠搜索结果。折叠是经过在每一个折叠键上只选择排序最高的文档来完成的。例以下面的查询为每一个用户检索最佳twee-t,并按喜欢的数量对它们进行排序。
下面首先经过示例进行展现field colla-psing的使用。
1)首先查询发的推特内容中包含elast-icsearch的推文:ide
1GET /twitter/_search 2{ 3 "query": { 4 "match": { 5 "message": "elasticsearch" 6 } 7 }, 8 "collapse" : { 9 "field" : "user" 10 }, 11 "sort": ["likes"] 12}
返回结果:
1{ 13 "hits":[ 14 { 15 "_index":"mapping_field_collapsing_twitter", 16 "_type":"_doc", 17 "_id":"OYnecmcB-IBeb8B-bF2X", 18 "_score":null, 19 "_source":{ 20 "message":"to be a elasticsearch", 21 "user":"user2", 22 "likes":3 23 }, 24 "sort":[ 25 3 26 ] 27 }, 84 ] 85 } 86}
首先上述会列出全部用户的推特,若是只想每一个用户只显示一条推文,而且点赞率最高,或者每一个用户只显示2条推文呢?这个时候,按字段折叠就闪亮登场了。java demo以下:
1public static void search_field_collapsing() { 2 RestHighLevelClient client = EsClient.getClient(); 3 try { 4 SearchRequest searchRequest = new SearchRequest(); 5 searchRequest.indices("mapping_field_collapsing_twitter"); 6 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 7 sourceBuilder.query( 8 QueryBuilders.matchQuery("message","elasticsearch") 9 ); 10 sourceBuilder.sort("likes", SortOrder.DESC); 11 CollapseBuilder collapseBuilder = new CollapseBuilder("user"); 12 sourceBuilder.collapse(collapseBuilder); 13 searchRequest.source(sourceBuilder); 14 SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT); 15 System.out.println(result); 16 } catch (Throwable e) { 17 e.printStackTrace(); 18 } finally { 19 EsClient.close(client); 20 } 21 }
其结果以下:
1{ 10 "hits":{ 11 13 "hits":[ 14 { 15 "_index":"mapping_field_collapsing_twitter", 16 "_type":"_doc", 17 "_id":"OYnecmcB-IBeb8B-bF2X", 18 "_score":null, 19 "_source":{ 20 "message":"to be a elasticsearch", 21 "user":"user2", 22 "likes":3 23 }, 24 "fields":{ 25 "user":[ 26 "user2" 27 ] 28 }, 29 "sort":[ 30 3 31 ] 32 }, 33 { 34 "_index":"mapping_field_collapsing_twitter", 35 "_type":"_doc", 36 "_id":"OInecmcB-IBeb8B-bF2G", 37 "_score":null, 38 "_source":{ 39 "message":"elasticsearch is very high", 40 "user":"user1", 41 "likes":3 42 }, 43 "fields":{ 44 "user":[ 45 "user1" 46 ] 47 }, 48 "sort":[ 49 3 50 ] 51 } 52 ] 53 } 54}
上面的示例只返回了每一个用户的第一条数据,若是须要每一个用户返回2条数据呢?能够经过inner_hit来设置。
1public static void search_field_collapsing() { 2 RestHighLevelClient client = EsClient.getClient(); 3 try { 4 SearchRequest searchRequest = new SearchRequest(); 5 searchRequest.indices("mapping_field_collapsing_twitter"); 6 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 7 sourceBuilder.query( 8 QueryBuilders.matchQuery("message","elasticsearch") 9 ); 10 sourceBuilder.sort("likes", SortOrder.DESC); 11 CollapseBuilder collapseBuilder = new CollapseBuilder("user"); 12 13 InnerHitBuilder collapseHitBuilder = new InnerHitBuilder("collapse_inner_hit"); 14 collapseHitBuilder.setSize(2); 15 collapseBuilder.setInnerHits(collapseHitBuilder); 16 sourceBuilder.collapse(collapseBuilder); 17 18 searchRequest.source(sourceBuilder); 19 SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT); 20 System.out.println(result); 21 } catch (Throwable e) { 22 e.printStackTrace(); 23 } finally { 24 EsClient.close(client); 25 } 26 }
返回结果以下:
1{ 2 "took":42, 3 "timed_out":false, 4 "_shards":{ 5 "total":5, 6 "successful":5, 7 "skipped":0, 8 "failed":0 9 }, 10 "hits":{ 11 "total":5, 12 "max_score":null, 13 "hits":[ 14 { 15 "_index":"mapping_field_collapsing_twitter", 16 "_type":"_doc", 17 "_id":"OYnecmcB-IBeb8B-bF2X", 18 "_score":null, 19 "_source":{ 20 "message":"to be a elasticsearch", 21 "user":"user2", 22 "likes":3 23 }, 24 "fields":{ 25 "user":[ 26 "user2" 27 ] 28 }, 29 "sort":[ 30 3 31 ], 32 "inner_hits":{ 33 "collapse_inner_hit":{ 34 "hits":{ 35 "total":2, 36 "max_score":0.19363807, 37 "hits":[ 38 { 39 "_index":"mapping_field_collapsing_twitter", 40 "_type":"_doc", 41 "_id":"OonecmcB-IBeb8B-bF2q", 42 "_score":0.19363807, 43 "_source":{ 44 "message":"to be elasticsearch", 45 "user":"user2", 46 "likes":3 47 } 48 }, 49 { 50 "_index":"mapping_field_collapsing_twitter", 51 "_type":"_doc", 52 "_id":"OYnecmcB-IBeb8B-bF2X", 53 "_score":0.17225473, 54 "_source":{ 55 "message":"to be a elasticsearch", 56 "user":"user2", 57 "likes":3 58 } 59 } 60 ] 61 } 62 } 63 } 64 }, 65 { 66 "_index":"mapping_field_collapsing_twitter", 67 "_type":"_doc", 68 "_id":"OInecmcB-IBeb8B-bF2G", 69 "_score":null, 70 "_source":{ 71 "message":"elasticsearch is very high", 72 "user":"user1", 73 "likes":3 74 }, 75 "fields":{ 76 "user":[ 77 "user1" 78 ] 79 }, 80 "sort":[ 81 3 82 ], 83 "inner_hits":{ 84 "collapse_inner_hit":{ 85 "hits":{ 86 "total":3, 87 "max_score":0.2876821, 88 "hits":[ 89 { 90 "_index":"mapping_field_collapsing_twitter", 91 "_type":"_doc", 92 "_id":"O4njcmcB-IBeb8B-Rl2H", 93 "_score":0.2876821, 94 "_source":{ 95 "message":"elasticsearch is high db", 96 "user":"user1", 97 "likes":1 98 } 99 }, 100 { 101 "_index":"mapping_field_collapsing_twitter", 102 "_type":"_doc", 103 "_id":"N4necmcB-IBeb8B-bF0n", 104 "_score":0.2876821, 105 "_source":{ 106 "message":"very likes elasticsearch", 107 "user":"user1", 108 "likes":1 109 } 110 } 111 ] 112 } 113 } 114 } 115 } 116 ] 117 } 118}
此时,返回结果是两级,第一级,仍是每一个用户第一条消息,而后再内部中嵌套inner_hits。
Elasticsearch支持的第三种分页获取方式,该方法不支持跳转页面。
es支持的分页方式目前已知:
1public static void search_search_after() { 2 RestHighLevelClient client = EsClient.getClient(); 3 try { 4 SearchRequest searchRequest = new SearchRequest(); 5 searchRequest.indices("mapping_search_after"); 6 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 7 sourceBuilder.query( 8 QueryBuilders.termQuery("user","user2") 9 ); 10 sourceBuilder.size(1); 11 sourceBuilder.sort("id", SortOrder.ASC); 12 searchRequest.source(sourceBuilder); 13 SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT); 14 System.out.println(result); 15 if(hasHit(result)) { // 若是本次匹配到数据 16 // 省略处理数据逻辑 17 // 继续下一批查询 18 // result.getHits(). 19 int length = result.getHits().getHits().length; 20 SearchHit aLastHit = result.getHits().getHits()[length - 1]; 21 //开始下一轮查询 22 sourceBuilder.searchAfter(aLastHit.getSortValues()); 23 result = client.search(searchRequest, RequestOptions.DEFAULT); 24 System.out.println(result); 25 } 26 } catch (Throwable e) { 27 e.printStackTrace(); 28 } finally { 29 EsClient.close(client); 30 } 31 } 32 private static boolean hasHit(SearchResponse result) { 33 return !( result.getHits() == null || 34 result.getHits().getHits() == null || 35 result.getHits().getHits().length < 1 ); 36 }
更多文章请关注微信公众号:
广告:做者新书《RocketMQ技术内幕》已上市《RocketMQ技术内幕》已出版上市,目前可在主流购物平台(京东、天猫等)购买,本书从源码角度深度分析了RocketMQ NameServer、消息发送、消息存储、消息消费、消息过滤、主从同步HA、事务消息;在实战篇重点介绍了RocketMQ运维管理界面与当前支持的39个运维命令;并在附录部分罗列了RocketMQ几乎全部的配置参数。本书获得了RocketMQ创始人、阿里巴巴Messaging开源技术负责人、Linux OpenMessaging 主席的高度承认并做序推荐。目前是国内第一本成体系剖析RocketMQ的书籍。