Elasticsearch 入门实战(5)--Java API Client 使用

打印 上一主题 下一主题

主题 507|帖子 507|积分 1521

本文主要介绍 Elasticsearch Java API Client 的使用,相关的环境及软件信息如下:CentOS 7.6.1810、Java 1.8.0_321(客户端用)、Elasticsearch 8.2.2。
1、Java API Client 的特点


  • Strongly typed requests and responses for all Elasticsearch APIs.
  • Blocking and asynchronous versions of all APIs.
  • Use of fluent builders and functional patterns to allow writing concise yet readable code when creating complex nested structures.
  • Seamless integration of application classes by using an object mapper such as Jackson or any JSON-B implementation.
  • Delegates protocol handling to an http client such as the Java Low Level REST Client that takes care of all transport-level concerns: HTTP connection pooling, retries, node discovery, and so on.
2、引入依赖
  1. <dependency>
  2.     <groupId>co.elastic.clients</groupId>
  3.     <artifactId>elasticsearch-java</artifactId>
  4.     <version>8.2.2</version>
  5. </dependency>
复制代码
3、使用

Elasticsearch Java API Client 通过 API 的方式来组装请求数据,避免直接编写 JSON 字符串;请求数据的详细说明可参考:Elasticsearch 入门实战(3)--REST API 使用
3.1、连接及关闭

Java API Client 底层依赖 Java Low Level REST Client,需先创建 Low Level REST Client。
  1. private ElasticsearchTransport transport;
  2. private ElasticsearchClient client;
  3. @Before
  4. public void before() {
  5.     RestClient restClient = RestClient.builder(
  6.             new HttpHost("10.49.196.10", 9200),
  7.             new HttpHost("10.49.196.11", 9200),
  8.             new HttpHost("10.49.196.12", 9200)).build();
  9.     ObjectMapper objectMapper = new ObjectMapper();
  10.     transport = new RestClientTransport(restClient, new JacksonJsonpMapper(objectMapper));
  11.     client = new ElasticsearchClient(transport);
  12. }
  13. @After
  14. public void after() throws IOException {
  15.     client.shutdown();
  16. }
复制代码
3.2、索引

3.2.1、创建索引
  1. @Test
  2. public void createIndex() throws IOException {
  3.     CreateIndexResponse response = client.indices().create(builder -> builder
  4.             .settings(indexSettingsBuilder -> indexSettingsBuilder.numberOfReplicas("1").numberOfShards("2"))
  5.             .mappings(typeMappingBuilder -> typeMappingBuilder
  6.                     .properties("age", propertyBuilder -> propertyBuilder.integer(integerNumberPropertyBuilder -> integerNumberPropertyBuilder))
  7.                     .properties("name", propertyBuilder -> propertyBuilder.keyword(keywordPropertyBuilder -> keywordPropertyBuilder))
  8.                     .properties("poems", propertyBuilder -> propertyBuilder.text(textPropertyBuilder -> textPropertyBuilder.analyzer("ik_max_word").searchAnalyzer("ik_max_word")))
  9.                     .properties("about", propertyBuilder -> propertyBuilder.text(textPropertyBuilder -> textPropertyBuilder.analyzer("ik_max_word").searchAnalyzer("ik_max_word")))
  10.                     .properties("success", propertyBuilder -> propertyBuilder.text(textPropertyBuilder -> textPropertyBuilder.analyzer("ik_max_word").searchAnalyzer("ik_max_word")))
  11.             )
  12.             .index(INDEX_NAME));
  13.     logger.info("acknowledged={}", response.acknowledged());
  14. }
复制代码
3.2.2、修改 _mapping 信息

字段可以新增,已有的字段只能修改字段的 search_analyzer 属性。
  1. @Test
  2. public void modifyIndex() throws IOException {
  3.     PutMappingResponse response = client.indices().putMapping(typeMappingBuilder -> typeMappingBuilder
  4.             .index(INDEX_NAME)
  5.             .properties("age", propertyBuilder -> propertyBuilder.integer(integerNumberPropertyBuilder -> integerNumberPropertyBuilder))
  6.             .properties("name", propertyBuilder -> propertyBuilder.keyword(keywordPropertyBuilder -> keywordPropertyBuilder))
  7.             .properties("poems", propertyBuilder -> propertyBuilder.text(textPropertyBuilder -> textPropertyBuilder.analyzer("ik_max_word").searchAnalyzer("ik_smart")))
  8.     );
  9.     logger.info("acknowledged={}", response.acknowledged());
  10. }
复制代码
3.2.3、删除索引
  1. @Test
  2. public void deleteIndex() throws IOException {
  3.     DeleteIndexResponse response = client.indices().delete(builder -> builder.index(INDEX_NAME));
  4.     logger.info("acknowledged={}", response.acknowledged());
  5. }
复制代码
3.2.4、查询索引列表
  1. @Test
  2. public void getIndex() throws IOException {
  3.     //使用 * 也可以
  4.     GetIndexResponse response = client.indices().get(builder -> builder.index("_all"));
  5.     logger.info(response.result().toString());
  6. }
复制代码
3.2.5、查询索引详情
  1. @Test
  2. public void getIndexDetail() throws IOException {
  3.     GetIndexResponse response = client.indices().get(builder -> builder.index(INDEX_NAME));
  4.     logger.info(response.result().toString());
  5. }
复制代码
3.3、文档

3.3.1、创建文档
  1. @Test
  2. public void createDoc() throws IOException {
  3.     Map<String, Object> doc = new HashMap<>();
  4.     doc.put("age", 30);
  5.     doc.put("name", "李白");
  6.     doc.put("poems", "静夜思");
  7.     doc.put("about", "字太白");
  8.     doc.put("success", "创造了古代浪漫主义文学高峰、歌行体和七绝达到后人难及的高度");
  9.     CreateResponse response = client.create(builder -> builder.index(INDEX_NAME).id("1").document(doc));
  10.     logger.info(response.toString());
  11.     Poet poet = new Poet(31, "杜甫", "登高", "字子美", "唐代伟大的现实主义文学作家,唐诗思想艺术的集大成者");
  12.     response = client.create(builder -> builder.index(INDEX_NAME).id("2").document(poet));
  13.     logger.info(response.toString());
  14. }
复制代码
3.3.2、删除文档
  1. @Test
  2. public void deleteDoc() throws IOException {
  3.     DeleteResponse response = client.delete(builder -> builder.index(INDEX_NAME).id("1"));
  4.     logger.info(response.toString());
  5. }
复制代码
3.3.3、修改文档

修改文档,只修改设置的字段。
  1. @Test
  2. public void updateDoc() throws IOException {
  3.     Map<String, Object> doc = new HashMap<>();
  4.     doc.put("age", 33);
  5.     doc.put("name", "李白2");
  6.     UpdateResponse response = client.update(builder -> builder.index(INDEX_NAME).id("1").doc(doc), Map.class);
  7.     logger.info(response.toString());
  8.     Poet poet = new Poet();
  9.     poet.setAge(40);
  10.     poet.setName("杜甫2");
  11.     response = client.update(builder -> builder.index(INDEX_NAME).id("2").doc(poet).docAsUpsert(true), Poet.class);
  12.     logger.info(response.toString());
  13. }
复制代码
3.3.4、新增或修改文档

新增或修改文档,修改时所有的字段都会覆盖(相当于先删除在新增)。
  1. @Test
  2. public void createOrUpdateDoc() throws IOException {
  3.     Map<String, Object> doc = new HashMap<>();
  4.     doc.put("age", 33);
  5.     doc.put("name", "李白2");
  6.     //只更新设置的字段
  7.     IndexResponse response = client.index(builder -> builder.index(INDEX_NAME).id("1").document(doc));
  8.     logger.info(response.toString());
  9.     Poet poet = new Poet();
  10.     poet.setAge(40);
  11.     poet.setName("杜甫2");
  12.     response = client.index(builder -> builder.index(INDEX_NAME).id("2").document(poet));
  13.     logger.info(response.toString());
  14. }
复制代码
3.3.5、批量操作
  1. @Test
  2. public void bulk() throws IOException {
  3.     List<BulkOperation> list = new ArrayList<>();
  4.     //批量新增
  5.     for (int i = 0; i < 5; i++) {
  6.         Map<String, Object> doc = new HashMap<>();
  7.         doc.put("age", 30);
  8.         doc.put("name", "李白" + i);
  9.         doc.put("poems", "静夜思");
  10.         doc.put("about", "字太白");
  11.         doc.put("success", "创造了古代浪漫主义文学高峰、歌行体和七绝达到后人难及的高度");
  12.         String id = 10 + i + "";
  13.         list.add(new BulkOperation.Builder().create(builder -> builder.index(INDEX_NAME).id(id).document(doc)).build());
  14.     }
  15.     for (int i = 0; i < 5; i++) {
  16.         Poet poet = new Poet(31, "杜甫" + i, "登高", "字子美", "唐代伟大的现实主义文学作家,唐诗思想艺术的集大成者");
  17.         String id = 20 + i + "";
  18.         list.add(new BulkOperation.Builder().create(builder -> builder.index(INDEX_NAME).id(id).document(poet)).build());
  19.     }
  20.     //批量删除
  21.     list.add(new BulkOperation.Builder().delete(builder -> builder.index(INDEX_NAME).id("1")).build());
  22.     list.add(new BulkOperation.Builder().delete(builder -> builder.index(INDEX_NAME).id("2")).build());
  23.     BulkResponse response = client.bulk(builder -> builder.index(INDEX_NAME).operations(list));
  24.     logger.info(response.toString());
  25. }
复制代码
3.4、查询

3.4.1、查询所有文档
  1. @Test
  2. public void getDocAll() throws IOException {
  3.     SearchResponse<Map> response = client.search(builder -> builder.index(INDEX_NAME), Map.class);
  4.     logger.info(response.toString());
  5. }
复制代码
3.4.2、查询单个文档
  1. @Test
  2. public void getDoc() throws IOException {
  3.     GetResponse<Map> response = client.get(builder -> builder.index(INDEX_NAME).id("1"), Map.class);
  4.     if (response.found()) {
  5.         logger.info(response.source().toString());
  6.     }
  7.     GetResponse<Poet> response2 = client.get(builder -> builder.index(INDEX_NAME).id("2"), Poet.class);
  8.     if (response2.found()) {
  9.         logger.info(response2.source().toString());
  10.     }
  11. }
复制代码
3.4.3、term/terms 查询

term/terms查询,对输入内容不做分词处理。
  1. @Test
  2. public void searchTerm() throws IOException {
  3.     SearchResponse<Map> response = client.search(searchRequestBuilder -> searchRequestBuilder
  4.             .index(INDEX_NAME)
  5.             .query(queryBuilder -> queryBuilder
  6.                     .term(termQueryBuilder -> termQueryBuilder
  7.                             .field("name").value("李白")))
  8.             .sort(sortOptionsBuilder -> sortOptionsBuilder
  9.                     .field(fieldSortBuilder -> fieldSortBuilder
  10.                             .field("name").order(SortOrder.Asc)))
  11.             .source(sourceConfigBuilder -> sourceConfigBuilder
  12.                     .filter(sourceFilterBuilder -> sourceFilterBuilder
  13.                             .includes("age", "name")))
  14.             .from(0)
  15.             .size(10)
  16.             , Map.class);
  17.     logger.info(response.toString());
  18.     List<FieldValue> words = new ArrayList<>();
  19.     words.add(new FieldValue.Builder().stringValue("李白").build());
  20.     words.add(new FieldValue.Builder().stringValue("杜甫").build());
  21.     SearchResponse<Poet> response2 = client.search(searchRequestBuilder -> searchRequestBuilder
  22.                     .index(INDEX_NAME)
  23.                     .query(queryBuilder -> queryBuilder
  24.                             .terms(termsQueryBuilder -> termsQueryBuilder
  25.                                     .field("name").terms(termsQueryFieldBuilder -> termsQueryFieldBuilder.value(words))))
  26.                     .source(sourceConfigBuilder -> sourceConfigBuilder
  27.                             .filter(sourceFilterBuilder -> sourceFilterBuilder
  28.                                     .excludes("about")))
  29.                     .from(0)
  30.                     .size(10)
  31.             , Poet.class);
  32.     logger.info(response2.toString());
  33. }
复制代码
3.4.4、range(范围) 查询
  1. @Test
  2. public void searchRange() throws IOException {
  3.     SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  4.                     .index(INDEX_NAME)
  5.                     .query(queryBuilder -> queryBuilder
  6.                             .range(rangeQueryBuilder -> rangeQueryBuilder
  7.                                     .field("age").gte(JsonData.of("20")).lt(JsonData.of("40"))))
  8.             , Poet.class);
  9.     logger.info(response.toString());
  10. }
复制代码
3.4.5、全文查询

3.4.5.1、match 查询

match 查询,对输入内容先分词再查询。
  1. @Test
  2. public void searchMatch() throws IOException {
  3.     SearchResponse<Map> response = client.search(searchRequestBuilder -> searchRequestBuilder
  4.                     .index(INDEX_NAME)
  5.                     .query(queryBuilder -> queryBuilder
  6.                             .match(matchQueryBuilder -> matchQueryBuilder
  7.                                     .field("success").query("思想")))
  8.             , Map.class);
  9.     logger.info(response.toString());
  10. }
复制代码
3.4.5.2、multi_match 查询

多个字段进行匹配。
  1. @Test
  2. public void searchMultiMatch() throws IOException {
  3.     SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  4.                     .index(INDEX_NAME)
  5.                     .query(queryBuilder -> queryBuilder
  6.                             .multiMatch(multiMatchQueryBuilder -> multiMatchQueryBuilder
  7.                                     .fields("about", "success").query("思想")))
  8.             , Poet.class);
  9.     logger.info(response.toString());
  10. }
复制代码
3.4.5.3、match_phrase 查询

匹配整个查询字符串。
  1. @Test
  2. public void searchMatchPhrase() throws IOException {
  3.     SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  4.                     .index(INDEX_NAME)
  5.                     .query(queryBuilder -> queryBuilder
  6.                             .matchPhrase(matchPhraseQueryBuilder -> matchPhraseQueryBuilder.field("success").query("文学作家")))
  7.             , Poet.class);
  8.     logger.info(response.toString());
  9. }
复制代码
3.4.5.4、match_all 查询

查询所有文档。
  1. @Test
  2. public void searchMatchAll() throws IOException {
  3.     SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  4.                     .index(INDEX_NAME)
  5.                     .query(queryBuilder -> queryBuilder
  6.                             .matchAll(matchAllQueryBuilder -> matchAllQueryBuilder))
  7.             , Poet.class);
  8.     logger.info(response.toString());
  9. }
复制代码
3.4.5.5、query_string 查询

query_string 可以同时实现前面几种查询方法。
  1. @Test
  2. public void searchQueryString() throws IOException {
  3.     //类似 match
  4.     SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  5.                     .index(INDEX_NAME)
  6.                     .query(queryBuilder -> queryBuilder
  7.                             .queryString(queryStringQueryBuilder -> queryStringQueryBuilder
  8.                                 .defaultField("success").query("古典文学")))
  9.             , Poet.class);
  10.     logger.info(response.toString());
  11.     //类似 mulit_match
  12.     response = client.search(searchRequestBuilder -> searchRequestBuilder
  13.                     .index(INDEX_NAME)
  14.                     .query(queryBuilder -> queryBuilder
  15.                             .queryString(queryStringQueryBuilder -> queryStringQueryBuilder
  16.                                     .fields("about", "success").query("古典文学")))
  17.             , Poet.class);
  18.     logger.info(response.toString());
  19.     //类似 match_phrase
  20.     response = client.search(searchRequestBuilder -> searchRequestBuilder
  21.                     .index(INDEX_NAME)
  22.                     .query(queryBuilder -> queryBuilder
  23.                             .queryString(queryStringQueryBuilder -> queryStringQueryBuilder
  24.                                     .defaultField("success").query(""文学作家"")))
  25.             , Poet.class);
  26.     logger.info(response.toString());
  27.     //带运算符查询,运算符两边的词不再分词
  28.     //查询同时包含 ”文学“ 和 ”伟大“ 的文档
  29.     response = client.search(searchRequestBuilder -> searchRequestBuilder
  30.                     .index(INDEX_NAME)
  31.                     .query(queryBuilder -> queryBuilder
  32.                             .queryString(queryStringQueryBuilder -> queryStringQueryBuilder
  33.                                     .fields("success").query("文学 AND 伟大")))
  34.             , Poet.class);
  35.     logger.info(response.toString());
  36.     //等同上一个查询
  37.     response = client.search(searchRequestBuilder -> searchRequestBuilder
  38.                     .index(INDEX_NAME)
  39.                     .query(queryBuilder -> queryBuilder
  40.                             .queryString(queryStringQueryBuilder -> queryStringQueryBuilder
  41.                                     .fields("success").query("文学 伟大").defaultOperator(Operator.And)))
  42.             , Poet.class);
  43.     logger.info(response.toString());
  44.     //查询 name 或 success 字段包含"文学"和"伟大"这两个单词,或者包含"李白"这个单词的文档。
  45.     response = client.search(searchRequestBuilder -> searchRequestBuilder
  46.                     .index(INDEX_NAME)
  47.                     .query(queryBuilder -> queryBuilder
  48.                             .queryString(queryStringQueryBuilder -> queryStringQueryBuilder
  49.                                     .fields("name","success").query("(文学 AND 伟大) OR 高度")))
  50.             , Poet.class);
  51.     logger.info(response.toString());
  52. }
复制代码
3.4.5.6、simple_query_string 查询

类似 query_string,主要区别如下:
1、不支持AND OR NOT ,会当做字符处理;使用 + 代替 AND,| 代替OR,- 代替 NOT
2、会忽略错误的语法
  1. @Test
  2. public void searchSimpleQueryString() throws IOException {
  3.     //查询同时包含 ”文学“ 和 ”伟大“ 的文档
  4.     SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  5.                     .index(INDEX_NAME)
  6.                     .query(queryBuilder -> queryBuilder
  7.                             .simpleQueryString(simpleQueryStringQueryBuilder -> simpleQueryStringQueryBuilder
  8.                                     .fields("success").query("文学 + 伟大")))
  9.             , Poet.class);
  10.     logger.info(response.toString());
  11. }
复制代码
3.4.6、模糊查询
  1. @Test
  2. public void searchFuzzy() throws IOException {
  3.     //全文查询时使用模糊参数,先分词再计算模糊选项。
  4.     SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  5.                     .index(INDEX_NAME)
  6.                     .query(queryBuilder -> queryBuilder
  7.                             .match(matchQueryBuilder -> matchQueryBuilder
  8.                                     .field("success").query("思考").fuzziness("1")))
  9.             , Poet.class);
  10.     logger.info(response.toString());
  11.     //使用 fuzzy query,对输入不分词,直接计算模糊选项。
  12.     SearchResponse<Poet> response2 = client.search(searchRequestBuilder -> searchRequestBuilder
  13.                     .index(INDEX_NAME)
  14.                     .query(queryBuilder -> queryBuilder
  15.                             .fuzzy(fuzzyQueryBuilder ->  fuzzyQueryBuilder
  16.                                     .field("success").fuzziness("1").value("理想")))
  17.             , Poet.class);
  18.     logger.info(response2.toString());
  19. }
复制代码
3.4.7、组合查询
  1. @Test
  2. public void searchBool() throws IOException {
  3.     //查询 success 包含 “思想” 且 age 在 [20-40] 之间的文档
  4.     SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  5.             .index(INDEX_NAME)
  6.             .query(queryBuilder -> queryBuilder
  7.                     .bool(boolQueryBuilder -> boolQueryBuilder
  8.                             .must(queryBuilder2 -> queryBuilder2
  9.                                     .match(matchQueryBuilder -> matchQueryBuilder
  10.                                             .field("success").query("思想"))
  11.                             )
  12.                             .must(queryBuilder2 -> queryBuilder2
  13.                                     .range(rangeQueryBuilder -> rangeQueryBuilder
  14.                                             .field("age").gte(JsonData.of("20")).lt(JsonData.of("40")))
  15.                             )
  16.                     )
  17.             )
  18.     , Poet.class);
  19.     logger.info(response.toString());
  20.     //过滤出 success 包含 “思想” 且 age 在 [20-40] 之间的文档,不计算得分
  21.     SearchResponse<Poet> response2 = client.search(searchRequestBuilder -> searchRequestBuilder
  22.             .index(INDEX_NAME)
  23.             .query(queryBuilder -> queryBuilder
  24.                     .bool(boolQueryBuilder -> boolQueryBuilder
  25.                             .filter(queryBuilder2 -> queryBuilder2
  26.                                     .match(matchQueryBuilder -> matchQueryBuilder
  27.                                             .field("success").query("思想"))
  28.                             )
  29.                             .filter(queryBuilder2 -> queryBuilder2
  30.                                     .range(rangeQueryBuilder -> rangeQueryBuilder
  31.                                             .field("age").gte(JsonData.of("20")).lt(JsonData.of("40")))
  32.                             )
  33.                     )
  34.             )
  35.     , Poet.class);
  36.     logger.info(response2.toString());
  37. }
复制代码
3.4.8、聚合查询
  1. @Test
  2. public void searchAggs() throws IOException {
  3.     //求和
  4.     SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  5.                     .index(INDEX_NAME)
  6.                     .aggregations("age_sum", aggregationBuilder -> aggregationBuilder
  7.                             .sum(sumAggregationBuilder -> sumAggregationBuilder
  8.                                     .field("age")))
  9.             , Poet.class);
  10.     logger.info(response.toString());
  11.     //类似 select count distinct(age) from poet-index
  12.     response = client.search(searchRequestBuilder -> searchRequestBuilder
  13.                     .index(INDEX_NAME)
  14.                     .aggregations("age_count", aggregationBuilder -> aggregationBuilder
  15.                             .cardinality(cardinalityAggregationBuilder -> cardinalityAggregationBuilder.field("age")))
  16.             , Poet.class);
  17.     logger.info(response.toString());
  18.     //数量、最大、最小、平均、求和
  19.     response = client.search(searchRequestBuilder -> searchRequestBuilder
  20.                     .index(INDEX_NAME)
  21.                     .aggregations("age_stats", aggregationBuilder -> aggregationBuilder
  22.                             .stats(statsAggregationBuilder -> statsAggregationBuilder
  23.                                     .field("age")))
  24.             , Poet.class);
  25.     logger.info(response.toString());
  26.     //select name,count(*) from poet-index group by name
  27.     response = client.search(searchRequestBuilder -> searchRequestBuilder
  28.                     .index(INDEX_NAME)
  29.                     .aggregations("name_terms", aggregationBuilder -> aggregationBuilder
  30.                             .terms(termsAggregationBuilder -> termsAggregationBuilder
  31.                                     .field("name")))
  32.             , Poet.class);
  33.     logger.info(response.toString());
  34.     //select name,age,count(*) from poet-index group by name,age
  35.     response = client.search(searchRequestBuilder -> searchRequestBuilder
  36.                     .index(INDEX_NAME)
  37.                     .aggregations("name_terms", aggregationBuilder -> aggregationBuilder
  38.                             .terms(termsAggregationBuilder -> termsAggregationBuilder
  39.                                     .field("name")
  40.                             )
  41.                             .aggregations("age_terms", aggregationBuilder2 -> aggregationBuilder2
  42.                                     .terms(termsAggregationBuilder -> termsAggregationBuilder
  43.                                             .field("age")
  44.                                     ))
  45.                     )
  46.             , Poet.class);
  47.     logger.info(response.toString());
  48.     //类似 select avg(age) from poet-index where name='李白'
  49.     response = client.search(searchRequestBuilder -> searchRequestBuilder
  50.                     .index(INDEX_NAME)
  51.                     .query(queryBuilder -> queryBuilder
  52.                             .bool(boolQueryBuilder -> boolQueryBuilder
  53.                                     .filter(queryBuilder2 -> queryBuilder2
  54.                                             .term(termQueryBuilder -> termQueryBuilder
  55.                                                     .field("name").value("李白")))))
  56.                     .aggregations("ave_age", aggregationBuilder -> aggregationBuilder
  57.                             .avg(averageAggregationBuilder -> averageAggregationBuilder.field("age")))
  58.             , Poet.class);
  59.     logger.info(response.toString());
  60. }
复制代码
3.4.9、推荐搜索
  1. @Test
  2. public void searchSuggest() throws IOException {
  3.     SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  4.                     .index(INDEX_NAME)
  5.                     .suggest(suggesterBuilder -> suggesterBuilder
  6.                             .suggesters("success_suggest", fieldSuggesterBuilder -> fieldSuggesterBuilder
  7.                                     .text("思考")
  8.                                     .term(termSuggesterBuilder -> termSuggesterBuilder
  9.                                             .field("success")
  10.                                             .suggestMode(SuggestMode.Always)
  11.                                             .minWordLength(2)
  12.                                     )
  13.                             )
  14.                     )
  15.             , Poet.class);
  16.     logger.info(response.toString());
  17. }
复制代码
该测试会报如下错误:
  1. co.elastic.clients.json.JsonpMappingException: Error deserializing co.elastic.clients.elasticsearch.core.search.TermSuggest: co.elastic.clients.json.UnexpectedJsonEventException: Unexpected JSON event 'START_ARRAY' instead of '[START_OBJECT, KEY_NAME]' (JSON path: suggest['term#success_suggest'][0].options) (line no=1, column no=247, offset=-1)
复制代码
还有高手知道原因?
3.4.10、高亮显示
  1. @Test
  2. public void searchHighlight() throws IOException {
  3.     SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  4.                 .index(INDEX_NAME)
  5.                 .query(queryBuilder -> queryBuilder
  6.                         .match(matchQueryBuilder -> matchQueryBuilder
  7.                                 .field("success").query("思想")))
  8.                 .highlight(highlightBuilder -> highlightBuilder
  9.                         .preTags("<span color='red'>")
  10.                         .postTags("</span>")
  11.                         .fields("success", highlightFieldBuilder -> highlightFieldBuilder))
  12.         , Poet.class);
  13.     logger.info(response.toString());
  14. }
复制代码
3.4.11、SQL 查询
  1. @Test
  2. public void searchSql() throws IOException {
  3.     QueryResponse response = client.sql().query(builder -> builder
  4.             .format("json").query("SELECT * FROM "" + INDEX_NAME + "" limit 3"));
  5.     logger.info(response.toString());
  6. }
复制代码
该测试会报如下错误:
  1. co.elastic.clients.json.JsonpMappingException: Error deserializing co.elastic.clients.elasticsearch.sql.QueryResponse: java.lang.UnsupportedOperationException (JSON path: rows[0][0]) (line no=1, column no=184, offset=-1)
复制代码
还有高手知道原因?
3.5、完整代码

  1. package com.abc.demo.es;
  2. import co.elastic.clients.elasticsearch.ElasticsearchClient;
  3. import co.elastic.clients.elasticsearch._types.*;
  4. import co.elastic.clients.elasticsearch._types.aggregations.AverageAggregation;
  5. import co.elastic.clients.elasticsearch._types.aggregations.CardinalityAggregation;
  6. import co.elastic.clients.elasticsearch._types.aggregations.SumAggregation;
  7. import co.elastic.clients.elasticsearch._types.query_dsl.*;
  8. import co.elastic.clients.elasticsearch.cat.IndicesResponse;
  9. import co.elastic.clients.elasticsearch.core.*;
  10. import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
  11. import co.elastic.clients.elasticsearch.indices.*;
  12. import co.elastic.clients.elasticsearch.sql.QueryResponse;
  13. import co.elastic.clients.json.JsonData;
  14. import co.elastic.clients.json.jackson.JacksonJsonpMapper;
  15. import co.elastic.clients.transport.ElasticsearchTransport;
  16. import co.elastic.clients.transport.rest_client.RestClientTransport;
  17. import com.fasterxml.jackson.databind.ObjectMapper;
  18. import lombok.AllArgsConstructor;
  19. import lombok.Data;
  20. import lombok.NoArgsConstructor;
  21. import org.apache.http.HttpHost;
  22. import org.elasticsearch.client.RestClient;
  23. import org.junit.After;
  24. import org.junit.Before;
  25. import org.junit.Test;
  26. import org.slf4j.Logger;
  27. import org.slf4j.LoggerFactory;
  28. import java.io.IOException;
  29. import java.util.ArrayList;
  30. import java.util.HashMap;
  31. import java.util.List;
  32. import java.util.Map;
  33. public class ElasticsearchJavaCase {
  34.     private static final Logger logger = LoggerFactory.getLogger(ElasticsearchJavaCase.class.getName());
  35.     private static final String INDEX_NAME = "poet-index";
  36.     private ElasticsearchTransport transport;
  37.     private ElasticsearchClient client;
  38.     @Before
  39.     public void before() {
  40.         RestClient restClient = RestClient.builder(
  41.                 new HttpHost("10.49.196.10", 9200),
  42.                 new HttpHost("10.49.196.11", 9200),
  43.                 new HttpHost("10.49.196.12", 9200)).build();
  44.         ObjectMapper objectMapper = new ObjectMapper();
  45.         transport = new RestClientTransport(restClient, new JacksonJsonpMapper(objectMapper));
  46.         client = new ElasticsearchClient(transport);
  47.     }
  48.     @After
  49.     public void after() throws IOException {
  50.         transport.close();
  51.     }
  52.     /**
  53.      * 创建索引
  54.      */
  55.     @Test
  56.     public void createIndex() throws IOException {
  57.         CreateIndexResponse response = client.indices().create(builder -> builder
  58.                 .settings(indexSettingsBuilder -> indexSettingsBuilder.numberOfReplicas("1").numberOfShards("2"))
  59.                 .mappings(typeMappingBuilder -> typeMappingBuilder
  60.                         .properties("age", propertyBuilder -> propertyBuilder.integer(integerNumberPropertyBuilder -> integerNumberPropertyBuilder))
  61.                         .properties("name", propertyBuilder -> propertyBuilder.keyword(keywordPropertyBuilder -> keywordPropertyBuilder))
  62.                         .properties("poems", propertyBuilder -> propertyBuilder.text(textPropertyBuilder -> textPropertyBuilder.analyzer("ik_max_word").searchAnalyzer("ik_max_word")))
  63.                         .properties("about", propertyBuilder -> propertyBuilder.text(textPropertyBuilder -> textPropertyBuilder.analyzer("ik_max_word").searchAnalyzer("ik_max_word")))
  64.                         .properties("success", propertyBuilder -> propertyBuilder.text(textPropertyBuilder -> textPropertyBuilder.analyzer("ik_max_word").searchAnalyzer("ik_max_word")))
  65.                 )
  66.                 .index(INDEX_NAME));
  67.         logger.info("acknowledged={}", response.acknowledged());
  68.     }
  69.     /**
  70.      * 修改索引的_mapping信息
  71.      * 字段可以新增,已有的字段只能修改字段的search_analyzer属性
  72.      */
  73.     @Test
  74.     public void modifyIndex() throws IOException {
  75.         PutMappingResponse response = client.indices().putMapping(typeMappingBuilder -> typeMappingBuilder
  76.                 .index(INDEX_NAME)
  77.                 .properties("age", propertyBuilder -> propertyBuilder.integer(integerNumberPropertyBuilder -> integerNumberPropertyBuilder))
  78.                 .properties("name", propertyBuilder -> propertyBuilder.keyword(keywordPropertyBuilder -> keywordPropertyBuilder))
  79.                 .properties("poems", propertyBuilder -> propertyBuilder.text(textPropertyBuilder -> textPropertyBuilder.analyzer("ik_max_word").searchAnalyzer("ik_smart")))
  80.         );
  81.         logger.info("acknowledged={}", response.acknowledged());
  82.     }
  83.     /**
  84.      * 删除索引
  85.      */
  86.     @Test
  87.     public void deleteIndex() throws IOException {
  88.         DeleteIndexResponse response = client.indices().delete(builder -> builder.index(INDEX_NAME));
  89.         logger.info("acknowledged={}", response.acknowledged());
  90.     }
  91.     /**
  92.      * 查询索引列表
  93.      */
  94.     @Test
  95.     public void getIndex() throws IOException {
  96.         //使用 * 也可以
  97.         GetIndexResponse response = client.indices().get(builder -> builder.index("_all"));
  98.         logger.info(response.result().toString());
  99.     }
  100.     /**
  101.      * 查询索引详情
  102.      */
  103.     @Test
  104.     public void getIndexDetail() throws IOException {
  105.         GetIndexResponse response = client.indices().get(builder -> builder.index(INDEX_NAME));
  106.         logger.info(response.result().toString());
  107.     }
  108.     /**
  109.      * 创建文档
  110.      */
  111.     @Test
  112.     public void createDoc() throws IOException {
  113.         Map<String, Object> doc = new HashMap<>();
  114.         doc.put("age", 30);
  115.         doc.put("name", "李白");
  116.         doc.put("poems", "静夜思");
  117.         doc.put("about", "字太白");
  118.         doc.put("success", "创造了古代浪漫主义文学高峰、歌行体和七绝达到后人难及的高度");
  119.         CreateResponse response = client.create(builder -> builder.index(INDEX_NAME).id("1").document(doc));
  120.         logger.info(response.toString());
  121.         Poet poet = new Poet(31, "杜甫", "登高", "字子美", "唐代伟大的现实主义文学作家,唐诗思想艺术的集大成者");
  122.         response = client.create(builder -> builder.index(INDEX_NAME).id("2").document(poet));
  123.         logger.info(response.toString());
  124.     }
  125.     /**
  126.      * 删除文档
  127.      */
  128.     @Test
  129.     public void deleteDoc() throws IOException {
  130.         DeleteResponse response = client.delete(builder -> builder.index(INDEX_NAME).id("1"));
  131.         logger.info(response.toString());
  132.     }
  133.     /**
  134.      * 修改文档,只修改设置的字段
  135.      */
  136.     @Test
  137.     public void updateDoc() throws IOException {
  138.         Map<String, Object> doc = new HashMap<>();
  139.         doc.put("age", 33);
  140.         doc.put("name", "李白2");
  141.         UpdateResponse response = client.update(builder -> builder.index(INDEX_NAME).id("1").doc(doc), Map.class);
  142.         logger.info(response.toString());
  143.         Poet poet = new Poet();
  144.         poet.setAge(40);
  145.         poet.setName("杜甫2");
  146.         response = client.update(builder -> builder.index(INDEX_NAME).id("2").doc(poet).docAsUpsert(true), Poet.class);
  147.         logger.info(response.toString());
  148.     }
  149.     /**
  150.      * 新增或修改文档,修改时所有的字段都会覆盖(相当于先删除在新增)
  151.      */
  152.     @Test
  153.     public void createOrUpdateDoc() throws IOException {
  154.         Map<String, Object> doc = new HashMap<>();
  155.         doc.put("age", 33);
  156.         doc.put("name", "李白2");
  157.         //只更新设置的字段
  158.         IndexResponse response = client.index(builder -> builder.index(INDEX_NAME).id("1").document(doc));
  159.         logger.info(response.toString());
  160.         Poet poet = new Poet();
  161.         poet.setAge(40);
  162.         poet.setName("杜甫2");
  163.         response = client.index(builder -> builder.index(INDEX_NAME).id("2").document(poet));
  164.         logger.info(response.toString());
  165.     }
  166.     /**
  167.      * 批量操作
  168.      */
  169.     @Test
  170.     public void bulk() throws IOException {
  171.         List<BulkOperation> list = new ArrayList<>();
  172.         //批量新增
  173.         for (int i = 0; i < 5; i++) {
  174.             Map<String, Object> doc = new HashMap<>();
  175.             doc.put("age", 30);
  176.             doc.put("name", "李白" + i);
  177.             doc.put("poems", "静夜思");
  178.             doc.put("about", "字太白");
  179.             doc.put("success", "创造了古代浪漫主义文学高峰、歌行体和七绝达到后人难及的高度");
  180.             String id = 10 + i + "";
  181.             list.add(new BulkOperation.Builder().create(builder -> builder.index(INDEX_NAME).id(id).document(doc)).build());
  182.         }
  183.         for (int i = 0; i < 5; i++) {
  184.             Poet poet = new Poet(31, "杜甫" + i, "登高", "字子美", "唐代伟大的现实主义文学作家,唐诗思想艺术的集大成者");
  185.             String id = 20 + i + "";
  186.             list.add(new BulkOperation.Builder().create(builder -> builder.index(INDEX_NAME).id(id).document(poet)).build());
  187.         }
  188.         //批量删除
  189.         list.add(new BulkOperation.Builder().delete(builder -> builder.index(INDEX_NAME).id("1")).build());
  190.         list.add(new BulkOperation.Builder().delete(builder -> builder.index(INDEX_NAME).id("2")).build());
  191.         BulkResponse response = client.bulk(builder -> builder.index(INDEX_NAME).operations(list));
  192.         logger.info(response.toString());
  193.     }
  194.     /**
  195.      * 查询索有文档
  196.      */
  197.     @Test
  198.     public void getDocAll() throws IOException {
  199.         SearchResponse<Map> response = client.search(builder -> builder.index(INDEX_NAME), Map.class);
  200.         logger.info(response.toString());
  201.     }
  202.     /**
  203.      * 查询单个文档
  204.      */
  205.     @Test
  206.     public void getDoc() throws IOException {
  207.         GetResponse<Map> response = client.get(builder -> builder.index(INDEX_NAME).id("1"), Map.class);
  208.         if (response.found()) {
  209.             logger.info(response.source().toString());
  210.         }
  211.         GetResponse<Poet> response2 = client.get(builder -> builder.index(INDEX_NAME).id("2"), Poet.class);
  212.         if (response2.found()) {
  213.             logger.info(response2.source().toString());
  214.         }
  215.     }
  216.     /**
  217.      * term/terms查询,对输入内容不做分词处理
  218.      */
  219.     @Test
  220.     public void searchTerm() throws IOException {
  221.         SearchResponse<Map> response = client.search(searchRequestBuilder -> searchRequestBuilder
  222.                 .index(INDEX_NAME)
  223.                 .query(queryBuilder -> queryBuilder
  224.                         .term(termQueryBuilder -> termQueryBuilder
  225.                                 .field("name").value("李白")))
  226.                 .sort(sortOptionsBuilder -> sortOptionsBuilder
  227.                         .field(fieldSortBuilder -> fieldSortBuilder
  228.                                 .field("name").order(SortOrder.Asc)))
  229.                 .source(sourceConfigBuilder -> sourceConfigBuilder
  230.                         .filter(sourceFilterBuilder -> sourceFilterBuilder
  231.                                 .includes("age", "name")))
  232.                 .from(0)
  233.                 .size(10)
  234.                 , Map.class);
  235.         logger.info(response.toString());
  236.         List<FieldValue> words = new ArrayList<>();
  237.         words.add(new FieldValue.Builder().stringValue("李白").build());
  238.         words.add(new FieldValue.Builder().stringValue("杜甫").build());
  239.         SearchResponse<Poet> response2 = client.search(searchRequestBuilder -> searchRequestBuilder
  240.                         .index(INDEX_NAME)
  241.                         .query(queryBuilder -> queryBuilder
  242.                                 .terms(termsQueryBuilder -> termsQueryBuilder
  243.                                         .field("name").terms(termsQueryFieldBuilder -> termsQueryFieldBuilder.value(words))))
  244.                         .source(sourceConfigBuilder -> sourceConfigBuilder
  245.                                 .filter(sourceFilterBuilder -> sourceFilterBuilder
  246.                                         .excludes("about")))
  247.                         .from(0)
  248.                         .size(10)
  249.                 , Poet.class);
  250.         logger.info(response2.toString());
  251.     }
  252.     /**
  253.      * range查询,范围查询
  254.      */
  255.     @Test
  256.     public void searchRange() throws IOException {
  257.         SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  258.                         .index(INDEX_NAME)
  259.                         .query(queryBuilder -> queryBuilder
  260.                                 .range(rangeQueryBuilder -> rangeQueryBuilder
  261.                                         .field("age").gte(JsonData.of("20")).lt(JsonData.of("40"))))
  262.                 , Poet.class);
  263.         logger.info(response.toString());
  264.     }
  265.     /**
  266.      * match查询,对输入内容先分词再查询
  267.      */
  268.     @Test
  269.     public void searchMatch() throws IOException {
  270.         SearchResponse<Map> response = client.search(searchRequestBuilder -> searchRequestBuilder
  271.                         .index(INDEX_NAME)
  272.                         .query(queryBuilder -> queryBuilder
  273.                                 .match(matchQueryBuilder -> matchQueryBuilder
  274.                                         .field("success").query("思想")))
  275.                 , Map.class);
  276.         logger.info(response.toString());
  277.     }
  278.     /**
  279.      * multi_match查询,-
  280.      */
  281.     @Test
  282.     public void searchMultiMatch() throws IOException {
  283.         SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  284.                         .index(INDEX_NAME)
  285.                         .query(queryBuilder -> queryBuilder
  286.                                 .multiMatch(multiMatchQueryBuilder -> multiMatchQueryBuilder
  287.                                         .fields("about", "success").query("思想")))
  288.                 , Poet.class);
  289.         logger.info(response.toString());
  290.     }
  291.     /**
  292.      * match_phrase 查询,匹配整个查询字符串
  293.      */
  294.     @Test
  295.     public void searchMatchPhrase() throws IOException {
  296.         SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  297.                         .index(INDEX_NAME)
  298.                         .query(queryBuilder -> queryBuilder
  299.                                 .matchPhrase(matchPhraseQueryBuilder -> matchPhraseQueryBuilder.field("success").query("文学作家")))
  300.                 , Poet.class);
  301.         logger.info(response.toString());
  302.     }
  303.     /**
  304.      * match_all 查询,查询所有
  305.      */
  306.     @Test
  307.     public void searchMatchAll() throws IOException {
  308.         SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  309.                         .index(INDEX_NAME)
  310.                         .query(queryBuilder -> queryBuilder
  311.                                 .matchAll(matchAllQueryBuilder -> matchAllQueryBuilder))
  312.                 , Poet.class);
  313.         logger.info(response.toString());
  314.     }
  315.     /**
  316.      * query_string 查询
  317.      */
  318.     @Test
  319.     public void searchQueryString() throws IOException {
  320.         //类似 match
  321.         SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  322.                         .index(INDEX_NAME)
  323.                         .query(queryBuilder -> queryBuilder
  324.                                 .queryString(queryStringQueryBuilder -> queryStringQueryBuilder
  325.                                     .defaultField("success").query("古典文学")))
  326.                 , Poet.class);
  327.         logger.info(response.toString());
  328.         //类似 mulit_match
  329.         response = client.search(searchRequestBuilder -> searchRequestBuilder
  330.                         .index(INDEX_NAME)
  331.                         .query(queryBuilder -> queryBuilder
  332.                                 .queryString(queryStringQueryBuilder -> queryStringQueryBuilder
  333.                                         .fields("about", "success").query("古典文学")))
  334.                 , Poet.class);
  335.         logger.info(response.toString());
  336.         //类似 match_phrase
  337.         response = client.search(searchRequestBuilder -> searchRequestBuilder
  338.                         .index(INDEX_NAME)
  339.                         .query(queryBuilder -> queryBuilder
  340.                                 .queryString(queryStringQueryBuilder -> queryStringQueryBuilder
  341.                                         .defaultField("success").query(""文学作家"")))
  342.                 , Poet.class);
  343.         logger.info(response.toString());
  344.         //带运算符查询,运算符两边的词不再分词
  345.         //查询同时包含 ”文学“ 和 ”伟大“ 的文档
  346.         response = client.search(searchRequestBuilder -> searchRequestBuilder
  347.                         .index(INDEX_NAME)
  348.                         .query(queryBuilder -> queryBuilder
  349.                                 .queryString(queryStringQueryBuilder -> queryStringQueryBuilder
  350.                                         .fields("success").query("文学 AND 伟大")))
  351.                 , Poet.class);
  352.         logger.info(response.toString());
  353.         //等同上一个查询
  354.         response = client.search(searchRequestBuilder -> searchRequestBuilder
  355.                         .index(INDEX_NAME)
  356.                         .query(queryBuilder -> queryBuilder
  357.                                 .queryString(queryStringQueryBuilder -> queryStringQueryBuilder
  358.                                         .fields("success").query("文学 伟大").defaultOperator(Operator.And)))
  359.                 , Poet.class);
  360.         logger.info(response.toString());
  361.         //查询 name 或 success 字段包含"文学"和"伟大"这两个单词,或者包含"李白"这个单词的文档。
  362.         response = client.search(searchRequestBuilder -> searchRequestBuilder
  363.                         .index(INDEX_NAME)
  364.                         .query(queryBuilder -> queryBuilder
  365.                                 .queryString(queryStringQueryBuilder -> queryStringQueryBuilder
  366.                                         .fields("name","success").query("(文学 AND 伟大) OR 高度")))
  367.                 , Poet.class);
  368.         logger.info(response.toString());
  369.     }
  370.     /**
  371.      * simple_query_string 查询,和query_string类似
  372.      * 不支持AND OR NOT,会当做字符串处理
  373.      * 使用 +替代AND,|替代OR,-替代NOT
  374.      */
  375.     @Test
  376.     public void searchSimpleQueryString() throws IOException {
  377.         //查询同时包含 ”文学“ 和 ”伟大“ 的文档
  378.         SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  379.                         .index(INDEX_NAME)
  380.                         .query(queryBuilder -> queryBuilder
  381.                                 .simpleQueryString(simpleQueryStringQueryBuilder -> simpleQueryStringQueryBuilder
  382.                                         .fields("success").query("文学 + 伟大")))
  383.                 , Poet.class);
  384.         logger.info(response.toString());
  385.     }
  386.     /**
  387.      * 模糊查询
  388.      */
  389.     @Test
  390.     public void searchFuzzy() throws IOException {
  391.         //全文查询时使用模糊参数,先分词再计算模糊选项。
  392.         SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  393.                         .index(INDEX_NAME)
  394.                         .query(queryBuilder -> queryBuilder
  395.                                 .match(matchQueryBuilder -> matchQueryBuilder
  396.                                         .field("success").query("思考").fuzziness("1")))
  397.                 , Poet.class);
  398.         logger.info(response.toString());
  399.         //使用 fuzzy query,对输入不分词,直接计算模糊选项。
  400.         SearchResponse<Poet> response2 = client.search(searchRequestBuilder -> searchRequestBuilder
  401.                         .index(INDEX_NAME)
  402.                         .query(queryBuilder -> queryBuilder
  403.                                 .fuzzy(fuzzyQueryBuilder ->  fuzzyQueryBuilder
  404.                                         .field("success").fuzziness("1").value("理想")))
  405.                 , Poet.class);
  406.         logger.info(response2.toString());
  407.     }
  408.     /**
  409.      * bool查询,组合查询
  410.      */
  411.     @Test
  412.     public void searchBool() throws IOException {
  413.         //查询 success 包含 “思想” 且 age 在 [20-40] 之间的文档
  414.         SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  415.                 .index(INDEX_NAME)
  416.                 .query(queryBuilder -> queryBuilder
  417.                         .bool(boolQueryBuilder -> boolQueryBuilder
  418.                                 .must(queryBuilder2 -> queryBuilder2
  419.                                         .match(matchQueryBuilder -> matchQueryBuilder
  420.                                                 .field("success").query("思想"))
  421.                                 )
  422.                                 .must(queryBuilder2 -> queryBuilder2
  423.                                         .range(rangeQueryBuilder -> rangeQueryBuilder
  424.                                                 .field("age").gte(JsonData.of("20")).lt(JsonData.of("40")))
  425.                                 )
  426.                         )
  427.                 )
  428.         , Poet.class);
  429.         logger.info(response.toString());
  430.         //过滤出 success 包含 “思想” 且 age 在 [20-40] 之间的文档,不计算得分
  431.         SearchResponse<Poet> response2 = client.search(searchRequestBuilder -> searchRequestBuilder
  432.                 .index(INDEX_NAME)
  433.                 .query(queryBuilder -> queryBuilder
  434.                         .bool(boolQueryBuilder -> boolQueryBuilder
  435.                                 .filter(queryBuilder2 -> queryBuilder2
  436.                                         .match(matchQueryBuilder -> matchQueryBuilder
  437.                                                 .field("success").query("思想"))
  438.                                 )
  439.                                 .filter(queryBuilder2 -> queryBuilder2
  440.                                         .range(rangeQueryBuilder -> rangeQueryBuilder
  441.                                                 .field("age").gte(JsonData.of("20")).lt(JsonData.of("40")))
  442.                                 )
  443.                         )
  444.                 )
  445.         , Poet.class);
  446.         logger.info(response2.toString());
  447.     }
  448.     /**
  449.      * aggs查询,聚合查询
  450.      */
  451.     @Test
  452.     public void searchAggs() throws IOException {
  453.         //求和
  454.         SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  455.                         .index(INDEX_NAME)
  456.                         .aggregations("age_sum", aggregationBuilder -> aggregationBuilder
  457.                                 .sum(sumAggregationBuilder -> sumAggregationBuilder
  458.                                         .field("age")))
  459.                 , Poet.class);
  460.         logger.info(response.toString());
  461.         //类似 select count distinct(age) from poet-index
  462.         response = client.search(searchRequestBuilder -> searchRequestBuilder
  463.                         .index(INDEX_NAME)
  464.                         .aggregations("age_count", aggregationBuilder -> aggregationBuilder
  465.                                 .cardinality(cardinalityAggregationBuilder -> cardinalityAggregationBuilder.field("age")))
  466.                 , Poet.class);
  467.         logger.info(response.toString());
  468.         //数量、最大、最小、平均、求和
  469.         response = client.search(searchRequestBuilder -> searchRequestBuilder
  470.                         .index(INDEX_NAME)
  471.                         .aggregations("age_stats", aggregationBuilder -> aggregationBuilder
  472.                                 .stats(statsAggregationBuilder -> statsAggregationBuilder
  473.                                         .field("age")))
  474.                 , Poet.class);
  475.         logger.info(response.toString());
  476.         //select name,count(*) from poet-index group by name
  477.         response = client.search(searchRequestBuilder -> searchRequestBuilder
  478.                         .index(INDEX_NAME)
  479.                         .aggregations("name_terms", aggregationBuilder -> aggregationBuilder
  480.                                 .terms(termsAggregationBuilder -> termsAggregationBuilder
  481.                                         .field("name")))
  482.                 , Poet.class);
  483.         logger.info(response.toString());
  484.         //select name,age,count(*) from poet-index group by name,age
  485.         response = client.search(searchRequestBuilder -> searchRequestBuilder
  486.                         .index(INDEX_NAME)
  487.                         .aggregations("name_terms", aggregationBuilder -> aggregationBuilder
  488.                                 .terms(termsAggregationBuilder -> termsAggregationBuilder
  489.                                         .field("name")
  490.                                 )
  491.                                 .aggregations("age_terms", aggregationBuilder2 -> aggregationBuilder2
  492.                                         .terms(termsAggregationBuilder -> termsAggregationBuilder
  493.                                                 .field("age")
  494.                                         ))
  495.                         )
  496.                 , Poet.class);
  497.         logger.info(response.toString());
  498.         //类似 select avg(age) from poet-index where name='李白'
  499.         response = client.search(searchRequestBuilder -> searchRequestBuilder
  500.                         .index(INDEX_NAME)
  501.                         .query(queryBuilder -> queryBuilder
  502.                                 .bool(boolQueryBuilder -> boolQueryBuilder
  503.                                         .filter(queryBuilder2 -> queryBuilder2
  504.                                                 .term(termQueryBuilder -> termQueryBuilder
  505.                                                         .field("name").value("李白")))))
  506.                         .aggregations("ave_age", aggregationBuilder -> aggregationBuilder
  507.                                 .avg(averageAggregationBuilder -> averageAggregationBuilder.field("age")))
  508.                 , Poet.class);
  509.         logger.info(response.toString());
  510.     }
  511.     /**
  512.      * suggest查询,推荐搜索, 报错
  513.      */
  514.     @Test
  515.     public void searchSuggest() throws IOException {
  516.         SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  517.                         .index(INDEX_NAME)
  518.                         .suggest(suggesterBuilder -> suggesterBuilder
  519.                                 .suggesters("success_suggest", fieldSuggesterBuilder -> fieldSuggesterBuilder
  520.                                         .text("思考")
  521.                                         .term(termSuggesterBuilder -> termSuggesterBuilder
  522.                                                 .field("success")
  523.                                                 .suggestMode(SuggestMode.Always)
  524.                                                 .minWordLength(2)
  525.                                         )
  526.                                 )
  527.                         )
  528.                 , Poet.class);
  529.         logger.info(response.toString());
  530.     }
  531.     /**
  532.      * 高亮显示
  533.      */
  534.     @Test
  535.     public void searchHighlight() throws IOException {
  536.         SearchResponse<Poet> response = client.search(searchRequestBuilder -> searchRequestBuilder
  537.                     .index(INDEX_NAME)
  538.                     .query(queryBuilder -> queryBuilder
  539.                             .match(matchQueryBuilder -> matchQueryBuilder
  540.                                     .field("success").query("思想")))
  541.                     .highlight(highlightBuilder -> highlightBuilder
  542.                             .preTags("<span color='red'>")
  543.                             .postTags("</span>")
  544.                             .fields("success", highlightFieldBuilder -> highlightFieldBuilder))
  545.             , Poet.class);
  546.         logger.info(response.toString());
  547.     }
  548.     /**
  549.      * sql查询,报错
  550.      */
  551.     @Test
  552.     public void searchSql() throws IOException {
  553.         QueryResponse response = client.sql().query(builder -> builder
  554.                 .format("json").query("SELECT * FROM "" + INDEX_NAME + "" limit 1"));
  555.         logger.info(response.toString());
  556.     }
  557.     @Data
  558.     @AllArgsConstructor
  559.     @NoArgsConstructor
  560.     static class Poet {
  561.         private Integer age;
  562.         private String name;
  563.         private String poems;
  564.         private String about;
  565.         /**成就*/
  566.         private String success;
  567.     }
  568. }
复制代码
ElasticsearchJavaCase.java 
详细的 Elasticsearch Java API Client 使用说明,请参考官网文档:https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/current/index.html。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

雁过留声

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表