日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Elasticsearch学习4《Elasticsearch的各种查询》

發布時間:2023/12/18 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Elasticsearch学习4《Elasticsearch的各种查询》 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、term 和terms 查詢
    • 1、term 查詢
    • 2、terms查詢
  • 二、 match查詢
    • 1、math_all
    • 2、match 查詢
    • 3、布爾match 查詢
    • 4、multi_match
  • 三、其他查詢
    • 1、id 查詢
    • 2、ids查詢
    • 3、prefix 查詢
    • 4、 fuzzy 查詢
    • 5、wildcard 查詢
    • 6、rang 查詢
    • 8、 regexp 查詢
  • 四、深分頁 scroll
  • 五、delete-by-query
  • 六、復合查詢
    • boosting 查詢
  • 七、filter 查詢
  • 八、高亮查詢
  • 九、聚合查詢
    • 1、去重計數聚合查詢
    • 2、范圍統計
    • 3、統計聚合
    • 4、其他聚合查詢 查看官方文檔
  • 十、 地圖經緯度搜索
    • 1、ES 的地圖檢索方式
    • 2、基于RESTFul 實現地圖檢索
    • 3、 java 實現 geo_polygon

一、term 和terms 查詢

1、term 查詢

term 查詢是代表完全匹配,搜索之前不會對你搜索的關鍵字進行分詞,直接拿 關鍵字 去文檔分詞庫中匹配內容 #term查詢 POST /sms-logs-index/sms-logs-type/_search {#limit ?"from": 0, #limit x,?"size":5,"query": {"term": {"province": {"value": "北京"}}} } public class TermSearch {ObjectMapper mapper = new ObjectMapper();RestHighLevelClient client = EsClient.getClient();String index = "sms-logs-index";String type="sms-logs-type";@Testpublic void termSearchTest() throws IOException {// 1.創建request對象SearchRequest request = new SearchRequest(index);request.types(type);// 2.創建查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();builder.from(0);builder.size(5);builder.query(QueryBuilders.termQuery("province","北京"));request.source(builder);// 3.執行查詢SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.輸出查詢結果for (SearchHit hit : response.getHits().getHits()) {Map<String, Object> sourceAsMap = hit.getSourceAsMap();System.out.println(sourceAsMap);}} }

2、terms查詢

  • terms 和 term 查詢的機制一樣,搜索之前不會對你搜索的關鍵字進行分詞,直接拿 關鍵字 去文檔分詞庫中匹配內容
  • terms: 是針對一個字段包含多個值
  • term : where province = 北京
  • terms: where province = 北京 or province =? (類似于mysql 中的 in)
    也可針對 text, 只是在分詞庫中查詢的時候不會進行分詞
#terms 查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"terms": {"province": ["北京","晉城"]}} } public class TermSearch {ObjectMapper mapper = new ObjectMapper();RestHighLevelClient client = EsClient.getClient();String index = "sms-logs-index";String type="sms-logs-type";@Testpublic void termsSearchTest() throws IOException {// 1.創建request對象SearchRequest request = new SearchRequest(index);request.types(type);// 2.創建查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();builder.query(QueryBuilders.termsQuery("province","北京","晉城"));request.source(builder);// 3.執行查詢SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 輸出查詢結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}} }

二、 match查詢

match 查詢屬于高級查詢,會根據你查詢字段的類型不一樣,采用不同的查詢方式

  • 查詢的是日期或者數值,他會將你基于字符串的查詢內容轉換為日期或數值對待
  • 如果查詢的內容是一個不能被分詞的內容(keyword),match 不會將你指定的關鍵字進行分詞
  • 如果查詢的內容是一個可以被分詞的內容(text),match 查詢會將你指定的內容根據一定的方式進行分詞,去分詞庫中匹配指定的內容

match 查詢,實際底層就是多個term 查詢,將多個term查詢的結果給你封裝到一起

1、math_all

查詢全部內容,不指定查詢條件

#match_all 查詢 POST /sms-logs-index/sms-logs-type/_search {"query":{"match_all": {}} } public class MatchSearch {ObjectMapper mapper = new ObjectMapper();RestHighLevelClient client = EsClient.getClient();String index = "sms-logs-index";String type="sms-logs-type";@Testpublic void matchAllSearch() throws IOException {// 1.創建request對象SearchRequest request = new SearchRequest(index);request.types(type);// 2.創建查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();builder.query(QueryBuilders.matchAllQuery());// ES 默認只查詢10條數據builder.size(20);request.source(builder);// 3.執行查詢SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.輸出查詢結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}System.out.println(response.getHits().getHits().length);} }

2、match 查詢

指定一個field 作為查詢條件

#match 查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"match": {"smsContent": "偉大戰士"}} } public class MatchSearch {ObjectMapper mapper = new ObjectMapper();RestHighLevelClient client = EsClient.getClient();String index = "sms-logs-index";String type="sms-logs-type";@Testpublic void matchSearch() throws IOException {// 1.創建request對象SearchRequest request = new SearchRequest(index);request.types(type);// 2.創建查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();//--------------------------------------------------------------builder.query(QueryBuilders.matchQuery("smsContent","偉大戰士"));//--------------------------------------------------------------builder.size(20);request.source(builder);// 3.執行查詢SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.輸出查詢結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}System.out.println(response.getHits().getHits().length);}}

3、布爾match 查詢

基于一個field 匹配的內容,按照 and 或者or的方式連接

#布爾match查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"match": {"smsContent": {# 既包含 戰士 也包含 團隊"query": "戰士 團隊","operator": "and"}}} }#布爾match查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"match": {"smsContent": {# 既包含 戰士 或者 團隊"query": "戰士 團隊","operator": "or"}}} } @Testpublic void booleanMatchSearch() throws IOException {// 1.創建request對象SearchRequest request = new SearchRequest(index);request.types(type);// 2.創建查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();//--------------------------------------------------------------builder.query(QueryBuilders.matchQuery("smsContent","戰士 團隊").operator(Operator.AND));//--------------------------------------------------------------builder.size(20);request.source(builder);// 3.執行查詢SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.輸出查詢結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}System.out.println(response.getHits().getHits().length);}

4、multi_match

match 針對一個field 做檢索,multi_math 針對多個field 進行檢索,多個field對應一個文本。

#multi_math 查詢 POST /sms-logs-index/sms-logs-type/_search {"query":{"multi_match": {"query": "北京","fields": ["province","smsContent"]}} } public void multiMatchSearch() throws IOException {// 1.創建request對象SearchRequest request = new SearchRequest(index);request.types(type);// 2.創建查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();//--------------------------------------------------------------builder.query(QueryBuilders.multiMatchQuery("北京","province","smsContent"));//--------------------------------------------------------------builder.size(20);request.source(builder);// 3.執行查詢SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.輸出查詢結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}System.out.println(response.getHits().getHits().length);}

三、其他查詢

1、id 查詢

#id 查詢 GET /sms-logs-index/sms-logs-type/1 public class IdGetSearch {ObjectMapper mapper = new ObjectMapper();RestHighLevelClient client = EsClient.getClient();String index = "sms-logs-index";String type="sms-logs-type";@Testpublic void findById() throws IOException {// 創建GetRequest對象GetRequest request = new GetRequest(index,type,"1");// 執行查詢GetResponse response = client.get(request, RequestOptions.DEFAULT);// 輸出結果System.out.println(response.getSourceAsMap());} }

2、ids查詢

根據多個id 查詢,類似 mysql 中的 where in (id1,id2…)

#ids 查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"ids": {"values": ["1","2","3"]}} } public void findByIds() throws IOException {// 創建request對象SearchRequest request = new SearchRequest(index);request.types(type);// 指定查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();//--------------------------------------------------builder.query(QueryBuilders.idsQuery().addIds("1","2","3"));//------------------------------------------------------request.source(builder);// 執行SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 輸出結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}}

3、prefix 查詢

前綴查詢,可以通過一個關鍵字去指定一個field 的前綴,從而查詢到指定文檔

#prefix 查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"prefix": {"corpName": {"value": "海"}}} } #match 查詢 在這里是什么都查不到的 和上邊的prefix 做比較 POST /sms-logs-index/sms-logs-type/_search {"query": {"match": {"corpName": "海"}} } public void findByPrefix() throws IOException {// 創建request對象SearchRequest request = new SearchRequest(index);request.types(type);// 指定查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();//--------------------------------------------------builder.query(QueryBuilders.prefixQuery("corpName","阿"));//------------------------------------------------------request.source(builder);// 執行SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 輸出結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}}

4、 fuzzy 查詢

模糊查詢,我們可以輸入一個字符的大概,ES 可以根據輸入的大概去匹配內容。查詢結果不穩定

#fuzzy 查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"fuzzy": {"corpName": {"value": "騰訊客堂",#指定前邊幾個字符是不允許出現錯誤的"prefix_length": 2}}} } public void findByFuzzy() throws IOException {// 創建request對象SearchRequest request = new SearchRequest(index);request.types(type);// 指定查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();//--------------------------------------------------builder.query(QueryBuilders.fuzzyQuery("corpName","騰訊客堂").prefixLength(2));//------------------------------------------------------request.source(builder);// 執行SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 輸出結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}}

5、wildcard 查詢

通配查詢,同mysql中的like 是一樣的,可以在查詢時,在字符串中指定通配符*和占位符?

#wildcard 查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"wildcard": {"corpName": {"value": "海爾*"}}} }#wildcard 查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"wildcard": {"corpName": {"value": "海爾??"}}} } public void findByWildCard() throws IOException {// 創建request對象SearchRequest request = new SearchRequest(index);request.types(type);// 指定查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();//--------------------------------------------------builder.query(QueryBuilders.wildcardQuery("corpName","海爾*"));//------------------------------------------------------request.source(builder);// 執行SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 輸出結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}}

6、rang 查詢

范圍查詢,只針對數值類型,對一個field 進行大于或者小于的范圍指定

#rang 查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"range": {"fee": {"gte": 10,"lte": 20}}} } public void findByRang() throws IOException {// 創建request對象SearchRequest request = new SearchRequest(index);request.types(type);// 指定查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();//--------------------------------------------------builder.query(QueryBuilders.rangeQuery("fee").gt(10).lte(30));//------------------------------------------------------request.source(builder);// 執行SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 輸出結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}}

8、 regexp 查詢

正則查詢,通過你編寫的正則表達式去匹配內容
Ps:prefix wildcard fuzzy 和regexp 查詢效率比較低 ,在要求效率比較高時,避免使用

#regexp 查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"regexp": {"mobile": "138[0-9]{8}"}} } public void findByRegexp() throws IOException {// 創建request對象SearchRequest request = new SearchRequest(index);request.types(type);// 指定查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();//--------------------------------------------------builder.query(QueryBuilders.regexpQuery("mobile","138[0-9]{8}"));//------------------------------------------------------request.source(builder);// 執行SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 輸出結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());} }

四、深分頁 scroll

ES 對from +size時又限制的,from +size 之和 不能大于1W,超過后 效率會十分低下
原理:
from+size ES查詢數據的方式,
第一步將用戶指定的關鍵詞進行分詞,
第二部將詞匯去分詞庫中進行檢索,得到多個文檔id,
第三步去各個分片中拉去數據, 耗時相對較長
第四步根據score 將數據進行排序, 耗時相對較長
第五步根據from 和size 的值 將部分數據舍棄,
第六步,返回結果。

scroll +size ES 查詢數據的方式
第一步將用戶指定的關鍵詞進行分詞,
第二部將詞匯去分詞庫中進行檢索,得到多個文檔id,
第三步,將文檔的id放在一個上下文中
第四步,根據指定的size去ES中檢索指定個數數據,拿完數據的文檔id,會從上下文中移除
第五步,如果需要下一頁的數據,直接去ES的上下文中找后續內容。
第六步,循環第四步和第五步
scroll 不適合做實時查詢。

#scroll 查詢,返回第一頁數據,并將文檔id信息存放在ES上下文中,并指定生存時間 POST /sms-logs-index/sms-logs-type/_search?scroll=1m {"query": {"match_all": {}},"size": 2,"sort": [{"fee": {"order": "desc"}}] }#根據scroll 查詢下一頁數據 POST _search/scroll {"scroll_id":"DnF1ZXJ5VGhlbkZldGNoAwAAAAAAABbqFk04VlZ1cjlUU2t1eHpsQWNRY1YwWWcAAAAAAAAW7BZNOFZWdXI5VFNrdXh6bEFjUWNWMFlnAAAAAAAAFusWTThWVnVyOVRTa3V4emxBY1FjVjBZZw==","scroll":"1m" }#刪除scroll上下文中的數據 DELETE _search/scroll/DnF1ZXJ5VGhlbkZldGNoAwAAAAAAABchFk04VlZ1cjlUU2t1eHpsQWNRY1YwWWcAAAAAAAAXIBZNOFZWdXI5VFNrdXh6bEFjUWNWMFlnAAAAAAAAFx8WTThWVnVyOVRTa3V4emxBY1FjVjBZZw== public class ScrollSearch {ObjectMapper mapper = new ObjectMapper();RestHighLevelClient client = EsClient.getClient();String index = "sms-logs-index";String type="sms-logs-type";@Testpublic void scrollSearch() throws IOException {// 1.創建requestSearchRequest searchRequest = new SearchRequest(index);searchRequest.types(type);// 2.指定scroll信息,過期時間searchRequest.scroll(TimeValue.timeValueMinutes(1L));// 3.指定查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();builder.size(4);builder.sort("fee", SortOrder.DESC);searchRequest.source(builder);// 4.獲取返回結果scrollId,獲取sourceSearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);String scrollId = response.getScrollId();System.out.println("-------------首頁數據---------------------");for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}while (true){// 5.創建scroll requestSearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);// 6.指定scroll 有效時間scrollRequest.scroll(TimeValue.timeValueMinutes(1L));// 7.執行查詢,返回查詢結果SearchResponse scroll = client.scroll(scrollRequest, RequestOptions.DEFAULT);// 8.判斷是否查詢到數據,查詢到輸出SearchHit[] searchHits = scroll.getHits().getHits();if(searchHits!=null && searchHits.length >0){System.out.println("-------------下一頁數據---------------------");for (SearchHit hit : searchHits) {System.out.println(hit.getSourceAsMap());}}else{// 9.沒有數據,結束System.out.println("-------------結束---------------------");break;}}// 10.創建 clearScrollRequestClearScrollRequest clearScrollRequest = new ClearScrollRequest();// 11.指定scrollIdclearScrollRequest.addScrollId(scrollId);//12.刪除scrollClearScrollResponse clearScrollResponse = client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);// 13.輸出結果System.out.println("刪除scroll:"+clearScrollResponse.isSucceeded());} }

五、delete-by-query

根據term,match 等查詢方式去刪除大量索引
PS:如果你要刪除的內容,時index下的大部分數據,推薦創建一個新的index,然后把保留的文檔內容,添加到全新的索引

#Delet-by-query 刪除 POST /sms-logs-index/sms-logs-type/_delete_by_query {"query": {"range": {"fee": {"lt": 20}}} } public void deleteByQuery() throws IOException {// 1.創建DeleteByQueryRequestDeleteByQueryRequest request = new DeleteByQueryRequest(index);request.types(type);// 2.指定條件request.setQuery(QueryBuilders.rangeQuery("fee").lt(20));// 3.執行BulkByScrollResponse response = client.deleteByQuery(request, RequestOptions.DEFAULT);// 4.輸出返回結果System.out.println(response.toString());}

六、復合查詢

復合過濾器,將你的多個查詢條件 以一定的邏輯組合在一起,

must:所有條件組合在一起,表示 and 的意思
must_not: 將must_not中的條件,全部都不匹配,表示not的意思
should:所有條件用should 組合在一起,表示or 的意思

#省是 晉城 或者北京 # 運營商不能是聯通 #smsContent 包含 戰士 和的 POST /sms-logs-index/sms-logs-type/_search {"query": {"bool": {"should": [{"term": {"province": {"value": "晉城"}}},{"term": {"province": {"value": "北京"}}}],"must_not": [{"term": {"operatorId": {"value": "2"}}}],"must": [{"match": {"smsContent": "戰士"}},{"match": {"smsContent": "的"}}]}} } public void boolSearch() throws IOException {// 1.創建 searchRequestSearchRequest request = new SearchRequest(index);request.types(type);// 2.指定查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();// #省是 晉城 或者北京boolQueryBuilder.should(QueryBuilders.termQuery("province","北京"));boolQueryBuilder.should(QueryBuilders.termQuery("province","晉城"));//# 運營商不能是聯通boolQueryBuilder.mustNot(QueryBuilders.termQuery("operatorId",2));//#smsContent 包含 戰士 和的boolQueryBuilder.must(QueryBuilders.matchQuery("smsContent","戰士"));boolQueryBuilder.must(QueryBuilders.matchQuery("smsContent","的"));builder.query(boolQueryBuilder);request.source(builder);// 3.執行查詢SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.輸出結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}}

boosting 查詢

boosting 查詢可以幫助我們去影響查詢后的score

  • positive:只有匹配上positive 查詢的內容,才會被放到返回的結果集中
  • negative: 如果匹配上了positive 也匹配上了negative, 就可以 降低這樣的文檔score.
  • negative_boost:指定系數,必須小于1 0.5

關于查詢時,分數時如何計算的:

  • 搜索的關鍵字再文檔中出現的頻次越高,分數越高
  • 指定的文檔內容越短,分數越高。
  • 我們再搜索時,指定的關鍵字也會被分詞,這個被分詞的內容,被分詞庫匹配的個數越多,分數就越高。
#boosting 查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"boosting": {"positive": {"match": {"smsContent": "戰士"}}, "negative": {"match": {"smsContent": "團隊"}},"negative_boost": 0.2}} } public void boostSearch() throws IOException {// 1.創建 searchRequestSearchRequest request = new SearchRequest(index);request.types(type);// 2.指定查詢條件SearchSourceBuilder builder = new SearchSourceBuilder();BoostingQueryBuilder boost = QueryBuilders.boostingQuery(QueryBuilders.matchQuery("smsContent", "戰士"),QueryBuilders.matchQuery("smsContent", "團隊")).negativeBoost(0.2f);builder.query(boost);request.source(builder);// 3.執行查詢SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.輸出結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}}

七、filter 查詢

query 查詢:根據你的查詢條件,去計算文檔的匹配度得到一個分數,并根據分數排序,不會做緩存的。

filter 查詢:根據查詢條件去查詢文檔,不去計算分數,而且filter會對經常被過濾的數據進行緩存。

#filter 查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"bool": {"filter": [{"term": {"corpName": "海爾智家公司"}},{"range":{"fee":{"lte":50}}}]}} } public void filter() throws IOException {// 1.searchRequestSearchRequest searchRequest = new SearchRequest(index);searchRequest.types(type);// 2.指定查詢條件SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();boolBuilder.filter(QueryBuilders.termQuery("corpName","海爾智家公司"));boolBuilder.filter(QueryBuilders.rangeQuery("fee").gt(20));sourceBuilder.query(boolBuilder);searchRequest.source(sourceBuilder);// 3.執行SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);// 4. 輸出結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());System.out.println(hit.getId()+"的分數是:"+hit.getScore());}}

八、高亮查詢

高亮查詢就是用戶輸入的關鍵字,以一定特殊樣式展示給用戶,讓用戶知道為什么這個結果被檢索出來
高亮展示的數據,本身就是文檔中的一個field,單獨將field以highlight的形式返回給用戶

ES提供了一個highlight 屬性,他和query 同級別。

  • frament_size: 指定高亮數據展示多少個字符回來
  • pre_tags:指定前綴標簽
  • post_tags:指定后綴標簽
#highlight 高亮查詢 POST /sms-logs-index/sms-logs-type/_search {"query": {"match": {"smsContent": "團隊"}},"highlight": {"fields": {"smsContent":{}},"pre_tags":"<font color='red'>","post_tags":"</font>","fragment_size":10} } public void highLightQuery() throws IOException {// 1.創建requestSearchRequest request = new SearchRequest(index);request.types(type);// 2.指定查詢條件,指定高亮SearchSourceBuilder builder = new SearchSourceBuilder();builder.query(QueryBuilders.matchQuery("smsContent","團隊"));HighlightBuilder highlightBuilder = new HighlightBuilder();highlightBuilder.field("smsContent",10).preTags("<font colr='red'>").postTags("</font>");builder.highlighter(highlightBuilder);request.source(builder);// 3.執行SearchResponse response = client.search(request, RequestOptions.DEFAULT);//4. 輸出結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getHighlightFields().get("smsContent"));}}

九、聚合查詢

ES的聚合查詢和mysql 的聚合查詢類似,ES的聚合查詢相比mysql 要強大得多。ES提供的統計數據的方式多種多樣。

#ES 聚合查詢的RSTFul 語法 POST /index/type/_search {"aggs":{"(名字)agg":{"agg_type":{"屬性""值"}}} }

1、去重計數聚合查詢

去重計數,cardinality 先將返回的文檔中的一個指定的field進行去重,統計一共有多少條

# 去重計數 查詢 province POST /sms-logs-index/sms-logs-type/_search {"aggs": {"provinceAgg": {"cardinality": {"field": "province"}}} } public void aggCardinalityC() throws IOException {// 1.創建requestSearchRequest request = new SearchRequest(index);request.types(type);// 2. 指定使用聚合查詢方式SearchSourceBuilder builder = new SearchSourceBuilder();builder.aggregation(AggregationBuilders.cardinality("provinceAgg").field("province"));request.source(builder);// 3.執行查詢SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.輸出返回結果Cardinality agg = response.getAggregations().get("provinceAgg");System.out.println(agg.getValue());}

2、范圍統計

統計一定范圍內出現的文檔個數,比如,針對某一個field 的值再0100,100200,200~300 之間文檔出現的個數分別是多少
范圍統計 可以針對 普通的數值,針對時間類型,針對ip類型都可以響應。
數值 rang
時間 date_rang
ip ip_rang

#針對數值方式的范圍統計 from 帶等于效果 ,to 不帶等于效果 POST /sms-logs-index/sms-logs-type/_search {"aggs": {"agg": {"range": {"field": "fee","ranges": [{"to": 30},{"from": 30,"to": 60},{"from": 60}]}}} } #時間方式統計 POST /sms-logs-index/sms-logs-type/_search {"aggs": {"agg": {"date_range": {"field": "sendDate","format": "yyyy", "ranges": [{"to": "2000"},{"from": "2000"}]}}} } #ip 方式 范圍統計 POST /sms-logs-index/sms-logs-type/_search {"aggs": {"agg": {"ip_range": {"field": "ipAddr","ranges": [{"to": "127.0.0.8"},{"from": "127.0.0.8"}]}}} } public void aggRang() throws IOException {// 1.創建requestSearchRequest request = new SearchRequest(index);request.types(type);// 2. 指定使用聚合查詢方式SearchSourceBuilder builder = new SearchSourceBuilder();builder.aggregation(AggregationBuilders.range("agg").field("fee").addUnboundedTo(30).addRange(30,60).addUnboundedFrom(60));request.source(builder);// 3.執行查詢SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.輸出返回結果Range agg = response.getAggregations().get("agg");for (Range.Bucket bucket : agg.getBuckets()) {String key = bucket.getKeyAsString();Object from = bucket.getFrom();Object to = bucket.getTo();long docCount = bucket.getDocCount();System.out.println(String.format("key: %s ,from: %s ,to: %s ,docCount: %s",key,from,to,docCount));}}

3、統計聚合

他可以幫你查詢指定field 的最大值,最小值,平均值,平方和…
使用 extended_stats

#統計聚合查詢 extended_stats POST /sms-logs-index/sms-logs-type/_search {"aggs": {"agg": {"extended_stats": {"field": "fee"}}} } // java實現 public void aggExtendedStats() throws IOException {// 1.創建requestSearchRequest request = new SearchRequest(index);request.types(type);// 2. 指定使用聚合查詢方式SearchSourceBuilder builder = new SearchSourceBuilder();builder.aggregation(AggregationBuilders.extendedStats("agg").field("fee"));request.source(builder);// 3.執行查詢SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.輸出返回結果ExtendedStats extendedStats = response.getAggregations().get("agg");System.out.println("最大值:"+extendedStats.getMaxAsString()+",最小值:"+extendedStats.getMinAsString());}

4、其他聚合查詢 查看官方文檔

https://www.elastic.co/guide/en/elasticsearch/reference/6.8/search-aggregations-metrics-weight-avg-aggregation.html

十、 地圖經緯度搜索

#創建一個經緯度索引,指定一個 name ,一個location PUT /map {"settings": {"number_of_shards": 5,"number_of_replicas": 1},"mappings": {"map":{"properties":{"name":{"type":"text"},"location":{"type":"geo_point"}}}} }#添加測試數據 PUT /map/map/1 {"name":"天安門","location":{"lon": 116.403694,"lat":39.914492} }PUT /map/map/2 {"name":"百望山","location":{"lon": 116.26284,"lat":40.036576} }PUT /map/map/3 {"name":"北京動物園","location":{"lon": 116.347352,"lat":39.947468} }

1、ES 的地圖檢索方式

geo_distance :直線距離檢索方式
geo_bounding_box: 以2個點確定一個矩形,獲取再矩形內的數據
geo_polygon:以多個點,確定一個多邊形,獲取多邊形的全部數據

2、基于RESTFul 實現地圖檢索

geo_distance

#geo_distance POST /map/map/_search {"query": {"geo_distance":{#確定一個點"location":{"lon":116.434739,"lat":39.909843},#確定半徑"distance":20000,#指定形狀為圓形"distance_type":"arc"}} } #geo_bounding_box POST /map/map/_search {"query":{"geo_bounding_box":{"location":{"top_left":{"lon":116.327805,"lat":39.95499},"bottom_right":{"lon": 116.363162,"lat":39.938395}}}} } #geo_polygon POST /map/map/_search {"query":{"geo_polygon":{"location":{# 指定多個點確定 位置"points":[{"lon":116.220296,"lat":40.075013},{"lon":116.346777,"lat":40.044751},{"lon":116.236106,"lat":39.981533} ]}}} }

3、 java 實現 geo_polygon

public class GeoDemo {RestHighLevelClient client = EsClient.getClient();String index = "map";String type="map";@Testpublic void GeoPolygon() throws IOException {// 1.創建searchRequestSearchRequest request = new SearchRequest(index);request.types(type);// 2.指定 檢索方式SearchSourceBuilder builder = new SearchSourceBuilder();List<GeoPoint> points = new ArrayList<>();points.add(new GeoPoint(40.075013,116.220296));points.add(new GeoPoint(40.044751,116.346777));points.add(new GeoPoint(39.981533,116.236106));builder.query(QueryBuilders.geoPolygonQuery("location",points));request.source(builder);// 3.執行SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.輸出結果for (SearchHit hit : response.getHits().getHits()) {System.out.println(hit.getSourceAsMap());}} }

參考:https://github.com/changxuepeng/ElasticsearchStudy/blob/master/ES%E7%AC%94%E8%AE%B0/ES%E7%AC%94%E8%AE%B0.md

總結

以上是生活随笔為你收集整理的Elasticsearch学习4《Elasticsearch的各种查询》的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。