【ElasticSearch】(三、常见方法总结)

前言:演示版本为7.6.1

一、SpringBoot整合ElasticSearch

1. 添加文件ElasticSearchConfig

package com.tm.es.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ElasticSearchConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient    (){
        RestHighLevelClient    client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("localhost",9200,"http")));
        return client;
    }
}
ElasticSearchConfig

2. 添加配置文件application.yml

server:
  port: 8080
spring:
  application:
    name: spring-boot-es-demo
  elasticsearch:
    rest:
      #username: user
      #password: 123456
      uris: https://127.0.0.1:9200
      # http连接超时时间
      connection-timeout: 1000
      # socket连接超时时间
      socketTimeout: 30000
      # 获取连接的超时时间
      connectionRequestTimeout: 500
      # 最大连接数
      maxConnTotal: 100
      # 最大路由连接数
      maxConnPerRoute: 100
      # 任务最长可执行时间 (单位:小时)
      executeTimeout: 8
application.yml

3. 添加相关依赖pom.xml

<!-- https://mvnrepository.com/artifact/org.elasticsearch/elasticsearch -->
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.6.1</version>
        </dependency>
        <!-- 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.1</version>
        </dependency>
pom.xml

4. controller中注入RestHighLevelClient

至此,一个简易的环境就搭好了,可以方便我们进行下面demo的练习了。

5. 创建实体类User用于业务开发

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {

    private String name;

    private String full_name;

    private Integer age;

    @JSONField(format="yyyy-MM-dd HH:mm:ss")
    private LocalDateTime birthday;

    private Date createTime;

    private Long timestamp;

    private Boolean isBoy;

}
User.java

二、常用的方法总结

通过浏览器访问:http://localhost:8080/ES/existIndex即可完成调试

package com.tm.es.controller;

import com.alibaba.fastjson.JSON;
import com.tm.es.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.Cancellable;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.*;
import org.elasticsearch.cluster.metadata.AliasMetaData;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @version 1.0
 * @ClassName EsTest
 * @Description
 * @Author tianmeng
 * @Date 2020/12/16 10:26
 */
@Slf4j
@RestController
@RequestMapping("/ES")
public class EsController {

    @Autowired
    private RestHighLevelClient client;

    //-------------------------------------------------查看索引是否存在------------------------------------------------

    @RequestMapping("/existIndex")
    public boolean existIndex() throws IOException {
        GetIndexRequest request = new GetIndexRequest("test_index");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        return exists;
    }

    //----------------------------------------------------查看索引信息----------------------------------------------------

    @RequestMapping("/getIndex")
    public void getIndex() throws IOException {
        GetIndexRequest request = new GetIndexRequest("test_index");
        GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
        //获取索引信息
        Map<String, List<AliasMetaData>> aliases = response.getAliases();
        Map<String, MappingMetaData> mappings = response.getMappings();
        Map<String, Settings> settings = response.getSettings();
    }

    //----------------------------------------------------查看所有索引信息----------------------------------------------------

    @RequestMapping("/getAllIndex")
    public void getAllIndex() throws IOException {
        //查看所有索引信息
        //GetIndexRequest request = new GetIndexRequest("*");
        //查看符合条件的索引信息
        GetIndexRequest request = new GetIndexRequest("test_*");
        GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
        String[] indices = response.getIndices();
    }

    //----------------------------------------------------创建索引----------------------------------------------------

    //1.创建索引(同步)
    @RequestMapping("/createIndex1")
    public void createIndex1() throws IOException {
        //如果存在该索引会报错
        //使用默认的settings
        CreateIndexRequest request = new CreateIndexRequest("test_index");
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        System.out.println(response);
    }

    //2.创建索引(同步)
    @RequestMapping("/createIndex2")
    public void createIndex2() throws IOException {
        CreateIndexRequest request = new CreateIndexRequest("test_index");
        // settings部分的设置
        request.settings(Settings.builder()
                // 创建索引时,分配的主分片的数量
                .put("index.number_of_shards", 2)
                // 创建索引时,为每一个主分片分配的副本分片的数量
                .put("index.number_of_replicas", 2)
        );
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
    }

    //3.创建索引(异步)
    @RequestMapping("/createIndex3")
    public void createIndex3(){
        CreateIndexRequest request = new CreateIndexRequest("test_index");
        client.indices().createAsync(request, RequestOptions.DEFAULT, new ActionListener<CreateIndexResponse>() {
            @Override
            public void onResponse(CreateIndexResponse createIndexResponse) {
                log.debug("执行情况:" + createIndexResponse);
                System.out.println(createIndexResponse);
            }

            @Override
            public void onFailure(Exception e) {
                log.error("执行失败的原因:" + e.getMessage()) ;
                System.out.println(e.getMessage());
            }
        });
    }

    //----------------------------------------------------删除索引----------------------------------------------------

    @RequestMapping("/deleteIndex")
    public boolean deleteIndex() throws IOException {
        //没有该索引会报错
        DeleteIndexRequest request = new DeleteIndexRequest("test_index");
        AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
        return delete.isAcknowledged();
    }

    //----------------------------------------------------更新索引settings----------------------------------------------------

    @RequestMapping("/updateIndexSettings")
    public void updateIndexSettings() throws IOException {
        UpdateSettingsRequest request = new UpdateSettingsRequest("test_index");
        Settings.Builder settingsBuilder = Settings.builder().put("index.number_of_replicas", "3");
        request.settings(settingsBuilder);
        // 是否更新已经存在的settings配置 默认false (false的时候可以更新成功 true的时候不成功)
        //request.setPreserveExisting(false);
        // 更新settings配置(同步)
        AcknowledgedResponse acknowledgedResponse = client.indices().putSettings(request, RequestOptions.DEFAULT);
        System.out.println(acknowledgedResponse.isAcknowledged());
    }

    //----------------------------------------------------更新索引mapping----------------------------------------------------

    @RequestMapping("/updateIndexMapping")
    public void updateIndexMapping() throws IOException {
        //这里要注意:已经创建好的文档字段不能删除和更改类型以及里面的属性,但是可以添加字段,
        //如果想要修改,需要新创建一个索引,之后将原索引中的数据同步过去,指定别名,最后删除原索引
        PutMappingRequest request = new PutMappingRequest("test_index");
        XContentBuilder builder = XContentFactory.jsonBuilder();
        builder.startObject();
        {
            builder.startObject("properties");
            {
                //String  text  分词
                builder.startObject("name");
                {
                    builder.field("type","text");
                    builder.field("analyzer", "ik_max_word");
                }
                builder.endObject();
                //String  keyword  不分词
                builder.startObject("full_name");
                {
                    builder.field("type","keyword");
                }
                builder.endObject();
                //Numeric  integer
                builder.startObject("age");
                {
                    builder.field("type","integer");
                }
                builder.endObject();
                //Date  date
                builder.startObject("birthday");
                {
                    builder.field("type","date");
                    builder.field("format","yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis");
                }
                builder.endObject();
                //Data date
                builder.startObject("createTime");
                {
                    builder.field("type","date");
                    builder.field("format","yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis");
                }
                builder.endObject();
                //Numeric  long
                builder.startObject("timestamp");
                {
                    builder.field("type","long");
                }
                builder.endObject();
                //Boolean boolean
                builder.startObject("isBoy");
                {
                    builder.field("type","boolean");
                }
                builder.endObject();
            }
            builder.endObject();
        }
        builder.endObject();
        request.source(builder);
        // 新增mapping配置(同步)
        AcknowledgedResponse response = client.indices().putMapping(request, RequestOptions.DEFAULT);
        System.out.println(response);
    }


    //----------------------------------------------------添加文档(单个 同步+异步)----------------------------------------------------

    @RequestMapping("/addDocument")
    public void addDocument() throws IOException {
        User user = new User();
        user.setName("张三");
        user.setFull_name("张三李四王五赵六");
        user.setAge(12);
        user.setIsBoy(true);
        user.setTimestamp(System.currentTimeMillis());//存入的是毫秒值1608108501654
        user.setCreateTime(new Date());//存入的是毫秒值1608108501654
        user.setBirthday(LocalDateTime.now());////存入的是时间格式2020-12-16 16:48:21

        IndexRequest request = new IndexRequest("test_index");
        // 规则 put /test_index/_doc/1
        //不指定id会随机生成 有该id会更新 没有该id会添加
        //request.id("1");
        request.timeout(TimeValue.timeValueSeconds(1));
        request.source(JSON.toJSONString(user), XContentType.JSON);

        //同步
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        // 结果:IndexResponse[index=test_index,type=_doc,id=nGvFanYBf998z9yKoZFx,version=1,result=created,seqNo=3,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]
        System.out.println(response.toString());
        //新建:CREATED 更新:OK
        System.out.println(response.status());

        //异步
//        Cancellable cancellable = client.indexAsync(request, RequestOptions.DEFAULT, new ActionListener<IndexResponse>() {
//            @Override
//            public void onResponse(IndexResponse indexResponse) {
//                //这里可以获取添加的数据
//                log.debug("执行情况: " + indexResponse);
//            }
//
//            @Override
//            public void onFailure(Exception e) {
//                log.error("执行失败的原因");
//            }
//        });
    }

    //----------------------------------------------------添加文档(单个 map方式)----------------------------------------------------

    @RequestMapping("/addDocumentByMap")
    public void addDocumentByMap() throws IOException {
        Map<String, Object> map = new HashMap<>();
        map.put("name", "张三");
        map.put("full_name", "测试测试");
        map.put("age", 45);
        map.put("birthday", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()));
        map.put("createTime", System.currentTimeMillis());
        map.put("timestamp", System.currentTimeMillis());
        map.put("isBoy", false);
        IndexRequest request = new IndexRequest("test_index");
        request.id("kk");
        request.source(map);
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        System.out.println(response.status());
    }

    //----------------------------------------------------添加文档(批量)----------------------------------------------------

    @RequestMapping("/addBulkDocument")
    public void addBulkDocument() throws Exception {
        BulkRequest request = new BulkRequest();
        request.timeout("15s");
        List<User> users = new ArrayList<>();
        users.add(new User("张三", "测试1", 12, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true));
        Thread.sleep(1000);
        users.add(new User("李四", "测试2", 22, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true));
        Thread.sleep(1000);
        users.add(new User("王五", "测试3", 32, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true));
        Thread.sleep(1000);
        users.add(new User("赵六", "测试4", 42, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true));
        for (int i = 0; i < users.size(); i++) {
            //指定id
            //request.add(new IndexRequest("test_index").id(""+(i+10)).source(JSON.toJSONString(users.get(i)), XContentType.JSON));
            //不指定id  后面还可以指定路由.routing("routing")
            request.add(new IndexRequest("test_index").source(JSON.toJSONString(users.get(i)), XContentType.JSON));
        }
        BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
        System.out.println(response);
        //false代表成功
        System.out.println(response.hasFailures());
    }

    //----------------------------------------------------删除文档(单个)----------------------------------------------------

    @RequestMapping("/deleteDocument")
    public void deleteDocument() throws IOException {
        DeleteRequest request = new DeleteRequest("test_index","kk");
        request.timeout("1s");
        DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
        //OK:删除成功  NOT_FOUND:未发现该id值对应的文档
        System.out.println(response.status());
    }

    //----------------------------------------------------查询文档----------------------------------------------------

    @RequestMapping("/getDocument")
    public void getDocument() throws IOException {
        GetRequest request = new GetRequest("test_index","1");
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        //没有返回:null
        //存在返回:{birthday=2020-12-16 16:56:02, full_name=张三李四王五赵六, createTime=1608108962893, name=张三, age=22, isBoy=true, timestamp=1608108962893}
        System.out.println(response.getSource());
    }

    //---基本查询-------------------

    //----------------------------------------------------查询所有(match_all)----------------------------------------------------

    @RequestMapping("/matchAllDocument")
    public void matchAllDocument() throws IOException {
        //1,构建SearchRequest请求对象,指定索引库
        SearchRequest request = new SearchRequest("test_index");
        //2,构建SearchSourceBuilder查询对象
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //3,构建QueryBuilder对象指定查询方式和查询条件
        QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
        //4,将QuseryBuilder对象设置到SearchSourceBuilder对象中
        sourceBuilder.query(queryBuilder);
        //5,将SearchSourceBuilder设置到request中
        request.source(sourceBuilder);
        //6,调用方法查询数据
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //7,解析返回结果
        SearchHit[] hits = response.getHits().getHits();
        //8. 返回查询数量 14 hits
        System.out.println(response.getHits().getTotalHits());
        for (int i = 0; i < hits.length; i++) {
            //9. 遍历所有数据 getSourceAsString 、getSourceAsMap
            //{"age":12,"birthday":"2020-12-16 17:15:12","createTime":1608110112784,"full_name":"测试1","isBoy":true,"name":"张三","timestamp":1608110112784}
            System.out.println(hits[i].getSourceAsString());
            //Map<String, Object> sourceAsMap = hits[i].getSourceAsMap();
        }

    }

    //----------------------------------------------------匹配查询(match)----------------------------------------------------

    @RequestMapping("/matchDocument")
    public void matchDocument() throws IOException {
        //1,构建SearchRequest请求对象,指定索引库
        SearchRequest request = new SearchRequest("test_index");
        //2,构建SearchSourceBuilder查询对象
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //3,构建QueryBuilder对象指定查询方式和查询条件
        QueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "张三");
        //4,将QuseryBuilder对象设置到SearchSourceBuilder对象中
        sourceBuilder.query(queryBuilder);
        //5,将SearchSourceBuilder设置到SearchRequest中
        request.source(sourceBuilder);
        //6,调用方法查询数据
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        //7,解析返回结果
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }

    //----------------------------------------------------多字段查询(multi_match)----------------------------------------------------

    @RequestMapping("/multiMatchDocument")
    public void multiMatchDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //第一个参数是查询的值,后面的参数是字段名,可以跟多个字段,用逗号隔开
        QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery("李四", "name", "full_name");
        sourceBuilder.query(queryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }

    //----------------------------------------------------词条精确匹配(term)----------------------------------------------------

    @RequestMapping("/termDocument")
    public void termDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        QueryBuilder queryBuilder = QueryBuilders.termQuery("name", "王五");
        sourceBuilder.query(queryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }

    //----------------------------------------------------多词条精确匹配(terms)----------------------------------------------------

    @RequestMapping("/termsDocument")
    public void termsDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        QueryBuilder queryBuilder = QueryBuilders.termsQuery("age", "22", "45");
        sourceBuilder.query(queryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }

        //写法2:
//        SearchRequest request = new SearchRequest("test_index");
//        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//        TermsQueryBuilder termsQueryBuilder = new TermsQueryBuilder("age", "22", "45");
//        sourceBuilder.query(termsQueryBuilder);
//        request.source(sourceBuilder);
//        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
//        SearchHit[] hits = searchResponse.getHits().getHits();
//        for (int i = 0; i <hits.length ; i++) {
//            System.out.println("返回的结果: "+hits[i].getSourceAsString());
//        }
    }

    //---高级查询-------------------

    //----------------------------------------------------布尔组合(bool)----------------------------------------------------
    //`bool`把各种其它查询通过`must`(与)、`must_not`(非)、`should`(或)的方式进行组合

    @RequestMapping("/boolDocument")
    public void boolDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询name字段值为李四或者王五的数据
//        QueryBuilder matchQueryBuilder1 = QueryBuilders.matchQuery("name", "王五");
//        QueryBuilder matchQueryBuilder2 = QueryBuilders.matchQuery("name", "李四");
//        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        boolQueryBuilder.should(matchQueryBuilder1);
//        boolQueryBuilder.should(matchQueryBuilder2);

        //查询name字段值为张三且age字段为22的
//        QueryBuilder matchQueryBuilder3 = QueryBuilders.matchQuery("name", "张三");
//        QueryBuilder matchQueryBuilder4 = QueryBuilders.matchQuery("age", "22");
//        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        boolQueryBuilder.must(matchQueryBuilder3);
//        boolQueryBuilder.must(matchQueryBuilder4);

        //查询name字段值不等于张三和李四的数据
        QueryBuilder matchQueryBuilder5 = QueryBuilders.matchQuery("name", "张三");
        QueryBuilder matchQueryBuilder6 = QueryBuilders.matchQuery("name", "李四");
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.mustNot(matchQueryBuilder5);
        boolQueryBuilder.mustNot(matchQueryBuilder6);
        sourceBuilder.query(boolQueryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }

    //----------------------------------------------------范围查询(range)----------------------------------------------------
    //`range` 查询找出那些落在指定区间内的数字或者时间 gt gte lt lte
    @RequestMapping("/rangeDocument")
    public void rangeDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询age字段大于22小于43的
        //QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").gt("22").lt("43");
        //查询birthday字段时间在2020-12-16 16:00:00~~~2020-12-16 17:00:00范围的
        QueryBuilder queryBuilder = QueryBuilders.rangeQuery("birthday").gte("2020-12-16 16:00:00").lte("2020-12-16 17:00:00");
        sourceBuilder.query(queryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }

    //----------------------------------------------------前缀查询(prefix)----------------------------------------------------

    @RequestMapping("/prefixDocument")
    public void prefixDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询full_name字段以张三开头的数据
        QueryBuilder queryBuilder = QueryBuilders.prefixQuery("full_name","张三");
        sourceBuilder.query(queryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }

    //----------------------------------------------------模糊查询(wildcard)----------------------------------------------------

    @RequestMapping("/wildcardDocument")
    public void wildcardDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询full_name字段以测试开头的数据
        //QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("full_name", "测试*");
        //查询full_name字段以1结尾的数据
        QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("full_name", "*1");
        sourceBuilder.query(queryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }

    //----------------------------------------------------模糊查询(fuzzy)----------------------------------------------------

    @RequestMapping("/fuzzyDocument")
    public void fuzzyDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //模糊查询full_name字段值为测试1的数据 fuzzy允许有一定程度的不同 所以尽管数据库中数据是测试1 仍可以搜索出来
        QueryBuilder queryBuilder = QueryBuilders.fuzzyQuery("full_name", "测测1");
        sourceBuilder.query(queryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }

    //----------------------------------------------------排序单字段、多字段(sort)----------------------------------------------------

    @RequestMapping("/sortDocument")
    public void sortDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //
        QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").lt(1000);
        //先按照age进行正排序,之后age字段相同的再按照birthday字段倒排序
        sourceBuilder.query(queryBuilder).sort("age", SortOrder.ASC).sort("birthday",SortOrder.DESC);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }

    //----------------------------------------------------分页(from、size)----------------------------------------------------

    @RequestMapping("/fromSizeDocument")
    public void fromSizeDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //
        QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").lt(1000);
        //查询从第一条开始(包括)查询两条数据(结果为查询前两条数据)
        sourceBuilder.query(queryBuilder).from(0).size(2);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }

    //----------------------------------------------------高亮(high light)----------------------------------------------------

    @RequestMapping("/highLightDocument")
    public void highLightDocument() throws IOException {
        //条件搜索
        SearchRequest goods = new SearchRequest("test_index");
        SearchSourceBuilder builder = new SearchSourceBuilder();

        TermQueryBuilder title = QueryBuilders.termQuery("name", "李四");
        builder.query(title);
        builder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");//高亮的字段
        highlightBuilder.requireFieldMatch(false);//是否多个字段都高亮
        highlightBuilder.preTags("<span style='color:red'>");//前缀后缀
        highlightBuilder.postTags("</span>");
        builder.highlighter(highlightBuilder);

        //执行搜索
        goods.source(builder);
        SearchResponse search = client.search(goods, RequestOptions.DEFAULT);
        //解析结果
        ArrayList<Map<String,Object>> list = new ArrayList<>();
        for (SearchHit hit : search.getHits().getHits()) {
            //解析高亮的字段
            //获取高亮字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField name = highlightFields.get("name");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();//原来的结果
            //将原来的字段替换为高亮字段即可
            if (name!=null){
                Text[] fragments = name.fragments();
                String newTitle = "";
                for (Text text : fragments) {
                    newTitle +=text;
                }
                sourceAsMap.put("name",newTitle);//替换掉原来的内容
            }
            list.add(sourceAsMap);
        }
        System.out.println(list);
    }


}
EsController

三、Kibana对应操作

1. 查看某个索引是否存在及该索引信息

//-------------------------------------------------查看索引是否存在------------------------------------------------

    @RequestMapping("/existIndex")
    public boolean existIndex() throws IOException {
        GetIndexRequest request = new GetIndexRequest("test_index");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        return exists;
    }

    //----------------------------------------------------查看索引信息----------------------------------------------------

    @RequestMapping("/getIndex")
    public void getIndex() throws IOException {
        GetIndexRequest request = new GetIndexRequest("test_index");
        GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
        //获取索引信息
        Map<String, List<AliasMetaData>> aliases = response.getAliases();
        Map<String, MappingMetaData> mappings = response.getMappings();
        Map<String, Settings> settings = response.getSettings();
    }
java操作
#查看索引结构  索引存在
GET /test_index

#结果
{
  "test_index" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "integer"
        },
        "birthday" : {
          "type" : "date",
          "format" : "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
        },
        "createTime" : {
          "type" : "date",
          "format" : "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
        },
        "full_name" : {
          "type" : "keyword"
        },
        "isBoy" : {
          "type" : "boolean"
        },
        "name" : {
          "type" : "text",
          "analyzer" : "ik_max_word"
        },
        "timestamp" : {
          "type" : "long"
        }
      }
    },
    "settings" : {
      "index" : {
        "creation_date" : "1608107781691",
        "number_of_shards" : "1",
        "number_of_replicas" : "1",
        "uuid" : "8u48j3MsQEuPy90fcYkcuA",
        "version" : {
          "created" : "7060199"
        },
        "provided_name" : "test_index"
      }
    }
  }
}


#查看索引结构 索引不存在
GET /test_index2

#结果
{
  "error" : {
    "root_cause" : [
      {
        "type" : "index_not_found_exception",
        "reason" : "no such index [test_index2]",
        "resource.type" : "index_or_alias",
        "resource.id" : "test_index2",
        "index_uuid" : "_na_",
        "index" : "test_index2"
      }
    ],
    "type" : "index_not_found_exception",
    "reason" : "no such index [test_index2]",
    "resource.type" : "index_or_alias",
    "resource.id" : "test_index2",
    "index_uuid" : "_na_",
    "index" : "test_index2"
  },
  "status" : 404
}
Kibana操作

2. 查看所有索引

//----------------------------------------------------查看所有索引信息----------------------------------------------------

    @RequestMapping("/getAllIndex")
    public void getAllIndex() throws IOException {
        //查看所有索引信息
        //GetIndexRequest request = new GetIndexRequest("*");
        //查看符合条件的索引信息
        GetIndexRequest request = new GetIndexRequest("test_*");
        GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
        String[] indices = response.getIndices();
    }
java操作
#查看所有索引
GET _cat/indices

#结果
yellow open test_index3              4Jo-ITT4Rma_u-y3KRhokA 1 1  0 0   230b   230b
green  open .kibana_task_manager_1   sT-xQclUT-Obsg2H8DC9pQ 1 0  2 0 31.6kb 31.6kb
yellow open test_index1              vcuSyzX3ThKKVq8GzHUpag 1 1  0 0   283b   283b
green  open .apm-agent-configuration fjiQqCgbQ1CVBvBK1J8TMA 1 0  0 0   283b   283b
yellow open test_index               8u48j3MsQEuPy90fcYkcuA 1 1 14 1   30kb   30kb
green  open .kibana_1                oILjMxaTQGaVyBHK94jdrQ 1 0 43 7 62.5kb 62.5kb
Kibana操作

Kibana操作

3. 创建索引:

{
        CreateIndexRequest request = new CreateIndexRequest("test_index");
        client.indices().createAsync(request, RequestOptions.DEFAULT, new ActionListener<CreateIndexResponse>() {
            @Override
            public void onResponse(CreateIndexResponse createIndexResponse) {
                log.debug("执行情况:" + createIndexResponse);
                System.out.println(createIndexResponse);
            }

            @Override
            public void onFailure(Exception e) {
                log.error("执行失败的原因:" + e.getMessage()) ;
                System.out.println(e.getMessage());
            }
        });
    }
java操作
#创建索引
PUT /test_index3
{
  "aliases": {},
  "mappings": {
    "properties": {
      "age": {
        "type": "integer"
      },
      "birthday": {
        "type": "date",
        "format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      },
      "createTime": {
        "type": "date",
        "format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      },
      "full_name": {
        "type": "keyword"
      },
      "isBoy": {
        "type": "boolean"
      },
      "name": {
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "timestamp": {
        "type": "long"
      }
    }
  },
  "settings": {
    "index": {
      "number_of_shards": "1",
      "number_of_replicas": "1"
    }
  }
}

#结果
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "test_index3"
}
Kibana操作

4. 删除索引

//----------------------------------------------------删除索引----------------------------------------------------

    @RequestMapping("/deleteIndex")
    public boolean deleteIndex() throws IOException {
        //没有该索引会报错
        DeleteIndexRequest request = new DeleteIndexRequest("test_index");
        AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
        return delete.isAcknowledged();
    }
java操作
#删除索引
DELETE /test_index3

#结果
{
  "acknowledged" : true
}
Kibana操作

5. 更新索引settings和mapping

注意:

1. 更新之前需要关闭索引才可以,否则会报错。

2. 对于mapping的更新,原有的字段及其类型无法更新。只能添加新的字段。

3. 对于settings的更新,目前发现只能更新number_of_replicas。无法更新number_of_shards。

//----------------------------------------------------更新索引settings----------------------------------------------------

    @RequestMapping("/updateIndexSettings")
    public void updateIndexSettings() throws IOException {
        UpdateSettingsRequest request = new UpdateSettingsRequest("test_index");
        Settings.Builder settingsBuilder = Settings.builder().put("index.number_of_replicas", "3");
        request.settings(settingsBuilder);
        // 是否更新已经存在的settings配置 默认false (false的时候可以更新成功 true的时候不成功)
        //request.setPreserveExisting(false);
        // 更新settings配置(同步)
        AcknowledgedResponse acknowledgedResponse = client.indices().putSettings(request, RequestOptions.DEFAULT);
        System.out.println(acknowledgedResponse.isAcknowledged());
    }

    //----------------------------------------------------更新索引mapping----------------------------------------------------

    @RequestMapping("/updateIndexMapping")
    public void updateIndexMapping() throws IOException {
        //这里要注意:已经创建好的文档字段不能删除和更改类型以及里面的属性,但是可以添加字段,
        //如果想要修改,需要新创建一个索引,之后将原索引中的数据同步过去,指定别名,最后删除原索引
        PutMappingRequest request = new PutMappingRequest("test_index");
        XContentBuilder builder = XContentFactory.jsonBuilder();
        builder.startObject();
        {
            builder.startObject("properties");
            {
                //String  text  分词
                builder.startObject("name");
                {
                    builder.field("type","text");
                    builder.field("analyzer", "ik_max_word");
                }
                builder.endObject();
                //String  keyword  不分词
                builder.startObject("full_name");
                {
                    builder.field("type","keyword");
                }
                builder.endObject();
                //Numeric  integer
                builder.startObject("age");
                {
                    builder.field("type","integer");
                }
                builder.endObject();
                //Date  date
                builder.startObject("birthday");
                {
                    builder.field("type","date");
                    builder.field("format","yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis");
                }
                builder.endObject();
                //Data date
                builder.startObject("createTime");
                {
                    builder.field("type","date");
                    builder.field("format","yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis");
                }
                builder.endObject();
                //Numeric  long
                builder.startObject("timestamp");
                {
                    builder.field("type","long");
                }
                builder.endObject();
                //Boolean boolean
                builder.startObject("isBoy");
                {
                    builder.field("type","boolean");
                }
                builder.endObject();
            }
            builder.endObject();
        }
        builder.endObject();
        request.source(builder);
        // 新增mapping配置(同步)
        AcknowledgedResponse response = client.indices().putMapping(request, RequestOptions.DEFAULT);
        System.out.println(response);
    }
java操作
#关闭索引
POST /test_index3/_close

#结果
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "indices" : {
    "test_index3" : {
      "closed" : true
    }
  }
}

#打开索引
POST /test_index3/_open

#结果
{
  "acknowledged" : true,
  "shards_acknowledged" : true
}

#修改settings
PUT /test_index3/_settings
{
  "number_of_replicas": 2
}

#修改mappings
PUT /test_index3/_mappings
{
    "properties": {
      "test":{
        "type":"text"
      }
    }
}

#结果
{
  "acknowledged" : true
}
Kibana操作

6. 添加文档(单个/多个 同步+异步)

//----------------------------------------------------添加文档(单个 同步+异步)----------------------------------------------------

    @RequestMapping("/addDocument")
    public void addDocument() throws IOException {
        User user = new User();
        user.setName("张三");
        user.setFull_name("张三李四王五赵六");
        user.setAge(12);
        user.setIsBoy(true);
        user.setTimestamp(System.currentTimeMillis());//存入的是毫秒值1608108501654
        user.setCreateTime(new Date());//存入的是毫秒值1608108501654
        user.setBirthday(LocalDateTime.now());////存入的是时间格式2020-12-16 16:48:21

        IndexRequest request = new IndexRequest("test_index");
        // 规则 put /test_index/_doc/1
        //不指定id会随机生成 有该id会更新 没有该id会添加
        //request.id("1");
        request.timeout(TimeValue.timeValueSeconds(1));
        request.source(JSON.toJSONString(user), XContentType.JSON);

        //同步
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        // 结果:IndexResponse[index=test_index,type=_doc,id=nGvFanYBf998z9yKoZFx,version=1,result=created,seqNo=3,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}]
        System.out.println(response.toString());
        //新建:CREATED 更新:OK
        System.out.println(response.status());

        //异步
//        Cancellable cancellable = client.indexAsync(request, RequestOptions.DEFAULT, new ActionListener<IndexResponse>() {
//            @Override
//            public void onResponse(IndexResponse indexResponse) {
//                //这里可以获取添加的数据
//                log.debug("执行情况: " + indexResponse);
//            }
//
//            @Override
//            public void onFailure(Exception e) {
//                log.error("执行失败的原因");
//            }
//        });
    }

    //----------------------------------------------------添加文档(单个 map方式)----------------------------------------------------

    @RequestMapping("/addDocumentByMap")
    public void addDocumentByMap() throws IOException {
        Map<String, Object> map = new HashMap<>();
        map.put("name", "张三");
        map.put("full_name", "测试测试");
        map.put("age", 45);
        map.put("birthday", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()));
        map.put("createTime", System.currentTimeMillis());
        map.put("timestamp", System.currentTimeMillis());
        map.put("isBoy", false);
        IndexRequest request = new IndexRequest("test_index");
        request.id("kk");
        request.source(map);
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        System.out.println(response.status());
    }

    //----------------------------------------------------添加文档(批量)----------------------------------------------------

    @RequestMapping("/addBulkDocument")
    public void addBulkDocument() throws Exception {
        BulkRequest request = new BulkRequest();
        request.timeout("15s");
        List<User> users = new ArrayList<>();
        users.add(new User("张三", "测试1", 12, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true));
        Thread.sleep(1000);
        users.add(new User("李四", "测试2", 22, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true));
        Thread.sleep(1000);
        users.add(new User("王五", "测试3", 32, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true));
        Thread.sleep(1000);
        users.add(new User("赵六", "测试4", 42, LocalDateTime.now(), new Date(), System.currentTimeMillis(), true));
        for (int i = 0; i < users.size(); i++) {
            //指定id
            //request.add(new IndexRequest("test_index").id(""+(i+10)).source(JSON.toJSONString(users.get(i)), XContentType.JSON));
            //不指定id  后面还可以指定路由.routing("routing")
            request.add(new IndexRequest("test_index").source(JSON.toJSONString(users.get(i)), XContentType.JSON));
        }
        BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
        System.out.println(response);
        //false代表成功
        System.out.println(response.hasFailures());
    }
java操作
#添加文档(指定id)
POST /test_index3/_doc/2
{
  "age":1
}

#结果
{
  "_index" : "test_index3",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 3,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 2,
  "_primary_term" : 8
}

#添加文档(不指定id-->随机生成)
POST /test_index3/_doc
{
  "age":2
}


#结果
{
  "_index" : "test_index3",
  "_type" : "_doc",
  "_id" : "ZKlVzXYB6Pl4va605fxV",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 3,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 4,
  "_primary_term" : 8
}

#批量添加
POST _bulk
{"index":{"_index":"test_index3","_id":"7"}}
{"age":7}
{"index":{"_index":"test_index3","_id":"8"}}
{"age":8}
{"index":{"_index":"test_index3","_id":"9"}}
{"age":9}
Kibana操作

7. 删除文档

    //----------------------------------------------------删除文档(单个)----------------------------------------------------

    @RequestMapping("/deleteDocument")
    public void deleteDocument() throws IOException {
        DeleteRequest request = new DeleteRequest("test_index","kk");
        request.timeout("1s");
        DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
        //OK:删除成功  NOT_FOUND:未发现该id值对应的文档
        System.out.println(response.status());
    }
java操作
#删除文档
DELETE /test_index3/_doc/9

#结果
{
  "_index" : "test_index3",
  "_type" : "_doc",
  "_id" : "9",
  "_version" : 3,
  "result" : "deleted",
  "_shards" : {
    "total" : 3,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 12,
  "_primary_term" : 8
}
Kibana操作

8. 查询文档

    //----------------------------------------------------查询文档----------------------------------------------------

    @RequestMapping("/getDocument")
    public void getDocument() throws IOException {
        GetRequest request = new GetRequest("test_index","1");
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        //没有返回:null
        //存在返回:{birthday=2020-12-16 16:56:02, full_name=张三李四王五赵六, createTime=1608108962893, name=张三, age=22, isBoy=true, timestamp=1608108962893}
        System.out.println(response.getSource());
    }
java操作
#查看文档
GET /test_index3/_doc/7

#结果
{
  "_index" : "test_index3",
  "_type" : "_doc",
  "_id" : "7",
  "_version" : 2,
  "_seq_no" : 9,
  "_primary_term" : 8,
  "found" : true,
  "_source" : {
    "age" : 7
  }
}
Kibana操作

四、基本查询

1. 查询所有(match_all)

    //----------------------------------------------------查询所有(match_all)----------------------------------------------------

    @RequestMapping("/matchAllDocument")
    public void matchAllDocument() throws IOException {
        //1,构建SearchRequest请求对象,指定索引库
        SearchRequest request = new SearchRequest("test_index");
        //2,构建SearchSourceBuilder查询对象
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //3,构建QueryBuilder对象指定查询方式和查询条件
        QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
        //4,将QuseryBuilder对象设置到SearchSourceBuilder对象中
        sourceBuilder.query(queryBuilder);
        //5,将SearchSourceBuilder设置到request中
        request.source(sourceBuilder);
        //6,调用方法查询数据
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //7,解析返回结果
        SearchHit[] hits = response.getHits().getHits();
        //8. 返回查询数量 14 hits
        System.out.println(response.getHits().getTotalHits());
        for (int i = 0; i < hits.length; i++) {
            //9. 遍历所有数据 getSourceAsString 、getSourceAsMap
            //{"age":12,"birthday":"2020-12-16 17:15:12","createTime":1608110112784,"full_name":"测试1","isBoy":true,"name":"张三","timestamp":1608110112784}
            System.out.println(hits[i].getSourceAsString());
            //Map<String, Object> sourceAsMap = hits[i].getSourceAsMap();
        }

    }
java操作
#查看所有
GET /test_index3/_search
{
  "query": {
    "match_all": {}
  }
}


#结果
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test_index3",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "age" : 1
        }
      },
      {
        "_index" : "test_index3",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "age" : 1
        }
      }
    ]
  }
}
Kibana操作

2. 按条件查询match

//----------------------------------------------------匹配查询(match)----------------------------------------------------

    @RequestMapping("/matchDocument")
    public void matchDocument() throws IOException {
        //1,构建SearchRequest请求对象,指定索引库
        SearchRequest request = new SearchRequest("test_index");
        //2,构建SearchSourceBuilder查询对象
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //3,构建QueryBuilder对象指定查询方式和查询条件
        QueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "张三");
        //4,将QuseryBuilder对象设置到SearchSourceBuilder对象中
        sourceBuilder.query(queryBuilder);
        //5,将SearchSourceBuilder设置到SearchRequest中
        request.source(sourceBuilder);
        //6,调用方法查询数据
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        //7,解析返回结果
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }
java操作
#按条件查看
GET /test_index/_search
{
  "query": {
    "match": {
      "name": "赵六"
    }
  }
}


#结果
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 3.712596,
    "hits" : [
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "13",
        "_score" : 3.712596,
        "_source" : {
          "age" : 42,
          "birthday" : "2020-12-16 17:15:15",
          "createTime" : 1608110115801,
          "full_name" : "测试4",
          "isBoy" : true,
          "name" : "赵六",
          "timestamp" : 1608110115801
        }
      },
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "oWvVanYBf998z9yKDJHM",
        "_score" : 3.712596,
        "_source" : {
          "age" : 42,
          "birthday" : "2020-12-16 17:15:15",
          "createTime" : 1608110115801,
          "full_name" : "测试4",
          "isBoy" : true,
          "name" : "赵六",
          "timestamp" : 1608110115801
        }
      }
    ]
  }
}
Kibana操作

3. 单、多词条精确查询term、terms

//----------------------------------------------------词条精确匹配(term)----------------------------------------------------

    @RequestMapping("/termDocument")
    public void termDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        QueryBuilder queryBuilder = QueryBuilders.termQuery("name", "王五");
        sourceBuilder.query(queryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }

    //----------------------------------------------------多词条精确匹配(terms)----------------------------------------------------

    @RequestMapping("/termsDocument")
    public void termsDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        QueryBuilder queryBuilder = QueryBuilders.termsQuery("age", "22", "45");
        sourceBuilder.query(queryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }

        //写法2:
//        SearchRequest request = new SearchRequest("test_index");
//        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//        TermsQueryBuilder termsQueryBuilder = new TermsQueryBuilder("age", "22", "45");
//        sourceBuilder.query(termsQueryBuilder);
//        request.source(sourceBuilder);
//        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
//        SearchHit[] hits = searchResponse.getHits().getHits();
//        for (int i = 0; i <hits.length ; i++) {
//            System.out.println("返回的结果: "+hits[i].getSourceAsString());
//        }
    }
java操作
#term
GET /test_index/_search
{
  "query": {
    "term": {
      "age": {
        "value": "42"
      }
    }
  }
}

#terms
GET /test_index/_search
{
  "query": {
    "terms": {
      "age": [22,42]
    }
  }
}

#结果
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "13",
        "_score" : 1.0,
        "_source" : {
          "age" : 42,
          "birthday" : "2020-12-16 17:15:15",
          "createTime" : 1608110115801,
          "full_name" : "测试4",
          "isBoy" : true,
          "name" : "赵六",
          "timestamp" : 1608110115801
        }
      },
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "oWvVanYBf998z9yKDJHM",
        "_score" : 1.0,
        "_source" : {
          "age" : 42,
          "birthday" : "2020-12-16 17:15:15",
          "createTime" : 1608110115801,
          "full_name" : "测试4",
          "isBoy" : true,
          "name" : "赵六",
          "timestamp" : 1608110115801
        }
      }
    ]
  }
}
Kibana操作

4. 布尔组合查询bool

bool把各种其它查询通过must(与)、must_not(非)、should(或)的方式进行组合

//----------------------------------------------------布尔组合(bool)----------------------------------------------------
    //`bool`把各种其它查询通过`must`(与)、`must_not`(非)、`should`(或)的方式进行组合

    @RequestMapping("/boolDocument")
    public void boolDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询name字段值为李四或者王五的数据
//        QueryBuilder matchQueryBuilder1 = QueryBuilders.matchQuery("name", "王五");
//        QueryBuilder matchQueryBuilder2 = QueryBuilders.matchQuery("name", "李四");
//        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        boolQueryBuilder.should(matchQueryBuilder1);
//        boolQueryBuilder.should(matchQueryBuilder2);

        //查询name字段值为张三且age字段为22的
//        QueryBuilder matchQueryBuilder3 = QueryBuilders.matchQuery("name", "张三");
//        QueryBuilder matchQueryBuilder4 = QueryBuilders.matchQuery("age", "22");
//        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        boolQueryBuilder.must(matchQueryBuilder3);
//        boolQueryBuilder.must(matchQueryBuilder4);

        //查询name字段值不等于张三和李四的数据
        QueryBuilder matchQueryBuilder5 = QueryBuilders.matchQuery("name", "张三");
        QueryBuilder matchQueryBuilder6 = QueryBuilders.matchQuery("name", "李四");
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.mustNot(matchQueryBuilder5);
        boolQueryBuilder.mustNot(matchQueryBuilder6);
        sourceBuilder.query(boolQueryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }
java操作
#bool
GET /test_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "name": "张三"
          }
        },
        {
          "term": {
            "age":"45"
          }
        }
      ]
    }
  }
}


#结果
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.5212969,
    "hits" : [
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "NstqbnYB2MS8XlkB1n68",
        "_score" : 1.5212969,
        "_source" : {
          "full_name" : "测试测试",
          "createTime" : 1608170259651,
          "name" : "张三",
          "age" : 45,
          "isBoy" : false,
          "timestamp" : 1608170259651
        }
      }
    ]
  }
}
Kibana操作

5. 范围查询range

//----------------------------------------------------范围查询(range)----------------------------------------------------
    //`range` 查询找出那些落在指定区间内的数字或者时间 gt gte lt lte
    @RequestMapping("/rangeDocument")
    public void rangeDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询age字段大于22小于43的
        //QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").gt("22").lt("43");
        //查询birthday字段时间在2020-12-16 16:00:00~~~2020-12-16 17:00:00范围的
        QueryBuilder queryBuilder = QueryBuilders.rangeQuery("birthday").gte("2020-12-16 16:00:00").lte("2020-12-16 17:00:00");
        sourceBuilder.query(queryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }
java操作
#range
GET /test_index/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 43,
        "lte": 45
      }
    }
  }
}


#结果
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "NstqbnYB2MS8XlkB1n68",
        "_score" : 1.0,
        "_source" : {
          "full_name" : "测试测试",
          "createTime" : 1608170259651,
          "name" : "张三",
          "age" : 45,
          "isBoy" : false,
          "timestamp" : 1608170259651
        }
      }
    ]
  }
}
Kibana操作

6. 前缀查询prefix

//----------------------------------------------------前缀查询(prefix)----------------------------------------------------

    @RequestMapping("/prefixDocument")
    public void prefixDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询full_name字段以张三开头的数据
        QueryBuilder queryBuilder = QueryBuilders.prefixQuery("full_name","张三");
        sourceBuilder.query(queryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }
java操作
#prefix
GET /test_index/_search
{
  "query": {
    "prefix": {
      "name": "王"
    }
  }
}


#结果
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "12",
        "_score" : 1.0,
        "_source" : {
          "age" : 32,
          "birthday" : "2020-12-16 17:15:14",
          "createTime" : 1608110114796,
          "full_name" : "测试3",
          "isBoy" : true,
          "name" : "王五",
          "timestamp" : 1608110114796
        }
      },
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "oGvVanYBf998z9yKDJHM",
        "_score" : 1.0,
        "_source" : {
          "age" : 32,
          "birthday" : "2020-12-16 17:15:14",
          "createTime" : 1608110114796,
          "full_name" : "测试3",
          "isBoy" : true,
          "name" : "王五",
          "timestamp" : 1608110114796
        }
      }
    ]
  }
}
Kibana操作

7. 模糊查询wildcard

//----------------------------------------------------模糊查询(wildcard)----------------------------------------------------

    @RequestMapping("/wildcardDocument")
    public void wildcardDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询full_name字段以测试开头的数据
        //QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("full_name", "测试*");
        //查询full_name字段以1结尾的数据
        QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("full_name", "*1");
        sourceBuilder.query(queryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }
java操作
#wildcard
GET /test_index/_search
{
  "query": {
    "wildcard": {
      "full_name": "*试测*"
    }
  }
}


#结果
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "NstqbnYB2MS8XlkB1n68",
        "_score" : 1.0,
        "_source" : {
          "full_name" : "测试测试",
          "createTime" : 1608170259651,
          "name" : "张三",
          "age" : 45,
          "isBoy" : false,
          "timestamp" : 1608170259651
        }
      }
    ]
  }
}
Kibana操作

8. 模糊查询fuzzy

//----------------------------------------------------模糊查询(fuzzy)----------------------------------------------------

    @RequestMapping("/fuzzyDocument")
    public void fuzzyDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //模糊查询full_name字段值为测试1的数据 fuzzy允许有一定程度的不同 所以尽管数据库中数据是测试1 仍可以搜索出来
        QueryBuilder queryBuilder = QueryBuilders.fuzzyQuery("full_name", "测测1");
        sourceBuilder.query(queryBuilder);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }
java操作
#wildcard
GET /test_index/_search
{
  "query": {
    "fuzzy": {
      "name": {
        "value": "李四",
        "fuzziness": 0,
        "prefix_length": 0,
        "max_expansions": 50,
        "transpositions": true
      }
    }
  }
}


#结果
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.856298,
    "hits" : [
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "11",
        "_score" : 1.856298,
        "_source" : {
          "age" : 22,
          "birthday" : "2020-12-16 17:15:13",
          "createTime" : 1608110113788,
          "full_name" : "测试2",
          "isBoy" : true,
          "name" : "李四",
          "timestamp" : 1608110113788
        }
      },
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "n2vVanYBf998z9yKDJHM",
        "_score" : 1.856298,
        "_source" : {
          "age" : 22,
          "birthday" : "2020-12-16 17:15:13",
          "createTime" : 1608110113788,
          "full_name" : "测试2",
          "isBoy" : true,
          "name" : "李四",
          "timestamp" : 1608110113788
        }
      }
    ]
  }
}
Kibana操作

9. 单、多字段排序sort

    //----------------------------------------------------排序单字段、多字段(sort)----------------------------------------------------

    @RequestMapping("/sortDocument")
    public void sortDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //
        QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").lt(1000);
        //先按照age进行正排序,之后age字段相同的再按照birthday字段倒排序
        sourceBuilder.query(queryBuilder).sort("age", SortOrder.ASC).sort("birthday",SortOrder.DESC);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }
java操作
#wildcard
GET /test_index/_search
{
  "query": {
    "match": {
      "name": "张三"
    }
  },
  "sort": [
    {
      "timestamp": {
        "order": "desc"
      },
      "birthday": {
        "order": "desc"
      }
    }
  ]
}


#结果
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 8,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "NstqbnYB2MS8XlkB1n68",
        "_score" : null,
        "_source" : {
          "full_name" : "测试测试",
          "createTime" : 1608170259651,
          "name" : "张三",
          "age" : 45,
          "isBoy" : false,
          "timestamp" : 1608170259651
        },
        "sort" : [
          1608170259651,
          9223372036854775807
        ]
      },
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "o2vranYBf998z9yKX5HG",
        "_score" : null,
        "_source" : {
          "age" : 12,
          "birthday" : "2020-12-16 17:39:04",
          "createTime" : 1608111544743,
          "full_name" : "张三李四王五赵六",
          "isBoy" : true,
          "name" : "张三",
          "timestamp" : 1608111544743
        },
        "sort" : [
          1608111544743,
          1608140344000
        ]
      },
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "omvoanYBf998z9yKeJGS",
        "_score" : null,
        "_source" : {
          "age" : 12,
          "birthday" : "2020-12-16 17:36:28",
          "createTime" : 1608111388649,
          "full_name" : "张三李四王五赵六",
          "isBoy" : true,
          "name" : "张三",
          "timestamp" : 1608111388649
        },
        "sort" : [
          1608111388649,
          1608140188000
        ]
      },
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "10",
        "_score" : null,
        "_source" : {
          "age" : 12,
          "birthday" : "2020-12-16 17:15:12",
          "createTime" : 1608110112784,
          "full_name" : "测试1",
          "isBoy" : true,
          "name" : "张三",
          "timestamp" : 1608110112784
        },
        "sort" : [
          1608110112784,
          1608138912000
        ]
      },
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "nmvVanYBf998z9yKDJHL",
        "_score" : null,
        "_source" : {
          "age" : 12,
          "birthday" : "2020-12-16 17:15:12",
          "createTime" : 1608110112784,
          "full_name" : "测试1",
          "isBoy" : true,
          "name" : "张三",
          "timestamp" : 1608110112784
        },
        "sort" : [
          1608110112784,
          1608138912000
        ]
      },
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "nWvGanYBf998z9yKv5Gv",
        "_score" : null,
        "_source" : {
          "age" : 12,
          "birthday" : "2020-12-16 16:59:38",
          "createTime" : 1608109178797,
          "full_name" : "张三李四王五赵六",
          "isBoy" : true,
          "name" : "张三",
          "timestamp" : 1608109178797
        },
        "sort" : [
          1608109178797,
          1608137978000
        ]
      },
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "nGvFanYBf998z9yKoZFx",
        "_score" : null,
        "_source" : {
          "age" : 12,
          "birthday" : "2020-12-16 16:58:25",
          "createTime" : 1608109105356,
          "full_name" : "张三李四王五赵六",
          "isBoy" : true,
          "name" : "张三",
          "timestamp" : 1608109105356
        },
        "sort" : [
          1608109105356,
          1608137905000
        ]
      },
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : null,
        "_source" : {
          "age" : 22,
          "birthday" : "2020-12-16 16:56:02",
          "createTime" : 1608108962893,
          "full_name" : "张三李四王五赵六",
          "isBoy" : true,
          "name" : "张三",
          "timestamp" : 1608108962893
        },
        "sort" : [
          1608108962893,
          1608137762000
        ]
      }
    ]
  }
}
Kibana操作

10. 分页from size

//----------------------------------------------------分页(from、size)----------------------------------------------------

    @RequestMapping("/fromSizeDocument")
    public void fromSizeDocument() throws IOException {
        SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //
        QueryBuilder queryBuilder = QueryBuilders.rangeQuery("age").lt(1000);
        //查询从第一条开始(包括)查询两条数据(结果为查询前两条数据)
        sourceBuilder.query(queryBuilder).from(0).size(2);
        request.source(sourceBuilder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        for (int i = 0; i <hits.length ; i++) {
            System.out.println("返回的结果: "+hits[i].getSourceAsString());
        }
    }
java操作
#from size
GET /test_index/_search
{
  "query": {
    "match": {
      "name": "张三"
    }
  },
  "from": 0,
  "size": 2
}

#结果
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 8,
      "relation" : "eq"
    },
    "max_score" : 1.0425937,
    "hits" : [
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0425937,
        "_source" : {
          "age" : 22,
          "birthday" : "2020-12-16 16:56:02",
          "createTime" : 1608108962893,
          "full_name" : "张三李四王五赵六",
          "isBoy" : true,
          "name" : "张三",
          "timestamp" : 1608108962893
        }
      },
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "nGvFanYBf998z9yKoZFx",
        "_score" : 1.0425937,
        "_source" : {
          "age" : 12,
          "birthday" : "2020-12-16 16:58:25",
          "createTime" : 1608109105356,
          "full_name" : "张三李四王五赵六",
          "isBoy" : true,
          "name" : "张三",
          "timestamp" : 1608109105356
        }
      }
    ]
  }
}
Kibana操作

11. 高亮high light

//----------------------------------------------------高亮(high light)----------------------------------------------------

    @RequestMapping("/highLightDocument")
    public void highLightDocument() throws IOException {
        //条件搜索
        SearchRequest goods = new SearchRequest("test_index");
        SearchSourceBuilder builder = new SearchSourceBuilder();

        TermQueryBuilder title = QueryBuilders.termQuery("name", "李四");
        builder.query(title);
        builder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");//高亮的字段
        highlightBuilder.requireFieldMatch(false);//是否多个字段都高亮
        highlightBuilder.preTags("<span style='color:red'>");//前缀后缀
        highlightBuilder.postTags("</span>");
        builder.highlighter(highlightBuilder);

        //执行搜索
        goods.source(builder);
        SearchResponse search = client.search(goods, RequestOptions.DEFAULT);
        //解析结果
        ArrayList<Map<String,Object>> list = new ArrayList<>();
        for (SearchHit hit : search.getHits().getHits()) {
            //解析高亮的字段
            //获取高亮字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField name = highlightFields.get("name");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();//原来的结果
            //将原来的字段替换为高亮字段即可
            if (name!=null){
                Text[] fragments = name.fragments();
                String newTitle = "";
                for (Text text : fragments) {
                    newTitle +=text;
                }
                sourceAsMap.put("name",newTitle);//替换掉原来的内容
            }
            list.add(sourceAsMap);
        }
        System.out.println(list);
    }
java操作

持续更新!!!

原文地址:https://www.cnblogs.com/flyinghome/p/14226497.html