RestHighLevelClient查詢es

 本篇分享的是es官網推薦的es客戶端組件RestHighLevelClient的使用,其封裝了操做es的crud方法,底層原理就是模擬各類es須要的請求,如put,delete,get等方式;本篇主要分享經常使用查詢,但願能給你們帶來好的幫助;html

  • 分頁查詢
  • 條件查詢java

    1. 文本模糊匹配
    2. 時間範圍匹配
  • 超時設置sql

    1. es超時時間
    2. RestHighLevelClient發送請求的http響應超時時間
  • 排序
  • 指定返回列
  • 模擬一個post獲取es數據

準備工做

本人es服務端的版本是5.6.x,所以RestHighLevelClient建議一樣引入相同主版本的包,相關參考文檔(link):json

 1         <dependency>
 2             <groupId>org.elasticsearch.client</groupId>
 3             <artifactId>elasticsearch-rest-high-level-client</artifactId>
 4             <version>5.6.16</version>
 5         </dependency>
 6 
 7         <dependency>
 8             <groupId>com.alibaba</groupId>
 9             <artifactId>fastjson</artifactId>
10             <version>1.2.56</version>
11             <scope>compile</scope>
12         </dependency>

做爲客戶端來講,咱們須要知道es服務的ip:端口,以此來鏈接到服務端,對於es來講鏈接服務端其實就是往這個ip:端口上發送各類格式請求參數,以下建立個restclient:elasticsearch

1     public RestHighLevelClient client() {
2         Assert.requireNonEmpty(this.hosts, "無效的es鏈接");
3         return new RestHighLevelClient(
4                 RestClient.builder(this.hosts).build()
5         );
6     }

分頁查詢

做爲客戶端來講resthighlevelclient的查詢操做及其簡單,只須要以下簡短代碼便可操做查詢:分佈式

 1             SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
 2             SearchRequest rq = new SearchRequest();
 3             //索引
 4             rq.indices(index);
 5             //各類組合條件
 6             rq.source(sourceBuilder);
 7 
 8             //請求
 9             System.out.println(rq.source().toString());
10             SearchResponse rp = client().search(rq);

如上模板咱們知道要完成一次查詢,須要知道對應的索引和各類業務查詢條件;索引是必須的,至於條件這裏先來分頁吧,能夠經過以下方式設置頁碼:ide

1             from = from <= -1 ? 0 : from;
2             size = size >= 1000 ? 1000 : size;
3             size = size <= 0 ? 15 : size;
4             //其實位置
5             sourceBuilder.from(from);
6             //每頁數量
7             sourceBuilder.size(size);

條件查詢

對於查詢來講一般都有各類and和or的條件,能夠經過SearchSourceBuilder的must和should來設置and和or關係,這裏用到了must;post

1.文本模糊匹配
對於es關鍵字或單詞的查詢咱們能夠藉助QueryBuilders.wildcardQuery方法來操做,只須要指定es中對應的列和要查詢的內容便可:fetch

1             //模糊匹配
2             boolQueryBuilder.must(QueryBuilders.wildcardQuery(k, v.toString()));

2.時間範圍匹配
相對時間條件來講,一般的需求都是按照範圍來查詢的,這裏能夠藉助QueryBuilders.rangeQuery指定es中某列(k)的範圍匹配:ui

1    boolQueryBuilder.must(
2                         QueryBuilders.rangeQuery(k).
3                                 gte(format.format(mapV.get("start"))).
4                                 lt(format.format(mapV.get("end"))));

超時設置

使用RestHighLevelClient做爲查詢端,須要注意的超時時間有兩種:es自己須要的時間和Rest發送http的響應時間

1.es超時時間
對於es服務端來講每每須要設置一下查詢超時時間,儘管es是分佈式查詢較快並創建在多個lucence基礎上聚合的查詢,也須要設置超時時間,避免因爲數據量過大或集羣過大致使查詢緩慢問題;

1     sourceBuilder.timeout(new TimeValue(timeOut, TimeUnit.SECONDS));

2.RestHighLevelClient發送請求的http響應超時時間
對應http來講每每會有一個響應的時長,超過期長後將不能再獲取到數據,RestHighLevelClient做爲以http方式請求es客戶端這點須要注意;好比es查詢須要10s,可是http設置了5s,數據就沒法正常返回;

1         return new RestHighLevelClient(
2                 RestClient.builder(this.hosts).
3                         setMaxRetryTimeoutMillis(60 * 1000).  //設置http客戶請求時長
4                         build()
5         );

排序

排序在業務中也是經常使用,es提供了默認排序和自定義排序,默認排序一般都是_score來排的,以下參數:

若是自定義列來排序,能夠經過以下方式:

1       sourceBuilder.sort(new FieldSortBuilder(k).order(v ? SortOrder.ASC : SortOrder.DESC));

指定返回列

對應查詢一般會指定一些返回列,就sql查詢來講select *一般都比select cols要慢,一個緣由是數據量少了有可能走了索引;es其實也一樣,指定返回列可減小返回數據體量;

1             //返回和排除列
2             if (!CollectionUtils.isEmpty(includeFields) || !CollectionUtils.isEmpty(excludeFields)) {
3                 sourceBuilder.fetchSource(includeFields, excludeFields);
4             }

模擬一個post獲取es數據

如上就是查詢es經常使用一些參數說明,配置及心得;下面給出完整的示例代碼:

 1   /**
 2      * @param index
 3      * @param from
 4      * @param size
 5      * @param where
 6      * @param sortFieldsToAsc
 7      * @param includeFields
 8      * @param excludeFields
 9      * @param timeOut
10      * @return
11      */
12     public List<Map<String, Object>> searchIndex(String index, int from, int size, Map<String, Object> where,
13                                                  Map<String, Boolean> sortFieldsToAsc, String[] includeFields, String[] excludeFields,
14                                                  int timeOut) {
15         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
16         try {
17             SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
18             //條件
19             if (where != null && !where.isEmpty()) {
20                 BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
21                 where.forEach((k, v) -> {
22                     if (v instanceof Map) {
23                         //範圍選擇map  暫定時間
24                         Map<String, Date> mapV = (Map<String, Date>) v;
25                         if (mapV != null) {
26                             boolQueryBuilder.must(
27                                     QueryBuilders.rangeQuery(k).
28                                             gte(format.format(mapV.get("start"))).
29                                             lt(format.format(mapV.get("end"))));
30                         }
31                     } else {
32                         //普通模糊匹配
33                         boolQueryBuilder.must(QueryBuilders.wildcardQuery(k, v.toString()));
34                     }
35                 });
36                 sourceBuilder.query(boolQueryBuilder);
37             }
38 
39             //分頁
40             from = from <= -1 ? 0 : from;
41             size = size >= 1000 ? 1000 : size;
42             size = size <= 0 ? 15 : size;
43             sourceBuilder.from(from);
44             sourceBuilder.size(size);
45 
46             //超時
47             sourceBuilder.timeout(new TimeValue(timeOut, TimeUnit.SECONDS));
48 
49             //排序
50             if (sortFieldsToAsc != null && !sortFieldsToAsc.isEmpty()) {
51                 sortFieldsToAsc.forEach((k, v) -> {
52                     sourceBuilder.sort(new FieldSortBuilder(k).order(v ? SortOrder.ASC : SortOrder.DESC));
53                 });
54             } else {
55                 sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));
56             }
57 
58             //返回和排除列
59             if (!CollectionUtils.isEmpty(includeFields) || !CollectionUtils.isEmpty(excludeFields)) {
60                 sourceBuilder.fetchSource(includeFields, excludeFields);
61             }
62 
63             SearchRequest rq = new SearchRequest();
64             //索引
65             rq.indices(index);
66             //各類組合條件
67             rq.source(sourceBuilder);
68 
69             //請求
70             System.out.println(rq.source().toString());
71             SearchResponse rp = client().search(rq);
72 
73             //解析返回
74             if (rp.status() != RestStatus.OK || rp.getHits().getTotalHits() <= 0) {
75                 return Collections.emptyList();
76             }
77 
78             //獲取source
79             return Arrays.stream(rp.getHits().getHits()).map(b -> {
80                 return b.getSourceAsMap();
81             }).collect(Collectors.toList());
82 
83         } catch (Exception ex) {
84             ex.printStackTrace();
85         }
86         return Collections.emptyList();
87     }

分享經過RestClient方式往es發送的請求參數以及模擬post方式發送參數獲取es數據:

 1 {
 2   "from" : 0,
 3   "size" : 5,
 4   "timeout" : "60s",
 5   "query" : {
 6     "bool" : {
 7       "must" : [
 8         {
 9           "range" : {
10             "timeStamp" : {
11               "from" : "2019-05-23T19:17:59.000+0800",
12               "to" : "2019-05-23T19:18:00.000+0800",
13               "include_lower" : true,
14               "include_upper" : false,
15               "boost" : 1.0
16             }
17           }
18         },
19         {
20           "wildcard" : {
21             "data" : {
22               "wildcard" : "",
23               "boost" : 1.0
24             }
25           }
26         }
27       ],
28       "disable_coord" : false,
29       "adjust_pure_negative" : true,
30       "boost" : 1.0
31     }
32   },
33   "_source" : {
34     "includes" : [ ],
35     "excludes" : [
36       "serverIp"
37     ]
38   },
39   "sort" : [
40     {
41       "timeStamp" : {
42         "order" : "desc"
43       }
44     }
45   ]
46 }

有了上面參數,咱們徹底能夠經過postman直接發post給es服務端,讓其返回響應的數據而;resthighlevelclient做爲http客戶端就是幫咱們完成了這部分封裝:

相關文章
相關標籤/搜索