查詢選擇副本分片的傾向性(即在一個複製組中選擇副本的分片值。默認狀況下,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的書籍。