ElasticSearch es 整体梳理 Spirng boot整合开发

本文介绍了如何在Linux环境下使用Java API操作Elasticsearch,包括创建索引、数据结构、倒排索引原理、分片与备份,以及Spring Boot整合Es的示例。涵盖了索引管理、CRUD操作和高级查询技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

you know for search ! 官网入门指南Java API中文分词器 githubLinux Es Kibana 安装笔记

Es 数据格式

  • 索引( indices / indexes) - > 类似数据库database
  • 文档 (_doc) - > 存储数据的基本单元,比如一条用户数据,存储在 用户索引库
  • 类型(_type)- > 文档类型,如存储用户数据,类型就是 用户
  • /class/student/1 -> class 班级索引库,student 文档类型(7.x 默认类型 _doc)(一个个学生文档),id = 1 号学生
  • 面向文档,直接存储数据对象,如:索引一个学生到班级索引库中,就直接存储了学生这个对象的整体数据

数据类型 -》介绍地址

  • String::text: 一般用于全文检索,将当前Field进行分词, keyword: 关键字,当前file不会被分词
  • number: long,integer,short,byte,double,float,half_float,scaled_float
  • boolean: true,flase
  • binary(二进制类型): 支持Base64 encode string
  • range(范围型): long_range, double_range, date_range, and ip_range
  • Geo (geo_point经纬度类型): 经纬度存储
  • ip: ip存储

倒排索引

  • 在存放类似文本内容数据时,会按照当前分词器进行分词,并且将分词的内容存放到一个单独分词库中,当用户查询数据时会将当前查询内容进行分词,然后去分词库匹配,根据匹配的程度进行得分排序,并根据匹配结果形成一个倒排索引(匹配目录),查询的时候就会直接查询匹配的 文档id,通过id返回数据,就不会进行全查询。
  • 倒排:普通索引,如数据库索引一般情况是根据查询条件中对应的字段创建索引,形成一种类似图书目录的作用,达到快速查询的作用。而倒排索引是从 内容入手,将内容进行分词,将查询内容分词与其匹配,形成一个匹配目录。

分片

  • 每个索引默认会被分成5个分片(索引默认被分成5片存储),每一个分片都会存在至少一个备份分片,备份分片默认不会帮助检索数据,当检索压力特别大的时候,备份分片才会帮助检索数据
  • 每个分片可以在不同服务器上迁移,一个分片就是一个Lucene索引,一个包含倒排索引的文件目录
// 创建索引库,并指定数据结构
PUT /class
{
  "settings": {
    "number_of_shards": 1,  //分片数
    "number_of_replicas": 1, //备份数
    "index.analysis.analyzer.default.type": "ik_max_word" //默认分词器设置
  },
  "mappings": {				//mappings 文档字段属性映射
    "properties": {         //属性
      "name":{				//name字段
        "type": "text",    //文本类型,存储时会被分词,存入分词库中
        "analyzer": "ik_max_word", //中文ik分词器,最细粒度拆分
        "index": true,     //fasle 不作为检索条件
        "store": false     //是否需要额外存储
      },
      "english_name":{
         "type":"text",   
         "analyzer": "english" //指定英文分词器
  	  },
      "sex":{
         "type":"keyword"   //关键字类型,不拆分
      },
      "age":{
       "type":"integer"		//integer类型
      },
      "birthday":{
        "type":"date",		//date 类型
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd"
      },
      "interests":{			//爱好,下方存储数组型数据
        "type":"text",
        "analyzer": "ik_smart" //中文ik分词器,最粗粒度拆分
      }
    }
  }
}

查询索引

GET /megacorp

基本说明

  • Elasticsearch 是使用 Java 编写的,它的内部使用 Lucene 做索引与搜索,但是它的目的是使全文检索变得简单, 通过隐藏 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API
  • 通过各种的请求来操作数据,Es的Java客户端也是封装了各种的请求类
  • 比如创建一个索引 ↓
//CreateIndexRequest- > 创建索引的Request请求
CreateIndexRequest request = new CreateIndexRequest(index);
//CreateIndexResponse -> 请求响应
CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
flag=response.isAcknowledged();

包含特点:

  • 一个分布式的实时文档存储,每个字段 可以被索引与搜索
  • 一个分布式实时分析搜索引擎
  • 能胜任上百个服务节点的扩展,并支持 PB级别的结构化或者非结构化数据

数据的CRUD

添加 数据 👇

PUT /class/_doc/1   // PUT /class/1  _doc文档类型 7.x 默认文档类型都为_doc
{
    "name" : "何小数",
    "english_name" :  "hexiaoshu",
    "sex": "男",
    "age" : 18,
    "birthday" : "2003-05-11",
    "interests": "撸代码做运动"
}

未指定索引类型时,可以直接这个添加索引库,并添加文档数据 eg 👇

PUT /megacorp/employee/1	//megacorp 索引名称 employee类型名称 1员工id ,动态映射字段类型
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}

修改 数据 👇

PUT /class/_doc/1   // 修改1号学生的数据,年龄改为20
{
     "name" : "何小数",
     "english_name" :  "hexiaoshu",
     "sex": "男",
     "age" : 20,
     "birthday" : "2003-05-11",
     "interests": "撸代码做运动"
}

//响应结果
{
  "_index" : "class",    //索引名称
  "_type" : "_doc",       //文档类型
  "_id" : "1",			 //数据id
  "_version" : 2,		//类型数据库cas的version标记
  "result" : "updated",	//更新标识
  "_shards" : {			//分片数
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

查询数据:👇

//查询所有 _search
GET /class/_search
{
  "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" : "class",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "何小数",
          "english_name" : "hexiaoshu",
          "sex" : "男",
          "age" : 20,
          "birthday" : "2003-05-11",
          "interests" : "撸代码做运动"
        }
      },
      {
        "_index" : "class",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "千千",
          "english_name" : "qianqian",
          "sex" : "女",
          "age" : 18,
          "birthday" : "2005-05-11",
          "interests" : "画画吃水果"
        }
      }
    ]
  }
//查询单条数据, id为1
GET /class/_doc/1
{
  "_index" : "class",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "_seq_no" : 1,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "何小数",
    "english_name" : "hexiaoshu",
    "sex" : "男",
    "age" : 20,
    "birthday" : "2003-05-11",
    "interests" : "撸代码做运动"
  }
}

//单条件匹配查询
GET /class/_search
{
  "query": {
    "match": {
      "sex": "男"
    }   
  }
}
//如果查询Fileds 是text型,会按照你设置的分词器,配置查询分词
GET /class/_search
{
  "query": {
    "match": {
      "interests": "撸代码"
    }
  }
}
//多条件查询, sex为男 -年龄大于18  范围查询就是 filter-range- 字段 - gt/gte lt/lte
//should中的两个条件至少满足一个就可以。  
GET /class/_search
{
  "query": {
    "bool": {
      "must": { // or should
        "match":{
          "sex":"男"
        }
      },
      "filter":{ //filter 将会被缓存
          "range":{
            "age":{
              "gte":18
            }
          }
        }
    }
  }
}

过滤情况(filtering context)和查询情况(query context)

  • 过滤查询(Filtering queries)只是简单的检查包含或者排除,这就使得计算起来非常快,使用不评分查询(non-scoring queries),结果会被缓存到内存中以便快速读取
  • 评分查询(scoring queries)不仅仅要找出匹配的文档,还要计算每个匹配文档的相关性,计算相关性使得它们比不评分查询费力的多。同时,查询结果并不缓存
  • 倒排索引(inverted index),一个简单的评分查询在匹配少量文档时可能与一个涵盖百万文档的filter表现的一样好,甚至会更好。但是在一般情况下,一个filter 会比一个评分的query性能更优异,并且每次都表现的很稳定。
//multi_match 多个字段,执行同一种查询操作
GET /class/_search
{
  "query": {
    "multi_match": {
      "query": "小",
      "fields": ["interests","name"]
    }
    
  }
}
//term 精确查询, 生日在 2003-05-11
GET /class/_search
{
  "query": {
    "term": {
      "birthday": "2003-05-11"
    }
    
  }
}
//exists - field(这里就是field不是表示字段) 不为null  missing 为null
GET /class/_search
{
  "query": {
    "bool": {
      "must": [
       {
        "exists": {
            "field": "sex"
          }
        }
      ]
    }
  }
}

查询指定排序,默认按评分 _score 排序

//query 后接 sort ,按birthday 生日排序
GET /class/_search
{
  "query": {
    "bool": {
      "filter":{
          "range":{
            "age":{
              "gte":18
            }
          }
       }
    }
  },
  "sort": [
    {
      "birthday": {
        "order": "desc"
      }
    }
  ]
}
//多级排序
"sort": [
        { "date":   { "order": "desc" }},
        { "_score": { "order": "desc" }}
    ]

分页查询

//查询结尾 + from,size。 类似mysql limit
GET /class/_search
{
  "query": {
    "match": {
      "interests": "撸代码"
    }
  },
  "from" : 0 , "size" : 10
}
//深分页 scroll,scroll=3m代表当前查询的数据缓存3分钟
//-- 可以一次性将所有满足查询条件的数据,都放到内存中。分页的时候,在内存中查询。相对浅分页,就可以避免多次读取磁盘。
GET /class/_search?scroll=3m
{
  "query": {
    "match": {
      "interests": "撸代码"
    }
  },
  "from" : 0 , "size" : 10
}

Spring boot 基础框架 整合 ES 7.10

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com</groupId>
    <artifactId>es</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>es</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.10.0</elasticsearch.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.10.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- 网页解析-->
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.10.2</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                        <exclude>
                            <groupId>org.elasticsearch</groupId>
                            <artifactId>elasticsearch</artifactId>
                            <version>7.9.3</version>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

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;

/**
 * @Description
 * @Author Hexiaoshu
 * @Date 2021/1/5
 * @modify
 */
@Configuration
public class ElasticSearchConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        return new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("es服务地址", 9200, "http")
                        //,new HttpHost("localhost", 9201, "http")
                ));
    }

}

EsUtil 自己整合的常用查询 ES版本 7.10

import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.client.GetAliasesResponse;
import org.elasticsearch.client.indices.*;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
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.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.cluster.metadata.AliasMetadata;
import org.elasticsearch.cluster.metadata.MappingMetadata;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.AbstractQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
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.stereotype.Component;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @Description ElasticSearch 7.10.0 工具类
 * @Author Hexiaoshu
 * @Date 2021/1/5
 * @modify
 */
@Slf4j
@Component
public class EsUtil {
    @Resource
    private RestHighLevelClient restHighLevelClient;


    /**
     * 查询索引字段属性信息 index-mapping
     * @param index 索引名称
     * @return Map<String, MappingMetadata>
     */
    public Map<String, MappingMetadata> mappingIndex(String index){
        Map<String, MappingMetadata> mappings =null;
        try {
            GetMappingsRequest request = new GetMappingsRequest().indices(index);
            GetMappingsResponse response = restHighLevelClient.indices().getMapping(request, RequestOptions.DEFAULT);
            mappings= response.mappings();
        }catch (IOException e){
            log.error("es 连接异常");
        }
        return mappings;
    }


    /**
     * 查询所有索引库,alias -配置
     * Map<索引名称,索引元数据>
     * @return Map<String,Set<AliasMetadata>>
     */
    public Map<String,Set<AliasMetadata>> searchIndex(){
        Map<String,Set<AliasMetadata>> aliases = null;
        try {
            GetAliasesRequest request = new GetAliasesRequest();
            GetAliasesResponse response = restHighLevelClient.indices().getAlias(request, RequestOptions.DEFAULT);
            aliases = response.getAliases();
        }catch (IOException e){
            log.error("es 连接异常");
        }
        return aliases;
    }


    /**
     * 创建索引,动态映射属性
     * @param index 索引名称
     * @return Boolean
     */
    public Boolean createIndex(String index){
        boolean flag=false;
        try {
            CreateIndexRequest request = new CreateIndexRequest(index);
            CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
            flag=response.isAcknowledged();
        }catch (IOException e){
            log.error("es 连接异常");
        }
        return flag;
    }

    /**
     * 创建索引,指定索引属性
     * @param index 索引名称
     * @param source 字段属性 mappings-properties-{source}
     * @return Boolean
     */
    public Boolean createIndex(String index,Map<String,Map<String,Object>> source){
        boolean flag=false;
        try {
            CreateIndexRequest request = new CreateIndexRequest(index);
            XContentBuilder builder = getxContentBuilder(source);
            request.mapping(builder);
            CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
            flag=response.isAcknowledged();
        }catch (IOException e){
            log.error("es 连接异常");
        }
        return flag;
    }

    /**
     * 设置index 字段属性
     * @param source 字段
     * @return XContentBuilder
     * 请求json示例
     * {
     *   "name":{
     *       "type":"text",
     *       "analyzer": "ik_max_word"
     *   },
     *   "english_name":{
     *       "type":"text",
     *       "analyzer": "english"
     *   },
     *  "age":{
     *       "type":"integer"
     *   },
     *   "height":{
     *       "type":"double"
     *   },
     *   "hobby":{
     *       "type":"text",
     *       "analyzer": "ik_max_word",
     *       "index": true,
     *       "store": false
     *   },
     *   "major":{
     *       "type":"keyword"
     *   },
     *   "birthday":{
     *       "type":"date",
     *       "format": "yyyy-MM-dd HH:mm:ss"
     *   },
     *   "sex":{
     *       "type":"keyword"
     *   }
     * }
     * @throws IOException
     */
    private XContentBuilder getxContentBuilder(Map<String,Map<String,Object>> source) throws IOException {
        XContentBuilder builder = XContentFactory.jsonBuilder();
        builder.startObject();
        {
            builder.startObject("properties");
            {
                source.forEach((k,v)->{
                    try {
                        builder.startObject(k);
                        v.forEach((p,f)->{
                            try {
                                builder.field(p, f);
                            } catch (IOException ex) {
                                ex.printStackTrace();
                            }
                        });
                        builder.endObject();
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                });
            }
            builder.endObject();
        }
        builder.endObject();
        return builder;
    }

    /**
     * 判断索引是否存在
     * @param index 索引名称
     * @return Boolean
     */
    public Boolean existIndex(String index){
        boolean flag=false;
        try {
            GetIndexRequest request = new GetIndexRequest(index);
            flag= restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
        }catch (IOException e){
            log.error("es 连接异常");
        }
        return flag;
    }

    /**
     * 删除索引
     * @param index 索引名称
     * @return Boolean
     */
    public Boolean delIndex(String index){
        boolean flag=false;
        try {
            DeleteIndexRequest request = new DeleteIndexRequest(index);
            flag=restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT).isAcknowledged();
        }catch (IOException e){
            log.error("es 连接异常");
        }
        return flag;
    }

    /**
     * 添加文档
     * @param index 索引库
     * @param o  对象
     * @param id 文档id
     * @return status
     */
    public Boolean addDoc(String index,Object o,String id){
        boolean flag=false;
        IndexRequest request = new IndexRequest(index);
        request.id(id);
        request.source(JsonUtil.toStr(o), XContentType.JSON);
        try {
            IndexResponse response = restHighLevelClient.index(request,RequestOptions.DEFAULT);
            flag= 201 == response.status().getStatus();
        } catch (IOException e) {
            log.error("es 连接异常");
        }
        return flag;
    }

    /**
     * 批量添加文档
     * @param index 索引
     * @param list  集合
     * @return Boolean
     */
    public <T> Boolean addDocs(String index, List<T> list){
        if (list==null){
            return null;
        }
        boolean flag=false;
        BulkRequest request = new BulkRequest();
        list.forEach(e->{
            request.add(new IndexRequest(index).source(JsonUtil.toStr(e),XContentType.JSON));
        });
        try {
            BulkResponse responses = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
            flag=!responses.hasFailures();
        } catch (IOException e) {
            log.error("es 连接异常");
        }
        return flag;
    }



    /**
     * 更新文档
     * @param index 索引
     * @param o     对象
     * @param id    文档id
     * @return Boolean
     */
    public Boolean updateDoc(String index,Object o,String id){
        boolean flag=false;
        UpdateRequest request = new UpdateRequest(index,id).doc(JsonUtil.toStr(o), XContentType.JSON);
        try {
            UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
            flag = 200==response.status().getStatus();
        } catch (IOException e) {
            log.error("es 连接异常");
        }
        return flag;
    }

    /**
     * 删除文档
     * @param index 索引
     * @param docId 文档id
     * @return Boolean
     */
    public Boolean delDoc(String index,String docId){
        boolean flag=false;
        DeleteRequest request = new DeleteRequest(index,docId);
        try {
            DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
            flag=200==response.status().getStatus();
        } catch (IOException e) {
            log.error("es 连接异常");
        }
        return flag;
    }

    /**
     * 根据id获取文档
     * @param index 索引库
     * @param docId 文档id
     * @return GetResponse
     */
    public GetResponse getDocById(String index,String docId){
        GetResponse response=null;
        GetRequest request = new GetRequest(index,docId);
        try {
             response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("es 连接异常");
        }
        return response;
    }

    /**
     * 文档精确查询
     * @param index 索引
     * @param filed 属性
     * @param value 值
     * @param page 当前页
     * @param size 每页数量
     * @return SearchResponse
     */
    public List<Map<String,Object>> searchDocTerm(String index,String filed,String value,String sortFiled,String sort,Integer page,Integer size){
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field(filed);
        highlightBuilder.requireFieldMatch(false);
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        SearchRequest request = setQuery(index, QueryBuilders.termQuery(filed,value),highlightBuilder,sortFiled,sort,page,size);
        return getData(request,filed);
    }

    /**
     * 文档全查询
     * @param index 索引
     * @param page 当前页
     * @param size 每页数量
     * @return SearchResponse
     */
    public List<Map<String,Object>> searchDocAll(String index,Integer page,Integer size){
        SearchRequest request = setQuery(index, QueryBuilders.matchAllQuery(),null,null,null,page,size);
        return getData(request,null);
    }

    /**
     * 获取sourceMap数据
     * @param request SearchRequest
     * @return List<Map<String, Object>>
     */
    private List<Map<String, Object>> getData(SearchRequest request,String highlightName) {
        List<Map<String,Object>> list = new LinkedList<>();
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            SearchHit[] hits = response.getHits().getHits();
            Arrays.stream(hits).forEach(e->{
                Map<String, Object> sourceAsMap = e.getSourceAsMap();
                if (highlightName!=null){
                    HighlightField highlightField = e.getHighlightFields().get(highlightName);
                    if (highlightField!=null){
                        Text[] fragments = highlightField.fragments();
                        AtomicReference<String> highlight= new AtomicReference<>(highlightName);
                        Arrays.stream(fragments).forEach(h-> highlight.updateAndGet(v -> v + h));
                        sourceAsMap.put(highlightName,highlight.get());
                    }
                }
                list.add(sourceAsMap);
            });
        } catch (IOException e) {
            log.error("es 连接异常");
        }
        return list;
    }

    /**
     * 查询设置
     * @param index 索引
     * @param queryBuilder 查询抽象类
     * @return SearchRequest
     */
    private SearchRequest setQuery(String index,AbstractQueryBuilder queryBuilder,HighlightBuilder highlightBuilder,String sortFiled,String sort,Integer page,Integer size){
        SearchRequest request = new SearchRequest(index);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.from(page==null?1:page);
        sourceBuilder.size(size==null?10:size);
        sourceBuilder.query(queryBuilder);
        if (sortFiled!=null){
            sourceBuilder.sort(sortFiled,"desc".equals(sort)?SortOrder.DESC:SortOrder.ASC );
        }
        if (highlightBuilder!=null){
            sourceBuilder.highlighter(highlightBuilder);
        }
        request.source(sourceBuilder);
        return  request;
    }
}

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.List;

/**
 * @Description json转化工具类
 * @Author Hexiaoshu
 * @Date 2021/1/9
 * @modify
 */
public class JsonUtil {


    /**
     * json字符串转对象
     * @param json json字符串
     * @param c    对象class字节码
     * @param <T> T
     * @return T
     */
    public static <T> T toObj(String json, Class<T> c){
        return JSON.toJavaObject(JSONObject.parseObject(json),c);
    }

    /**
     * json转 List
     * @param json json字符串
     * @param c    对象class字节码
     * @param <T>  T
     * @return List
     */
    public static  <T> List toList(String json, Class<T> c){
        return JSONArray.parseArray(json, c);
    }

    /**
     * Object转json
     * @param o obj
     * @return String
     */
    public static String toStr(Object o){
        return JSON.toJSONString(o);
    }


}
@Resource
private EsUtil esUtil;

@PostMapping("/create_index")
public Result test(String index) {
     Boolean isSuccess = esUtil.createIndex(index);
     return Result.ok(isSuccess);
 }

下篇主更搜索,我在捋一捋!

哈哈

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值