Java Elasticsearch

概述

操作数据习惯使用sql语句,对于非sql语句的数据库中间肯定使用得很不习惯对于Elasticsearch经常常用的操作,总结一些语句(包括 json格式语句和对应java api编写)。

配置

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  4. </dependency>

直接导入依赖,然后注入 RestHighLevelClient 对象即可使用

基础增删改

添加文档

Java API

  1. /**
  2. * 添加文档
  3. * @param addDocDto
  4. * @throws IOException
  5. */
  6. public void addDoc(AddDocDto addDocDto) throws IOException {
  7. IndexRequest indexRequest = new IndexRequest(addDocDto.getIndexName());
  8. indexRequest.source(addDocDto.getData());
  9. indexRequest.id(addDocDto.getId());
  10. //创建索引
  11. IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
  12. log.info("执行结果:"+JSONUtil.toJsonStr(index));
  13. }

Elasticsearch

  1. POST test-index-20220228/_doc
  2. {
  3. "sex": "w",
  4. "balance2": 320,
  5. "balance": "501",
  6. "name": "liujing5",
  7. "age": 6
  8. }

说明:用于插入文档,post 方法 自动生成 id

更新文档

Java API

  1. /**
  2. * 更新文档(仅仅根据id更新,是增量字段)
  3. * @param updateDocDto
  4. * @throws IOException
  5. */
  6. public void updateDoc3(UpdateDocDto updateDocDto) throws IOException {
  7. UpdateRequest indexRequest = new UpdateRequest(updateDocDto.getIndexName(),updateDocDto.getId());
  8. //设置数据
  9. indexRequest.doc(updateDocDto.getData());
  10. //更新文档
  11. UpdateResponse update = restHighLevelClient.update(indexRequest, RequestOptions.DEFAULT);
  12. log.info("执行结果:"+JSONUtil.toJsonStr(update));
  13. }

Elasticsearch

  1. POST test-index-20220228/_update/L1gtSX8BX_oAU-6DS9F3
  2. {
  3. "doc": {
  4. "sex" : "w",
  5. "balance2" : 320,
  6. "balance" : "501",
  7. "name" : "liujing5",
  8. "age" : 7
  9. }
  10. }

更新文档根据条件

Java API

  1. /**
  2. * 更新文档(根据条件更新数据,删掉了老字段)
  3. * @param updateDocDto
  4. * @throws IOException
  5. */
  6. public void updateDoc2(UpdateDocDto updateDocDto) throws IOException {
  7. UpdateByQueryRequest indexRequest = new UpdateByQueryRequest(updateDocDto.getIndexName());
  8. //设置更新条件
  9. Set<String> strings = updateDocDto.getQuery().keySet();
  10. for (String key:strings){
  11. QueryBuilder queryBuilder = new TermQueryBuilder(key,updateDocDto.getQuery().get(key));
  12. indexRequest.setQuery(queryBuilder);
  13. }
  14. //设置更新值
  15. JSONObject data = updateDocDto.getData();
  16. //更新值脚本
  17. String source = "ctx._source=params";
  18. Script script = new Script(ScriptType.INLINE, "painless", source, data);
  19. indexRequest.setScript(script);
  20. //更新文档
  21. BulkByScrollResponse index = restHighLevelClient.updateByQuery(indexRequest, RequestOptions.DEFAULT);
  22. log.info("执行结果:"+JSONUtil.toJsonStr(index));
  23. }

Elasticsearch

  1. POST test-index-20220228/_update_by_query
  2. {
  3. "query": {
  4. "term": {
  5. "age": {
  6. "value" : 7,
  7. "boost" : 1.0
  8. }
  9. }
  10. },
  11. "script": {
  12. "source":"ctx._source=params",
  13. "params":{"aaa":"50003"}
  14. }
  15. }

说明:根据任意条件更新匹配文档

删除文档

Java API

  1. /**
  2. * 删除文档(根据id)
  3. * @param deleteDocDto
  4. * @throws IOException
  5. */
  6. public void deleteDoc(DeleteDocDto deleteDocDto) throws IOException {
  7. DeleteRequest indexRequest = new DeleteRequest(deleteDocDto.getIndexName(),deleteDocDto.getId());
  8. //更新文档
  9. DeleteResponse update = restHighLevelClient.delete(indexRequest, RequestOptions.DEFAULT);
  10. log.info("执行结果:"+JSONUtil.toJsonStr(update));
  11. }

Elasticsearch

  1. DELETE test-index-20220228/_doc/L1gtSX8BX_oAU-6DS9F3

删除文档根据条件

Java API

  1. /**
  2. * 删除文档(根据任意条件)
  3. * @param deleteDocDto
  4. * @throws IOException
  5. */
  6. public void deleteDoc2(DeleteDocDto deleteDocDto) throws IOException {
  7. DeleteByQueryRequest indexRequest = new DeleteByQueryRequest(deleteDocDto.getIndexName());
  8. //设置查询条件
  9. Set<String> strings = deleteDocDto.getQuery().keySet();
  10. for (String key:strings){
  11. QueryBuilder queryBuilder = new TermQueryBuilder(key,deleteDocDto.getQuery().get(key));
  12. indexRequest.setQuery(queryBuilder);
  13. log.info(queryBuilder.toString());
  14. }
  15. //更新文档
  16. BulkByScrollResponse response = restHighLevelClient.deleteByQuery(indexRequest, RequestOptions.DEFAULT);
  17. log.info("执行结果:"+JSONUtil.toJsonStr(response));
  18. }

Elasticsearch

  1. POST test-index-20220228/_delete_by_query
  2. {
  3. "query":{
  4. "term" : {
  5. "age" : {
  6. "value" : 6,
  7. "boost" : 1.0
  8. }
  9. }
  10. }
  11. }

说明:根据条件删除指定文档

非分词基础查询 (term)

单字段等值查询

SQL

  1. select * from user where name = "张三"

Java API

  1. /**
  2. * 单字段查询(等值)
  3. * @param searchDocDto
  4. * @throws IOException
  5. */
  6. public void search(SearchDocDto searchDocDto) throws IOException {
  7. //构件查询
  8. TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(searchDocDto.getKey(), searchDocDto.getValue());
  9. //查询
  10. searchCommon(searchDocDto.getIndexName(),termQueryBuilder);
  11. }

Elasticsearch

  1. POST test-index-20220228/_search
  2. {
  3. "query": {
  4. "term": {
  5. "name": {
  6. "value": "liujing2",
  7. "boost": 1
  8. }
  9. }
  10. }
  11. }

说明:可以进行任意单字段进行等值查询操作

单字段多值查询

SQL

  1. select * from user where name in ("张三","李四")

Java API

  1. /**
  2. * 单字段查询(多值等值)
  3. * @param searchDocDto
  4. * @throws IOException
  5. */
  6. public void search2(SearchDocDto searchDocDto) throws IOException {
  7. //构件查询
  8. TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery(searchDocDto.getKey(), searchDocDto.getValues());
  9. //查询
  10. searchCommon(searchDocDto.getIndexName(),termsQueryBuilder);
  11. }

Elasticsearch

  1. POST test-index-20220228/_search
  2. {
  3. "query": {
  4. "terms": {
  5. "name": [
  6. "liujing3",
  7. "liujing"
  8. ],
  9. "boost": 1
  10. }
  11. }
  12. }

说明:可以进行任意单字段多个值进行等值批量查询操作

分词基础查询 (match)

单字段分词查询

SQL

  1. select * from user where name like "%liujjing%"

Java API

  1. /**
  2. * 单字段查询(模糊-分词查询)
  3. * @param searchDocDto
  4. */
  5. public void search11(SearchDocDto searchDocDto) throws IOException {
  6. //构件match查询
  7. MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(searchDocDto.getKey(), searchDocDto.getValue());
  8. //查询
  9. searchCommon(searchDocDto.getIndexName(),matchQueryBuilder);
  10. }

Elasticsearch

  1. POST test-index-20220228/_search
  2. {
  3. "query": {
  4. "match": {
  5. "name": {
  6. "query": "liujing2",
  7. "operator": "OR",
  8. "prefix_length": 0,
  9. "max_expansions": 50,
  10. "fuzzy_transpositions": true,
  11. "lenient": false,
  12. "zero_terms_query": "NONE",
  13. "auto_generate_synonyms_phrase_query": true,
  14. "boost": 1
  15. }
  16. }
  17. }
  18. }

说明:可以对任意字段进行分词查询

多字段分词查询

SQL

  1. select * from user where name like "%liujjing%" or ...

Java API

  1. /**
  2. * 多字段查询(模糊多个字段-分词查询)
  3. * @param searchDocDto
  4. */
  5. public void search12(SearchDocDto searchDocDto) throws IOException {
  6. //构件match查询
  7. MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(searchDocDto.getValue(),searchDocDto.getFields());
  8. //查询
  9. searchCommon(searchDocDto.getIndexName(),multiMatchQueryBuilder);
  10. }

Elasticsearch

  1. POST test-index-20220228/_search
  2. {
  3. "query": {
  4. "multi_match": {
  5. "query": "liujing2 1200",
  6. "fields": [
  7. "name^1.0","balance"
  8. ],
  9. "type": "best_fields",
  10. "operator": "OR",
  11. "slop": 0,
  12. "prefix_length": 0,
  13. "max_expansions": 50,
  14. "zero_terms_query": "NONE",
  15. "auto_generate_synonyms_phrase_query": true,
  16. "fuzzy_transpositions": true,
  17. "boost": 1
  18. }
  19. }
  20. }

说明:可以同时对多个任意字段进行分词查询

多字段词组分词查询

SQL

  1. select * from user where name like "%liujjing hello %"

Java API

  1. /**
  2. * 单字段查询(模糊-词组分词查询)
  3. * @param searchDocDto
  4. */
  5. public void search13(SearchDocDto searchDocDto) throws IOException {
  6. //构件match查询
  7. MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery(searchDocDto.getKey(), searchDocDto.getValue());
  8. //查询
  9. searchCommon(searchDocDto.getIndexName(),matchPhraseQueryBuilder);
  10. }

Elasticsearch

  1. POST test-index-20220228/_search
  2. {
  3. "query": {
  4. "match_phrase": {
  5. "name": {
  6. "query": "liujing2 hello",
  7. "slop": 0,
  8. "zero_terms_query": "NONE",
  9. "boost": 1
  10. }
  11. }
  12. }
  13. }

说明:可以任意字段进行词语分词查询

范围和分页查询

单字段范围查询

SQL

  1. select * from user where age >20 and age<30

Java API

  1. /**
  2. * 单字段查询(范围)
  3. * @param searchDocDto
  4. * @throws IOException
  5. */
  6. public void search3(SearchDocDto searchDocDto) throws IOException {
  7. //构件查询
  8. RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(searchDocDto.getKey());
  9. rangeQueryBuilder.from(searchDocDto.getStartValue());
  10. rangeQueryBuilder.to(searchDocDto.getEndValue());
  11. //查询
  12. searchCommon(searchDocDto.getIndexName(),rangeQueryBuilder);
  13. }

Elasticsearch

  1. POST test-index-20220228/_search
  2. {
  3. "query": {
  4. "range": {
  5. "age": {
  6. "from": "2",
  7. "to": "19",
  8. "include_lower": true,
  9. "include_upper": true,
  10. "boost": 1
  11. }
  12. }
  13. }
  14. }

说明:可以进行任意单字段范围批量查询操作

分页查询

SQL

  1. select * from user limit 1 5

Java API

  1. /**
  2. * 分页
  3. * @param searchDocDto
  4. */
  5. public void search14(SearchDocDto searchDocDto) throws IOException {
  6. SearchRequest searchRequest = new SearchRequest(searchDocDto.getIndexName());
  7. //构建查询
  8. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  9. //分页
  10. searchSourceBuilder.from(1);
  11. searchSourceBuilder.size(2);
  12. searchRequest.source(searchSourceBuilder);
  13. log.info("查询条件"+searchSourceBuilder.toString());
  14. SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
  15. SearchHits hits = search.getHits();
  16. for (SearchHit searchHit:hits){
  17. log.info(JSONUtil.toJsonStr(searchHit.getSourceAsString()));
  18. }
  19. }

Elasticsearch

  1. POST test-index-20220228/_search
  2. {
  3. //query 可以使用query分页
  4. "from": 1,
  5. "size": 5
  6. }

说明:可以进行带条件分页查询

复合条件查询

should

SQL

  1. select * from user = "张三" or age=18

Java API

  1. /**
  2. * 复合多字段查询(should)
  3. * @param searchDocDto
  4. */
  5. public void search4(SearchDocDto searchDocDto) throws IOException {
  6. //构件查询
  7. BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
  8. JSONObject query = searchDocDto.getQuery();
  9. Set<String> strings = query.keySet();
  10. for(String key:strings) {
  11. TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(key, query.get(key));
  12. boolQueryBuilder.should(termQueryBuilder);
  13. }
  14. //查询
  15. searchCommon(searchDocDto.getIndexName(),boolQueryBuilder);
  16. }

Elasticsearch

  1. POST test-index-20220228/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "should": [
  6. {
  7. "term": {
  8. "name": {
  9. "value": "liujing",
  10. "boost": 1
  11. }
  12. }
  13. },
  14. {
  15. "term": {
  16. "age": {
  17. "value": 19,
  18. "boost": 1
  19. }
  20. }
  21. }
  22. ],
  23. "adjust_pure_negative": true,
  24. "boost": 1
  25. }
  26. }
  27. }

说明:可以进行多字段进行 or 查询, 只要满足一个 shoud 的条件即可

must

SQL

  1. select * from user = "张三" and age=18

Java API

  1. /**
  2. * 复合多字段查询(must)
  3. * @param searchDocDto
  4. */
  5. public void search5(SearchDocDto searchDocDto) throws IOException {
  6. //构件查询
  7. BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
  8. JSONObject query = searchDocDto.getQuery();
  9. Set<String> strings = query.keySet();
  10. for(String key:strings) {
  11. TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(key, query.get(key));
  12. boolQueryBuilder.must(termQueryBuilder);
  13. }
  14. //查询
  15. searchCommon(searchDocDto.getIndexName(),boolQueryBuilder);
  16. }

Elasticsearch

  1. POST test-index-20220228/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. {
  7. "term": {
  8. "name": {
  9. "value": "liujing",
  10. "boost": 1
  11. }
  12. }
  13. },
  14. {
  15. "term": {
  16. "age": {
  17. "value": 19,
  18. "boost": 1
  19. }
  20. }
  21. }
  22. ],
  23. "adjust_pure_negative": true,
  24. "boost": 1
  25. }
  26. }
  27. }

说明:可以进行多字段进行 and 查询,要同时满足多个条件才返回

must not

SQL

  1. select * from user != "张三" and age!=18

Java API

  1. /**
  2. * 复合多字段查询(must not,不计算相关性分数,和must查询到数据相反)
  3. * @param searchDocDto
  4. */
  5. public void search6(SearchDocDto searchDocDto) throws IOException {
  6. //构件查询
  7. BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
  8. JSONObject query = searchDocDto.getQuery();
  9. Set<String> strings = query.keySet();
  10. for(String key:strings) {
  11. TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(key, query.get(key));
  12. boolQueryBuilder.mustNot(termQueryBuilder);
  13. }
  14. //查询
  15. searchCommon(searchDocDto.getIndexName(),boolQueryBuilder);
  16. }

Elasticsearch

  1. {
  2. "query": {
  3. "bool": {
  4. "must_not": [
  5. {
  6. "term": {
  7. "name": {
  8. "value": "liujing",
  9. "boost": 1
  10. }
  11. }
  12. },
  13. {
  14. "term": {
  15. "age": {
  16. "value": 19,
  17. "boost": 1
  18. }
  19. }
  20. }
  21. ],
  22. "adjust_pure_negative": true,
  23. "boost": 1
  24. }
  25. }
  26. }

说明:可以进行多字段进行 and 查询,要同时不满足多个条件才返回

filter

SQL

  1. select * from user = "张三" and age=18

Java API

  1. /**
  2. * 复合多字段查询(filter,不计算相关性分数,和must查询到数据相同)
  3. * @param searchDocDto
  4. */
  5. public void search7(SearchDocDto searchDocDto) throws IOException {
  6. //构件查询
  7. BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
  8. JSONObject query = searchDocDto.getQuery();
  9. Set<String> strings = query.keySet();
  10. for(String key:strings) {
  11. TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(key, query.get(key));
  12. boolQueryBuilder.filter(termQueryBuilder);
  13. }
  14. //查询
  15. searchCommon(searchDocDto.getIndexName(),boolQueryBuilder);
  16. }

Elasticsearch

  1. {
  2. "query": {
  3. "bool": {
  4. "filter": [
  5. {
  6. "term": {
  7. "name": {
  8. "value": "liujing",
  9. "boost": 1
  10. }
  11. }
  12. },
  13. {
  14. "term": {
  15. "age": {
  16. "value": 19,
  17. "boost": 1
  18. }
  19. }
  20. }
  21. ],
  22. "adjust_pure_negative": true,
  23. "boost": 1
  24. }
  25. }
  26. }

说明:和 must 效果一样,只是不做评分

should,must,must_not,filter 复合

SQL

  1. select * from ((user = "张三" and age=18) and (balance=1000 or balance=2000))

Java API

  1. /**
  2. * 复合多字段查询(should,must,must_not,filter进行复合)
  3. * @param searchDocDto
  4. */
  5. public void search8(SearchDocDto searchDocDto) throws IOException {
  6. //构件查询
  7. BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
  8. //构件should条件
  9. JSONObject query = searchDocDto.getShouldQuery();
  10. Set<String> strings = query.keySet();
  11. for(String key:strings) {
  12. TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(key, query.get(key));
  13. boolQueryBuilder.should(termQueryBuilder);
  14. }
  15. //构件must条件
  16. JSONObject query1 = searchDocDto.getMustQuery();
  17. Set<String> strings1 = query1.keySet();
  18. for(String key:strings1) {
  19. TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(key, query1.get(key));
  20. boolQueryBuilder.must(termQueryBuilder);
  21. }
  22. //查询
  23. searchCommon(searchDocDto.getIndexName(),boolQueryBuilder);
  24. }

Elasticsearch

  1. POST test-index-20220228/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": [
  6. {
  7. "term": {
  8. "sex": {
  9. "value": "w",
  10. "boost": 1
  11. }
  12. }
  13. },
  14. {
  15. "term": {
  16. "name": {
  17. "value": "liujing2",
  18. "boost": 1
  19. }
  20. }
  21. }
  22. ],
  23. "should": [
  24. {
  25. "term": {
  26. "balance": {
  27. "value": 1200,
  28. "boost": 1
  29. }
  30. }
  31. },
  32. {
  33. "term": {
  34. "age": {
  35. "value": 5,
  36. "boost": 1
  37. }
  38. }
  39. }
  40. ],
  41. "adjust_pure_negative": true,
  42. "boost": 1
  43. }
  44. }
  45. }

说明:should,must,filter,must not 这些查询的条件都满足

should,must,must_not,filter 和 bool 复合

SQL

  1. select * from ((user = "张三" and age=18) and (balance=1000 or balance=2000)) or((....))

Java API

  1. /**
  2. * 复合多字段查询((should,must,must_not,filter)(bool)进行复合)
  3. * @param searchDocDto
  4. */
  5. public void search9(SearchDocDto searchDocDto) throws IOException {
  6. //构件查询
  7. BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
  8. //构件should条件
  9. JSONObject query = searchDocDto.getShouldQuery();
  10. Set<String> strings = query.keySet();
  11. for(String key:strings) {
  12. TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(key, query.get(key));
  13. boolQueryBuilder.should(termQueryBuilder);
  14. }
  15. //构件内部bool
  16. BoolQueryBuilder boolQueryBuilder1 = QueryBuilders.boolQuery();
  17. JSONObject query1 = searchDocDto.getInnerBoolQuery();
  18. Set<String> strings1 = query1.keySet();
  19. for(String key:strings1) {
  20. TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(key, query1.get(key));
  21. boolQueryBuilder1.must(termQueryBuilder);
  22. }
  23. boolQueryBuilder.should(boolQueryBuilder1);
  24. //查询
  25. searchCommon(searchDocDto.getIndexName(),boolQueryBuilder);
  26. }

Elasticsearch

  1. GET test-index-20220228/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "should": [
  6. {
  7. "term": {
  8. "balance": {
  9. "value": 1200,
  10. "boost": 1
  11. }
  12. }
  13. },
  14. {
  15. "term": {
  16. "age": {
  17. "value": 5,
  18. "boost": 1
  19. }
  20. }
  21. },
  22. {
  23. "bool": {
  24. "must": [
  25. {
  26. "term": {
  27. "balance": {
  28. "value": "50",
  29. "boost": 1
  30. }
  31. }
  32. },
  33. {
  34. "term": {
  35. "age": {
  36. "value": 2,
  37. "boost": 1
  38. }
  39. }
  40. }
  41. ],
  42. "adjust_pure_negative": true,
  43. "boost": 1
  44. }
  45. }
  46. ],
  47. "adjust_pure_negative": true,
  48. "boost": 1
  49. }
  50. }
  51. }

说明:should,must,filter,must not 内部可以再次嵌套 bool 系列条件

should,must,must_not,filter 内部可使用基本查询

SQL

  1. select * from ()

Java API

  1. /**
  2. * 复合多字段查询((should,must,must_not,filter)(term,much,range)进行复合)
  3. * @param searchDocDto
  4. */
  5. public void search10(SearchDocDto searchDocDto) throws IOException {
  6. //构件range条件
  7. RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(searchDocDto.getKey());
  8. rangeQueryBuilder.from(searchDocDto.getStartValue());
  9. rangeQueryBuilder.to(searchDocDto.getEndValue());
  10. //构件should条件
  11. BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
  12. boolQueryBuilder.should(rangeQueryBuilder);
  13. //查询
  14. searchCommon(searchDocDto.getIndexName(),boolQueryBuilder);
  15. }

Elasticsearch

  1. GET test-index-20220228/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "should": [
  6. {
  7. "range": {
  8. "name": {
  9. "from": "1",
  10. "to": "19",
  11. "include_lower": true,
  12. "include_upper": true,
  13. "boost": 1
  14. }
  15. }
  16. }
  17. ],
  18. "adjust_pure_negative": true,
  19. "boost": 1
  20. }
  21. }
  22. }

说明:should,must,filter,must not 内部可以使用基本查询 (term,match,range)

聚合查询

常用聚合

SQL

  1. select count(*) from user where age>20 group by name,age

Java API

  1. /**
  2. * 聚合(terms--统计文档数量)==(group(可以嵌套group,相当于多字段group)+count(*)聚合函数)
  3. * 聚合(max)==(max(*)聚合函数)
  4. * 聚合(min)==(min(*)聚合函数)
  5. * 聚合(avg)==(avg(*)聚合函数)
  6. * 聚合(sum)==(sum(*)聚合函数)
  7. * 聚合(top_hits)==保存聚合后记录
  8. * @param searchDocDto
  9. * @throws IOException
  10. */
  11. public void search15(SearchDocDto searchDocDto) throws IOException {
  12. SearchRequest searchRequest = new SearchRequest(searchDocDto.getIndexName());
  13. //构建查询
  14. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  15. //聚合
  16. TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg");
  17. //设置聚合字段
  18. ageAgg.field(searchDocDto.getAggField());
  19. //设置展示聚合分布的结果数量
  20. ageAgg.size(searchDocDto.getAggSize());
  21. //设置聚合结果文档数下限
  22. ageAgg.minDocCount(searchDocDto.getAggMinDocCount());
  23. //设置排序
  24. BucketOrder count = BucketOrder.count(true);
  25. ageAgg.order(count);
  26. //设置子聚合
  27. AggregatorFactories.Builder builder = AggregatorFactories.builder();
  28. //设置平均值聚合函数
  29. AvgAggregationBuilder balanceAvgAgg = AggregationBuilders.avg("balanceAvgAgg");
  30. balanceAvgAgg.field("balance2");
  31. builder.addAggregator(balanceAvgAgg);
  32. //设置最大值聚合函数
  33. MaxAggregationBuilder maxAgg = AggregationBuilders.max("balanceMaxAgg");
  34. maxAgg.field("balance2");
  35. builder.addAggregator(maxAgg);
  36. //设置最小值聚合函数
  37. MinAggregationBuilder minAgg = AggregationBuilders.min("balanceMinAgg");
  38. minAgg.field("balance2");
  39. builder.addAggregator(minAgg);
  40. //设置总数聚合函数
  41. SumAggregationBuilder sumAggregationBuilder = AggregationBuilders.sum("balanceSumAgg");
  42. sumAggregationBuilder.field("balance2");
  43. builder.addAggregator(sumAggregationBuilder);
  44. //设置聚合中各值对应记录
  45. TopHitsAggregationBuilder aggRecord = AggregationBuilders.topHits("aggRecord");
  46. aggRecord.size(1);
  47. builder.addAggregator(aggRecord);
  48. ageAgg.subAggregations(builder);
  49. searchSourceBuilder.aggregation(ageAgg);
  50. searchRequest.source(searchSourceBuilder);
  51. log.info("查询条件"+searchSourceBuilder.toString());
  52. SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
  53. //获取聚合结果
  54. Aggregations aggregations = search.getAggregations();
  55. for (Aggregation aggr:aggregations.asList()){
  56. ParsedLongTerms parsedLongTerms=(ParsedLongTerms)aggr;
  57. List<? extends Terms.Bucket> buckets = parsedLongTerms.getBuckets();
  58. for(Terms.Bucket bucket:buckets){
  59. log.info(JSONUtil.toJsonStr(bucket));
  60. }
  61. }
  62. }

Elasticsearch

  1. GET test-index-20220228/_search
  2. {
  3. "aggregations": {
  4. "ageAgg": {
  5. "terms": {
  6. "field": "age",
  7. "size": 10,
  8. "min_doc_count": 1,
  9. "shard_min_doc_count": 0,
  10. "show_term_doc_count_error": false,
  11. "order": [
  12. {
  13. "_count": "asc"
  14. },
  15. {
  16. "_key": "asc"
  17. }
  18. ]
  19. },
  20. "aggregations": {
  21. "balanceAvgAgg": {
  22. "avg": {
  23. "field": "balance2"
  24. }
  25. },
  26. "balanceMaxAgg": {
  27. "max": {
  28. "field": "balance2"
  29. }
  30. },
  31. "balanceMinAgg": {
  32. "min": {
  33. "field": "balance2"
  34. }
  35. },
  36. "balanceSumAgg": {
  37. "sum": {
  38. "field": "balance2"
  39. }
  40. },
  41. "aggRecord": {
  42. "top_hits": {
  43. "from": 0,
  44. "size": 1,
  45. "version": false,
  46. "seq_no_primary_term": false,
  47. "explain": false
  48. }
  49. }
  50. }
  51. }
  52. }
  53. }

说明:

  1. term 聚合类型相当于 group by 可以用于分布数据, 当然可以嵌套 term, 相当于根据多个字段分组
  2. term 聚合后得到的聚合结果会有基本的文档数量
  3. max,min,sum,avg 相当于一些计算聚合函数

    常用聚合 2(聚合条件过滤)

    SQL

    1. select count(*) count from user where age>20 group by name,age having count>1

    Java API

    1. /**
    2. * 聚合(bucket_selector)==(having in)聚合函数)
    3. * @param searchDocDto
    4. * @throws IOException
    5. */
    6. public void search17(SearchDocDto searchDocDto) throws IOException {
    7. SearchRequest searchRequest = new SearchRequest(searchDocDto.getIndexName());
    8. //构建查询
    9. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    10. //聚合term聚合
    11. TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg");
    12. ageAgg.field(searchDocDto.getAggField());
    13. searchSourceBuilder.aggregation(ageAgg);
    14. //设置子聚合
    15. AggregatorFactories.Builder builder = AggregatorFactories.builder();
    16. //设置bucket_selector
    17. Map<String, String> bucketsPath = new HashMap<>();
    18. bucketsPath.put("count","_count");
    19. BucketSelectorPipelineAggregationBuilder pipelineAggregationBuilder = new BucketSelectorPipelineAggregationBuilder
    20. ("filterAgg",bucketsPath, Script.parse("params.count>1"));
    21. builder.addPipelineAggregator(pipelineAggregationBuilder);
    22. ageAgg.subAggregations(builder);
    23. searchRequest.source(searchSourceBuilder);
    24. log.info("查询条件"+searchSourceBuilder.toString());
    25. SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    26. Aggregations aggregations = search.getAggregations();
    27. for (Aggregation aggr:aggregations.asList()){
    28. ParsedLongTerms parsedLongTerms=(ParsedLongTerms)aggr;
    29. List<? extends Terms.Bucket> buckets = parsedLongTerms.getBuckets();
    30. for(Terms.Bucket bucket:buckets){
    31. log.info(JSONUtil.toJsonStr(bucket));
    32. }
    33. }
    34. }

    Elasticsearch

    1. GET test-index-20220228/_search
    2. {
    3. "aggregations": {
    4. "ageAgg": {
    5. "terms": {
    6. "field": "age",
    7. "size": 10,
    8. "min_doc_count": 1,
    9. "shard_min_doc_count": 0,
    10. "show_term_doc_count_error": false,
    11. "order": [
    12. {
    13. "_count": "desc"
    14. },
    15. {
    16. "_key": "asc"
    17. }
    18. ]
    19. },
    20. "aggregations": {
    21. "filterAgg": {
    22. "bucket_selector": {
    23. "buckets_path": {
    24. "count": "_count"
    25. },
    26. "script": {
    27. "source": "params.count>1",
    28. "lang": "painless"
    29. },
    30. "gap_policy": "skip"
    31. }
    32. }
    33. }
    34. }
    35. }
    36. }

    说明:bucket_selector 类型聚合可以将上一级聚合桶进行条件过滤

    总结

  4. 有基本的 term,match,range 查询

  5. should,must,must not filter 复合可以内部使用基本查询
  6. should,must,must not filter 内部可以组合 bool 实现更复杂的复合查询
  7. aggregations 实现分组和聚合函数计算