使用RestHighLevelClient方式操作Elasticsearch详细步骤 建议收藏

操作ES有很多种方式,而官方推荐的是使用Java REST Client
本例使用的ES版本:7.6.2

ES提供了两个JAVA REST client 版本

  • Java Low Level REST Client: 低级别的REST客户端,通过http与集群交互,用户需自己编组请求JSON串,及解析响应JSON串。兼容所有ES版本。
  • Java High Level REST Client: 高级别的REST客户端,基于低级别的REST客户端,增加了编组请求JSON串、解析响应JSON串等相关api。使用的版本需要保持和ES服务端的版本一致,否则会有版本问题。

Java Low Level REST Client 说明

特点、maven 引入、使用介绍:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-low.html
API doc:https://artifacts.elastic.co/javadoc/org/elasticsearch/client/elasticsearch-rest-client/6.2.4/index.html

Java High Level REST Client 说明

从6.0.0开始加入的,目的是以java面向对象的方式来进行请求、响应处理。
每个API 支持 同步/异步 两种方式,同步方法直接返回一个结果对象。异步的方法以async为后缀,通过listener参数来通知结果。
高级java REST 客户端依赖Elasticsearch core project

兼容性说明:
依赖 java1.8 和 Elasticsearch core project
请使用与服务端ES版本一致的客户端版本

官方文档

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.9/java-rest-low.html

一、Maven依赖

<!-- https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-high-level-client -->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.6.2</version>
</dependency>

二、配置

@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
    
    
    @Override
    public RestHighLevelClient elasticsearchClient() {
    
    
        ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo("localhost:9200")
                .build();
        return RestClients.create(clientConfiguration).rest();
    }
}

三、操作Elasticsearch

1.创建索引

package com.example;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;

@SpringBootTest
public class IndexCreateTest {
    
    
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    private static Logger logger = LogManager.getRootLogger();

    /**
     * 创建索引
     *
     * @throws IOException
     */
    @Test
    public void indexCreate() {
    
    
        try {
    
    
            // 1、创建索引twitter 参数:索引名 twitter
            CreateIndexRequest request = new CreateIndexRequest("twitter");

            // 2、设置索引的settings
            request.settings(Settings.builder()
                    // 分片数
                    // .put("index.number_of_shards", 3)
                    // 副本数
                    // .put("index.number_of_replicas", 2)
                    .put("analysis.analyzer.default.tokenizer", "ik_max_word") // 默认分词器
            );

            // 3、设置索引的mapping
            request.mapping("_doc",
                    "{\n" +
                            "    \"properties\":{\n" +
                            "        \"id\":{\n" +
                            "            \"type\":\"long\",\n" +
                            "            \"store\":true\n" +
                            "        },\n" +
                            "        \"username\":{\n" +
                            "            \"type\":\"text\",\n" +
                            "            \"store\":true,\n" +
                            "            \"analyzer\":\"ik_max_word\"\n" +
                            "        },\n" +
                            "        \"email\":{\n" +
                            "            \"type\":\"text\",\n" +
                            "            \"store\":true,\n" +
                            "            \"analyzer\":\"ik_max_word\"\n" +
                            "        }\n" +
                            "    }\n" +
                            "}",
                    XContentType.JSON);

            // 4、 设置索引的别名
            request.alias(new Alias("账户信息"));

            // 5、 发送请求
            // 5.1 同步方式发送请求
            CreateIndexResponse createIndexResponse = restHighLevelClient.indices()
                    .create(request, RequestOptions.DEFAULT);

            // 6、处理响应
            boolean acknowledged = createIndexResponse.isAcknowledged();
            boolean shardsAcknowledged = createIndexResponse
                    .isShardsAcknowledged();
           logger.info("acknowledged = " + acknowledged);
           logger.info("shardsAcknowledged = " + shardsAcknowledged);

            // 5.1 异步方式发送请求
            /*ActionListener<CreateIndexResponse> listener = new ActionListener<CreateIndexResponse>() {
                @Override
                public void onResponse(
                        CreateIndexResponse createIndexResponse) {
                    // 6、处理响应
                    boolean acknowledged = createIndexResponse.isAcknowledged();
                    boolean shardsAcknowledged = createIndexResponse
                            .isShardsAcknowledged();
                   logger.info("acknowledged = " + acknowledged);
                   logger.info(
                            "shardsAcknowledged = " + shardsAcknowledged);
                }

                @Override
                public void onFailure(Exception e) {
                   logger.info("创建索引异常:" + e.getMessage());
                }
            };

            client.indices().createAsync(request, listener);
            */
        } catch (IOException e) {
    
    
            logger.error(e);
        }
    }
}

在这里插入图片描述

2.修改type的mapping

/**
     * 自定义json字符串方式设置Mapping
     *
     * @throws IOException
     */
    @Test
    public void putMappingRequest() {
    
    
        try {
    
    
            PutMappingRequest request = new PutMappingRequest("twitter");
            request.type("_doc");
            request.source(
                    "{\n" +
                            "    \"properties\":{\n" +
                            "        \"id\":{\n" +
                            "            \"type\":\"long\",\n" +
                            "            \"store\":true\n" +
                            "        },\n" +
                            "        \"username\":{\n" +
                            "            \"type\":\"text\",\n" +
                            "            \"store\":true,\n" +
                            "            \"analyzer\":\"ik_max_word\"\n" +
                            "        },\n" +
                            "        \"email\":{\n" +
                            "            \"type\":\"text\",\n" +
                            "            \"store\":true,\n" +
                            "            \"analyzer\":\"ik_max_word\"\n" +
                            "        },\n" +
                            "        \"age\":{\n" +
                            "            \"type\":\"long\",\n" +
                            "            \"store\":true\n" +
                            "        }\n" +
                            "    }\n" +
                            "}",
                    XContentType.JSON);

            restHighLevelClient.indices().putMapping(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
    
    
            System.out.println(e);
        }
    }

3.往索引里面放入文档数据

package com.example;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.replication.ReplicationResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;

@SpringBootTest
public class IndexDocumentTest {
    
    
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    private static Logger logger = LogManager.getRootLogger();

    /**
     * 索引文档,即往索引里面放入文档数据.类似于数据库里面向表里面插入一行数据,一行数据就是一个文档
     *
     * @throws IOException
     */
    @Test
    public void indexDocument() {
    
    
        try {
    
    
            // 1、创建索引请求
            IndexRequest request = new IndexRequest(
                    "twitter",   //索引
                    "_doc",     // mapping type
                    "1");     //文档id

            // 2、准备文档数据
            // 方式一:直接给JSON串
            String jsonString = "{" +
                    "\"id\":\"1\"," +
                    "\"username\":\"JonssonYan\"," +
                    "\"email\":\"[email protected]\"" +
                    "}";
            request.source(jsonString, XContentType.JSON);

            // 方式二:以map对象来表示文档
            // Map<String, Object> jsonMap = new HashMap<>();
            // jsonMap.put("id", "1");
            // jsonMap.put("messageId", "20201008");
            // jsonMap.put("content", "trying out Elasticsearch");
            // request.source(jsonMap);

            // 方式三:用XContentBuilder来构建文档
            // XContentBuilder builder = XContentFactory.jsonBuilder();
            // builder.startObject();
            // {
    
    
            //     builder.field("id", "1");
            //     builder.field("messageId", "20201008");
            //     builder.field("content", "trying out Elasticsearch");
            // }
            // builder.endObject();
            // request.source(builder);

            // 方式四:直接用key-value对给出
            // request.source("id", "1",
            //         "messageId", "20201008",
            //         "content", "trying out Elasticsearch",

            // 3、其他的一些可选设置
            // 设置routing值
            // request.routing("routing");
            // 设置主分片等待时长
            // request.timeout(TimeValue.timeValueSeconds(1));
            // 设置重刷新策略
            // request.setRefreshPolicy("wait_for");
            // 设置版本号
            // request.version(2);
            // 操作类别
            // request.opType(DocWriteRequest.OpType.CREATE);

            //4、发送请求
            IndexResponse indexResponse = null;
            try {
    
    
                // 同步方式
                indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);
            } catch (ElasticsearchException e) {
    
    
                // 捕获,并处理异常
                //判断是否版本冲突、create但文档已存在冲突
                if (e.status() == RestStatus.CONFLICT) {
    
    
                    System.out.println("冲突了,请在此写冲突处理逻辑!" + e.getDetailedMessage());
                }
                System.out.println("索引异常");
            }

            //5、处理响应
            if (indexResponse != null) {
    
    
                String index = indexResponse.getIndex();
                String type = indexResponse.getType();
                String id = indexResponse.getId();
                long version = indexResponse.getVersion();
                if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
    
    
                    System.out.println("新增文档成功,处理逻辑代码写到这里。");
                } else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
    
    
                    System.out.println("修改文档成功,处理逻辑代码写到这里。");
                }
                // 分片处理信息
                ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
                if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
    
    

                }
                // 如果有分片副本失败,可以获得失败原因信息
                if (shardInfo.getFailed() > 0) {
    
    
                    for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
    
    
                        String reason = failure.reason();
                        System.out.println("副本失败原因:" + reason);
                    }
                }
            }
        } catch (IOException e) {
    
    
            logger.error(e);
        }
    }
}

在这里插入图片描述

4.获取文档数据

package com.example;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.Strings;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.Map;

@SpringBootTest
public class GetDocumentTest {
    
    
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    private static Logger logger = LogManager.getRootLogger();

    @Test
    public void getDocument() {
    
    
        try {
    
    
            // 1、创建获取文档请求
            GetRequest request = new GetRequest(
                    "twitter",   //索引
                    "_doc",     // mapping type
                    "1");     //文档id

            // 2、可选的设置
            //request.routing("routing");
            //request.version(2);

            //request.fetchSourceContext(new FetchSourceContext(false)); //是否获取_source字段
            //选择返回的字段
            String[] includes = new String[]{
    
    "id", "username", "email"};
            String[] excludes = Strings.EMPTY_ARRAY;
            FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes);
            request.fetchSourceContext(fetchSourceContext);

            //也可写成这样
            /*String[] includes = Strings.EMPTY_ARRAY;
            String[] excludes = new String[]{"message"};
            FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes);
            request.fetchSourceContext(fetchSourceContext);*/


            // 取stored字段
            /*request.storedFields("message");
            GetResponse getResponse = client.get(request);
            String message = getResponse.getField("message").getValue();*/


            //3、发送请求
            GetResponse getResponse = null;
            try {
    
    
                // 同步请求
                getResponse = restHighLevelClient.get(request, RequestOptions.DEFAULT);
            } catch (ElasticsearchException e) {
    
    
                if (e.status() == RestStatus.NOT_FOUND) {
    
    
                    logger.info("没有找到该id的文档");
                }
                if (e.status() == RestStatus.CONFLICT) {
    
    
                    logger.info("获取时版本冲突了,请在此写冲突处理逻辑!");
                }
                logger.info("获取文档异常" + e);
            }

            //4、处理响应
            if (getResponse != null) {
    
    
                String index = getResponse.getIndex();
                String type = getResponse.getType();
                String id = getResponse.getId();
                if (getResponse.isExists()) {
    
     // 文档存在
                    long version = getResponse.getVersion();
                    String sourceAsString = getResponse.getSourceAsString(); //结果取成 String
                    Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();  // 结果取成Map
                    byte[] sourceAsBytes = getResponse.getSourceAsBytes();    //结果取成字节数组
                    logger.info("index:" + index + "  type:" + type + "  id:" + id);
                    logger.info(sourceAsString);
                } else {
    
    
                    logger.info("没有找到该id的文档");
                }
            }

            //异步方式发送获取文档请求
            /*
            ActionListener<GetResponse> listener = new ActionListener<GetResponse>() {
                @Override
                public void onResponse(GetResponse getResponse) {

                }

                @Override
                public void onFailure(Exception e) {

                }
            };
            client.getAsync(request, listener);
            */
        } catch (IOException e) {
    
    
            logger.error(e);
        }
    }
}

在这里插入图片描述

在这里插入图片描述

5.搜索数据

package com.example;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@SpringBootTest
public class SearchTest {
    
    
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    private static Logger logger = LogManager.getRootLogger();

    @Test
    public void search() {
    
    
        try {
    
    
            // 1、创建search请求
            //SearchRequest searchRequest = new SearchRequest();
            SearchRequest searchRequest = new SearchRequest("twitter");
            searchRequest.types("_doc");

            // 2、用SearchSourceBuilder来构造查询请求体 ,请仔细查看它的方法,构造各种查询的方法都在这。
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

            // 构造QueryBuilder
        /*QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("username", "JonssonYan")
                    // 对匹配查询启用模糊匹配
                   .fuzziness(Fuzziness.AUTO)
                   // 在匹配查询中设置前缀长度选项
                   .prefixLength(3)
                   // 设置最大扩展选项以控制查询的模糊过程
                   .maxExpansions(10);
           sourceBuilder.query(matchQueryBuilder);*/

            sourceBuilder.query(QueryBuilders.termQuery("email", "[email protected]"));
            // 设置from确定结果索引以开始搜索的选项。预设为0。
            sourceBuilder.from(0);
            // 设置size用于确定要返回的搜索命中次数的选项。默认为10
            sourceBuilder.size(10);
            // 设置一个可选的超时时间,以控制允许搜索的时间。
            sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

            //是否返回_source字段
            //sourceBuilder.fetchSource(false);

            //设置返回哪些字段
        /*String[] includeFields = new String[] {"username", "email", "innerObject.*"};
           String[] excludeFields = new String[] {"_type"};
           sourceBuilder.fetchSource(includeFields, excludeFields);*/

            //指定排序
            //sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));
            //sourceBuilder.sort(new FieldSortBuilder("_uid").order(SortOrder.ASC));

            // 设置返回 profile
            //sourceBuilder.profile(true);

            //将请求体加入到请求中
            searchRequest.source(sourceBuilder);

            // 可选的设置
            //searchRequest.routing("routing");

            // 高亮设置


        /*HighlightBuilder highlightBuilder = new HighlightBuilder();
        HighlightBuilder.Field highlightTitle = new HighlightBuilder.Field("username");
        highlightTitle.highlighterType("text");
        highlightBuilder.field(highlightTitle);
        HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("email");
        highlightBuilder.field(highlightUser);
        sourceBuilder.highlighter(highlightBuilder);*/


            //加入聚合
        /*TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_company")
                   .field("company.keyword");
           aggregation.subAggregation(AggregationBuilders.avg("average_age")
                   .field("age"));
           sourceBuilder.aggregation(aggregation);*/

            //做查询建议
        /*SuggestionBuilder termSuggestionBuilder =
                   SuggestBuilders.termSuggestion("user").text("kmichy");
               SuggestBuilder suggestBuilder = new SuggestBuilder();
               suggestBuilder.addSuggestion("suggest_user", termSuggestionBuilder);
           sourceBuilder.suggest(suggestBuilder);*/

            //3、发送请求
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);


            //4、处理响应
            //搜索结果状态信息
            RestStatus status = searchResponse.status();
            TimeValue took = searchResponse.getTook();
            Boolean terminatedEarly = searchResponse.isTerminatedEarly();
            boolean timedOut = searchResponse.isTimedOut();

            //分片搜索情况
            int totalShards = searchResponse.getTotalShards();
            int successfulShards = searchResponse.getSuccessfulShards();
            int failedShards = searchResponse.getFailedShards();
            for (ShardSearchFailure failure : searchResponse.getShardFailures()) {
    
    
                // failures should be handled here
            }

            //处理搜索命中文档结果
            SearchHits hits = searchResponse.getHits();

            TotalHits totalHits = hits.getTotalHits();
            float maxScore = hits.getMaxScore();

            SearchHit[] searchHits = hits.getHits();
            for (SearchHit hit : searchHits) {
    
    
                // do something with the SearchHit

                String index = hit.getIndex();
                String type = hit.getType();
                String id = hit.getId();
                float score = hit.getScore();

                //取_source字段值
                String sourceAsString = hit.getSourceAsString(); //取成json串
                Map<String, Object> sourceAsMap = hit.getSourceAsMap(); // 取成map对象
                //从map中取字段值
                /*
                String documentTitle = (String) sourceAsMap.get("title");
                List<Object> users = (List<Object>) sourceAsMap.get("user");
                Map<String, Object> innerObject = (Map<String, Object>) sourceAsMap.get("innerObject");
                */
                logger.info("index:" + index + "  type:" + type + "  id:" + id);
                logger.info(sourceAsString);

                //取高亮结果
                /*Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                HighlightField highlight = highlightFields.get("title");
                Text[] fragments = highlight.fragments();
                String fragmentString = fragments[0].string();*/
            }

            // 获取聚合结果
            /*
            Aggregations aggregations = searchResponse.getAggregations();
            Terms byCompanyAggregation = aggregations.get("by_company");
            Bucket elasticBucket = byCompanyAggregation.getBucketByKey("Elastic");
            Avg averageAge = elasticBucket.getAggregations().get("average_age");
            double avg = averageAge.getValue();
            */

            // 获取建议结果
            /*Suggest suggest = searchResponse.getSuggest();
            TermSuggestion termSuggestion = suggest.getSuggestion("suggest_user");
            for (TermSuggestion.Entry entry : termSuggestion.getEntries()) {
                for (TermSuggestion.Entry.Option option : entry) {
                    String suggestText = option.getText().string();
                }
            }
            */

            //异步方式发送获查询请求
            /*
            ActionListener<SearchResponse> listener = new ActionListener<SearchResponse>() {
                @Override
                public void onResponse(SearchResponse getResponse) {
                    //结果获取
                }

                @Override
                public void onFailure(Exception e) {
                    //失败处理
                }
            };
            client.searchAsync(searchRequest, listener);
            */
        } catch (IOException e) {
    
    
            logger.error(e);
        }
    }
}

在这里插入图片描述

6.高亮

package com.example;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.Map;

@SpringBootTest
public class HighlightTest {
    
    
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    private static Logger logger = LogManager.getRootLogger();

    @Test
    public void highlight() {
    
    
        try {
    
    
            // 1、创建search请求
            SearchRequest searchRequest = new SearchRequest("twitter");

            // 2、用SearchSourceBuilder来构造查询请求体 ,请仔细查看它的方法,构造各种查询的方法都在这。
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

            //构造QueryBuilder
            QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("username", "JonssonYan");
            sourceBuilder.query(matchQueryBuilder);

            //分页设置
            /*sourceBuilder.from(0);
            sourceBuilder.size(5); ;*/


            // 高亮设置
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder.requireFieldMatch(false).field("username").field("email")
                    .preTags("<strong>").postTags("</strong>");
            //不同字段可有不同设置,如不同标签
            /*HighlightBuilder.Field highlightTitle = new HighlightBuilder.Field("title");
            highlightTitle.preTags("<strong>").postTags("</strong>");
            highlightBuilder.field(highlightTitle);
            HighlightBuilder.Field highlightContent = new HighlightBuilder.Field("content");
            highlightContent.preTags("<b>").postTags("</b>");
            highlightBuilder.field(highlightContent).requireFieldMatch(false);*/

            sourceBuilder.highlighter(highlightBuilder);

            searchRequest.source(sourceBuilder);

            //3、发送请求
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);


            //4、处理响应
            if (RestStatus.OK.equals(searchResponse.status())) {
    
    
                //处理搜索命中文档结果
                SearchHits hits = searchResponse.getHits();
                TotalHits totalHits = hits.getTotalHits();

                SearchHit[] searchHits = hits.getHits();
                for (SearchHit hit : searchHits) {
    
    
                    String index = hit.getIndex();
                    String type = hit.getType();
                    String id = hit.getId();
                    float score = hit.getScore();

                    //取_source字段值
                    //String sourceAsString = hit.getSourceAsString(); //取成json串
                    Map<String, Object> sourceAsMap = hit.getSourceAsMap(); // 取成map对象
                    //从map中取字段值
                    /*String title = (String) sourceAsMap.get("title");
                    String content  = (String) sourceAsMap.get("content"); */
                    logger.info("index:" + index + "  type:" + type + "  id:" + id);
                    logger.info("sourceMap : " + sourceAsMap);
                    //取高亮结果
                    Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                    HighlightField highlight = highlightFields.get("username");
                    if (highlight != null) {
    
    
                        Text[] fragments = highlight.fragments();  //多值的字段会有多个值
                        if (fragments != null) {
    
    
                            String fragmentString = fragments[0].string();
                            logger.info("username highlight : " + fragmentString);
                            //可用高亮字符串替换上面sourceAsMap中的对应字段返回到上一级调用
                            //sourceAsMap.put("title", fragmentString);
                        }
                    }

                    highlight = highlightFields.get("email");
                    if (highlight != null) {
    
    
                        Text[] fragments = highlight.fragments();  //多值的字段会有多个值
                        if (fragments != null) {
    
    
                            String fragmentString = fragments[0].string();
                            logger.info("email highlight : " + fragmentString);
                            //可用高亮字符串替换上面sourceAsMap中的对应字段返回到上一级调用
                            //sourceAsMap.put("content", fragmentString);
                        }
                    }
                }
            }
        } catch (IOException e) {
    
    
            logger.error(e);
        }
    }
}

在这里插入图片描述

7.查询建议

词项建议拼写检查,检查用户的拼写是否错误,如果有错给用户推荐正确的词,appel->apple

package com.example;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.SuggestBuilders;
import org.elasticsearch.search.suggest.SuggestionBuilder;
import org.elasticsearch.search.suggest.term.TermSuggestion;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;

@SpringBootTest
public class SuggestTest {
    
    
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    private static Logger logger = LogManager.getRootLogger();

    /**
     * 词项建议拼写检查,检查用户的拼写是否错误,如果有错给用户推荐正确的词,appel->apple
     */
    @Test
    public void termSuggest() {
    
    
        try {
    
    
            // 1、创建search请求
            //SearchRequest searchRequest = new SearchRequest();
            SearchRequest searchRequest = new SearchRequest("twitter");

            // 2、用SearchSourceBuilder来构造查询请求体 ,请仔细查看它的方法,构造各种查询的方法都在这。
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

            sourceBuilder.size(0);

            //做查询建议
            //词项建议
            SuggestionBuilder termSuggestionBuilder = SuggestBuilders.termSuggestion("username").text("JonssonYa");
            SuggestBuilder suggestBuilder = new SuggestBuilder();
            suggestBuilder.addSuggestion("suggest_user", termSuggestionBuilder);
            sourceBuilder.suggest(suggestBuilder);

            searchRequest.source(sourceBuilder);
            //3、发送请求
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

            //4、处理响应
            //搜索结果状态信息
            if (RestStatus.OK.equals(searchResponse.status())) {
    
    
                // 获取建议结果
                Suggest suggest = searchResponse.getSuggest();
                TermSuggestion termSuggestion = suggest.getSuggestion("suggest_user");
                for (TermSuggestion.Entry entry : termSuggestion.getEntries()) {
    
    
                    logger.info("text: " + entry.getText().string());
                    for (TermSuggestion.Entry.Option option : entry) {
    
    
                        String suggestText = option.getText().string();
                        logger.info("   suggest option : " + suggestText);
                    }
                }
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

自动补全,根据用户的输入联想到可能的词或者短语

8.聚合分析

package com.example;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.Avg;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;

@SpringBootTest
public class AggregationTest {
    
    
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    private static Logger logger = LogManager.getRootLogger();

    @Test
    public void aggregation() {
    
    
        try {
    
    
            // 1、创建search请求
            //SearchRequest searchRequest = new SearchRequest();
            SearchRequest searchRequest = new SearchRequest("twitter");

            // 2、用SearchSourceBuilder来构造查询请求体 ,请仔细查看它的方法,构造各种查询的方法都在这。
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

            sourceBuilder.size(0);

            //加入聚合
            //字段值项分组聚合
            TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_age")
                    .field("age").order(BucketOrder.aggregation("average_balance", true));
            //计算每组的平均balance指标
            aggregation.subAggregation(AggregationBuilders.avg("average_balance")
                    .field("balance"));
            sourceBuilder.aggregation(aggregation);

            searchRequest.source(sourceBuilder);

            //3、发送请求
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

            //4、处理响应
            //搜索结果状态信息
            if (RestStatus.OK.equals(searchResponse.status())) {
    
    
                // 获取聚合结果
                Aggregations aggregations = searchResponse.getAggregations();
                Terms byAgeAggregation = aggregations.get("by_age");
                logger.info("aggregation by_age 结果");
                logger.info("docCountError: " + byAgeAggregation.getDocCountError());
                logger.info("sumOfOtherDocCounts: " + byAgeAggregation.getSumOfOtherDocCounts());
                logger.info("------------------------------------");
                for (Terms.Bucket buck : byAgeAggregation.getBuckets()) {
    
    
                    logger.info("key: " + buck.getKeyAsNumber());
                    logger.info("docCount: " + buck.getDocCount());
                    logger.info("docCountError: " + buck.getDocCountError());
                    //取子聚合
                    Avg averageBalance = buck.getAggregations().get("average_balance");

                    logger.info("average_balance: " + averageBalance.getValue());
                    logger.info("------------------------------------");
                }
                //直接用key 来去分组
                /*Bucket elasticBucket = byCompanyAggregation.getBucketByKey("24");
                Avg averageAge = elasticBucket.getAggregations().get("average_age");
                double avg = averageAge.getValue();*/
            }

        } catch (IOException e) {
    
    
            logger.error(e);
        }
    }
}

在这里插入图片描述
在这里插入图片描述

各种查询对应的QueryBuilder:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-query-builders.html
各种聚合对应的AggregationBuilder:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-aggregation-builders.html

猜你喜欢

转载自blog.csdn.net/y1534414425/article/details/108957677