ES工具类

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-lang3</artifactId>
</dependency>

注解

import java.lang.annotation.*;

/**
 * 该注解类用于注解映射到ES中的数据字段,类似Hibernate中实体字段映射数据库中的表字段
 * @version 1.0
 * @date 2022/5/19 9:46
 * @since : JDK 11
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
@Inherited
public @interface ESMappingField {

    /**
     * 字段名称
     * @return
     */
    String fieldName() default "";

    /**
     * 数据类型
     * @return
     */
    String dataType() default "";

    /**
     * 使用哪种分词器
     * @return
     */
    String setAnalyzer() default "";

    /**
     * 是否使用分词功能
     * @return
     */
    boolean isAnalyze() default false;
}

ES索引

controller

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;

/**
 * @version 1.0
 * @date 2022/5/19 9:48
 * @since : JDK 11
 */
@RestController
@RequestMapping("/es/index")
@Api(value = "/es/index", tags = "ES索引操作")
public class EsIndexController {

    @Autowired
    private IElasticsearchIndexService elasticsearchIndexService;

    @GetMapping("/isIndexExists")
    @ApiOperation(value = "判断索引是否存在")
    @ApiImplicitParam(value = "索引名称", name = "indexName", dataTypeClass = String.class, required = true, paramType = "query")
    public R<Object> isIndexExists(@RequestParam(value = "indexName") String indexName) throws IOException {
        return R.ok(elasticsearchIndexService.isIndexExists(indexName));
    }


    @PostMapping("/createIndex")
    @ApiOperation(value = "创建索引")
    @ApiImplicitParam(value = "索引名称", name = "indexName", dataTypeClass = String.class, required = true, paramType = "query")
    public R<Object> createIndex(@RequestParam(value = "indexName") String indexName) throws IOException {
        return R.ok(elasticsearchIndexService.createIndex(indexName));
    }

    @PostMapping("/createIndexWithShards")
    @ApiOperation(value = "创建索引及自定义分片信息")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "索引名称", name = "indexName", dataTypeClass = String.class, required = true, paramType = "query"),
            @ApiImplicitParam(value = "分片数量", name = "numberOfShards", dataTypeClass = int.class, required = true, paramType = "query"),
            @ApiImplicitParam(value = "副本数量", name = "numberOfReplicas", dataTypeClass = int.class, required = true, paramType = "query")
    })
    public R<Object> createIndexWithShards(@RequestParam(value = "indexName") String indexName,
                                           @RequestParam(value = "numberOfShards") int numberOfShards,
                                           @RequestParam(value = "numberOfReplicas") int numberOfReplicas) throws IOException {
        return R.ok(elasticsearchIndexService.createIndexWithShards(indexName, numberOfShards, numberOfReplicas));
    }

    @PostMapping("/deleteIndex")
    @ApiOperation(value = "删除索引")
    @ApiImplicitParam(value = "索引名称", name = "indexName", dataTypeClass = String.class, required = true, paramType = "query")
    public R<Object> deleteIndex(@RequestParam(value = "indexName") String indexName) throws IOException {
        return R.ok(elasticsearchIndexService.deleteIndex(indexName));
    }

    /**
     * 判断索引别名是否存在
     *
     * @param aliasName
     * @return
     */
    @GetMapping("/isAliasExists")
    @ApiOperation(value = "判断索引别名是否存在")
    @ApiImplicitParam(value = "别名", name = "aliasName", dataTypeClass = String.class, required = true, paramType = "query")
    public R<Object> isAliasExists(@RequestParam(value = "aliasName") String aliasName) throws IOException {
        return R.ok(elasticsearchIndexService.isAliasExists(aliasName));
    }

    @PostMapping("/createIndexWithAlias")
    @ApiOperation(value = "创建索引同时给索引创建别名")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "索引名称", name = "indexName", dataTypeClass = String.class, required = true, paramType = "query"),
            @ApiImplicitParam(value = "别名", name = "aliasName", dataTypeClass = String.class, required = true, paramType = "query")
    })
    public R<Object> createIndexWithAlias(@RequestParam(value = "indexName") String indexName,
                                          @RequestParam(value = "aliasName") String aliasName) throws IOException {
        return R.ok(elasticsearchIndexService.createIndexWithAlias(indexName, aliasName));
    }

    @PostMapping("/addAlias")
    @ApiOperation(value = "给索引添加别名")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "索引名称", name = "indexName", dataTypeClass = String.class, required = true, paramType = "query"),
            @ApiImplicitParam(value = "别名", name = "aliasName", dataTypeClass = String.class, required = true, paramType = "query")
    })
    public R<Object> addAlias(@RequestParam(value = "indexName") String indexName,
                              @RequestParam(value = "aliasName") String aliasName) throws IOException {
        return R.ok(elasticsearchIndexService.addAlias(indexName, aliasName));
    }

    @PostMapping("/deleteAlias")
    @ApiOperation(value = "删除某个索引的别名")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "索引名称", name = "indexName", dataTypeClass = String.class, required = true, paramType = "query"),
            @ApiImplicitParam(value = "别名", name = "aliasName", dataTypeClass = String.class, required = true, paramType = "query")
    })
    public R<Object> deleteAlias(@RequestParam(value = "indexName") String indexName,
                                 @RequestParam(value = "aliasName") String aliasName) throws IOException {
        return R.ok(elasticsearchIndexService.deleteAlias(indexName, aliasName));
    }

    @PostMapping("/reindex")
    @ApiOperation(value = "重建索引,拷贝数据")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "原索引名称", name = "oldIndexName", dataTypeClass = String.class, required = true, paramType = "query"),
            @ApiImplicitParam(value = "新索引名称", name = "newIndexName", dataTypeClass = String.class, required = true, paramType = "query")
    })
    void reindex(@RequestParam(value = "oldIndexName") String oldIndexName,
                 @RequestParam(value = "newIndexName") String newIndexName) throws IOException {
        elasticsearchIndexService.reindex(oldIndexName, newIndexName);

    }

    @PostMapping("/changeAliasAfterReindex")
    @ApiOperation(value = "重建索引后修改别名")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "原索引名称别名", name = "aliasName", dataTypeClass = String.class, required = true, paramType = "query"),
            @ApiImplicitParam(value = "原索引名称", name = "oldIndexName", dataTypeClass = String.class, required = true, paramType = "query"),
            @ApiImplicitParam(value = "新索引名称", name = "newIndexName", dataTypeClass = String.class, required = true, paramType = "query")
    })
    public R<Object> changeAliasAfterReindex(@RequestParam(value = "aliasName") String aliasName,
                                             @RequestParam(value = "oldIndexName") String oldIndexName,
                                             @RequestParam(value = "newIndexName") String newIndexName) throws IOException {
        return R.ok(elasticsearchIndexService.changeAliasAfterReindex(aliasName, oldIndexName, newIndexName));
    }


    /**
     * 添加mapping
     *
     * @param indexName
     * @param className
     * @return
     */
    @PostMapping("/addMapping")
    @ApiOperation(value = "添加mapping")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "索引名称", name = "indexName", dataTypeClass = String.class, required = true, paramType = "query"),
            @ApiImplicitParam(value = "添加的映射实体权限定名", name = "className", dataTypeClass = String.class, required = true, paramType = "query")
    })
    public R<Object> addMapping(@RequestParam(value = "indexName") String indexName,
                                @RequestParam(value = "className") String className) throws IOException, ClassNotFoundException {
        Class<?> clazz = Class.forName(className);
        return R.ok(elasticsearchIndexService.addMapping(indexName, clazz));
    }
}

响应主体R

import java.io.Serializable;

/**
 * 响应信息主体

 */
public class R<T> implements Serializable
{
    private static final long serialVersionUID = 1L;

    /** 成功 */
    public static final int SUCCESS = 200;

    /** 失败 */
    public static final int FAIL = 500;

    private int code;

    private String msg;

    private T data;

    public static <T> R<T> ok()
    {
        return restResult(null, SUCCESS, null);
    }

    public static <T> R<T> ok(T data)
    {
        return restResult(data, SUCCESS, null);
    }

    public static <T> R<T> ok(T data, String msg)
    {
        return restResult(data, SUCCESS, msg);
    }

    public static <T> R<T> fail()
    {
        return restResult(null, FAIL, null);
    }

    public static <T> R<T> fail(String msg)
    {
        return restResult(null, FAIL, msg);
    }

    public static <T> R<T> fail(T data)
    {
        return restResult(data, FAIL, null);
    }

    public static <T> R<T> fail(T data, String msg)
    {
        return restResult(data, FAIL, msg);
    }

    public static <T> R<T> fail(int code, String msg)
    {
        return restResult(null, code, msg);
    }

    private static <T> R<T> restResult(T data, int code, String msg)
    {
        R<T> apiResult = new R<>();
        apiResult.setCode(code);
        apiResult.setData(data);
        apiResult.setMsg(msg);
        return apiResult;
    }

    public int getCode()
    {
        return code;
    }

    public void setCode(int code)
    {
        this.code = code;
    }

    public String getMsg()
    {
        return msg;
    }

    public void setMsg(String msg)
    {
        this.msg = msg;
    }

    public T getData()
    {
        return data;
    }

    public void setData(T data)
    {
        this.data = data;
    }
}

service

import java.io.IOException;

/**
 * @version 1.0
 * @date 2022/5/19 9:41
 * @since : JDK 11
 */
public interface IElasticsearchIndexService {

    /**
     * 判断索引是否存在
     * @param indexName
     * @return
     */
    Boolean isIndexExists(String indexName) throws IOException;

    /**
     * 创建索引
     *
     * @param indexName
     * @param numberOfShards
     * @param numberOfReplicas
     * @return
     */
    Boolean createIndexWithShards(String indexName, Integer numberOfShards, Integer numberOfReplicas) throws IOException;

    /**
     * 创建索引(默认1个分片,1个副本)
     *
     * @param indexName
     * @return
     */
    Boolean createIndex(String indexName) throws IOException;

    /**
     * 删除索引
     * @param indexName
     * @return
     * @throws IOException
     */
    Boolean deleteIndex(String indexName) throws IOException;

    /**
     * 判断索引别名是否存在
     * @param aliasName
     * @return
     */
    Boolean isAliasExists(String aliasName) throws IOException;

    /**
     * 创建索引同时给索引创建别名
     *
     * @param indexName
     * @param aliasName
     * @return
     */
    Boolean createIndexWithAlias(String indexName, String aliasName) throws IOException;

    /**
     * 给索引添加别名
     * @param indexName
     * @param aliasName
     * @return
     * @throws IOException
     */
    Boolean addAlias(String indexName, String aliasName) throws IOException;

    /**
     * 删除某个索引的别名
     * @param aliasName
     * @return
     * @throws IOException
     */
    Boolean deleteAlias(String indexName,String aliasName) throws IOException;

    /**
     * 重建索引,拷贝数据
     *
     * @param oldIndexname
     * @param newIndexname
     */
    void reindex(String oldIndexname, String newIndexname) throws IOException;

    /**
     * 重建索引后修改别名
     *
     * @param aliasname
     * @param oldIndexname
     * @param newIndexname
     * @return
     */
    Boolean changeAliasAfterReindex(String aliasname, String oldIndexname, String newIndexname) throws IOException ;

    /**
     * 添加mapping
     * @param indexName
     * @param clazz
     * @return
     */
    Boolean addMapping(String indexName, Class<?> clazz) throws IOException;

}

serviceImpl

import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.*;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.reindex.ReindexRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Map;

/**
 * @version 1.0
 * @date 2022/5/19 9:42
 * @since : JDK 11
 */
@Service
public class ElasticsearchIndexServiceImpl implements IElasticsearchIndexService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;


    @Override
    public Boolean isIndexExists(String indexName) throws IOException {
        GetIndexRequest getIndexRequest = new GetIndexRequest(indexName);
        getIndexRequest.humanReadable(true);
        return restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
    }

    @Override
    public Boolean createIndexWithShards(String indexName, Integer numberOfShards, Integer numberOfReplicas) throws IOException {
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
        //设置分片信息
        numberOfShards = numberOfShards == null ? 1 : numberOfShards;
        numberOfReplicas = numberOfReplicas == null ? 1 : numberOfReplicas;
        createIndexRequest.settings(Settings.builder().
                put("index.number_of_shards", numberOfShards)
                .put("index.number_of_replicas", numberOfReplicas));
        //创建索引
        CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        return createIndexResponse.isAcknowledged();
    }

    @Override
    public Boolean createIndex(String indexName) throws IOException {
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
        CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        return createIndexResponse.isAcknowledged();
    }

    @Override
    public Boolean deleteIndex(String indexName) throws IOException {
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);
        deleteIndexRequest.indicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN);
        AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
        return delete.isAcknowledged();
    }

    @Override
    public Boolean isAliasExists(String aliasName) throws IOException {
        GetAliasesRequest getAliasesRequest = new GetAliasesRequest(aliasName);
        return restHighLevelClient.indices().existsAlias(getAliasesRequest, RequestOptions.DEFAULT);
    }


    @Override
    public Boolean createIndexWithAlias(String indexName, String aliasName) throws IOException {
        CreateIndexRequest request = new CreateIndexRequest(indexName);
        if (StringUtils.isNotEmpty(aliasName)) {
            request.alias(new Alias(aliasName));
        }
        CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        return createIndexResponse.isAcknowledged();
    }

    @Override
    public Boolean addAlias(String indexName, String aliasName) throws IOException {
        IndicesAliasesRequest aliasesRequest = new IndicesAliasesRequest();
        IndicesAliasesRequest.AliasActions aliasAction =
                new IndicesAliasesRequest.AliasActions(IndicesAliasesRequest.AliasActions.Type.ADD)
                        .index(indexName)
                        .alias(aliasName);
        aliasesRequest.addAliasAction(aliasAction);
        AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().updateAliases(aliasesRequest,RequestOptions.DEFAULT);
        return acknowledgedResponse.isAcknowledged();
    }

    @Override
    public void reindex(String oldIndexname, String newIndexname) throws IOException {
        ReindexRequest request = new ReindexRequest();
        request.setSourceIndices(oldIndexname);
        request.setDestIndex(newIndexname);
        request.setSourceBatchSize(1000);
        request.setDestOpType("create");
        request.setConflicts("proceed");
//        request.setScroll(TimeValue.timeValueMinutes(10));
//        request.setTimeout(TimeValue.timeValueMinutes(20));
        request.setRefresh(true);
        restHighLevelClient.reindex(request, RequestOptions.DEFAULT);
    }

    @Override
    public Boolean deleteAlias(String indexName,String aliasName) throws IOException {
        DeleteAliasRequest deleteAliasRequest = new DeleteAliasRequest(indexName,aliasName);
        org.elasticsearch.client.core.AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().deleteAlias(deleteAliasRequest, RequestOptions.DEFAULT);
        return acknowledgedResponse.isAcknowledged();
    }

    @Override
    public Boolean changeAliasAfterReindex(String aliasname, String oldIndexname, String newIndexname) throws IOException {
        IndicesAliasesRequest.AliasActions addIndexAction = new IndicesAliasesRequest.AliasActions(
                IndicesAliasesRequest.AliasActions.Type.ADD).index(newIndexname).alias(aliasname);
        IndicesAliasesRequest.AliasActions removeAction = new IndicesAliasesRequest.AliasActions(
                IndicesAliasesRequest.AliasActions.Type.REMOVE).index(oldIndexname).alias(aliasname);

        IndicesAliasesRequest indicesAliasesRequest = new IndicesAliasesRequest();
        indicesAliasesRequest.addAliasAction(addIndexAction);
        indicesAliasesRequest.addAliasAction(removeAction);
        AcknowledgedResponse indicesAliasesResponse = restHighLevelClient.indices().updateAliases(indicesAliasesRequest,
                RequestOptions.DEFAULT);
        return indicesAliasesResponse.isAcknowledged();
    }


    @Override
    public Boolean addMapping(String indexName, Class<?> clazz) throws IOException {
        PutMappingRequest putMappingRequest = new PutMappingRequest(indexName);
        Map<String, Object> jsonMap = Maps.newHashMap();
        Map<String, Object> properties = Maps.newHashMap();

        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            ESMappingField esMappingField = field.getDeclaredAnnotation(ESMappingField.class);
            if (esMappingField != null) {
                String fieldname = esMappingField.fieldName();
                String datatype = esMappingField.dataType();
                String analyzer = esMappingField.setAnalyzer();
                boolean isanalye = esMappingField.isAnalyze();
                Map<String, Object> m = Maps.newHashMap();
                m.put("type", datatype);
                if (isanalye && StringUtils.isNotEmpty(analyzer)) {
                    m.put("analyzer", analyzer);
                    m.put("search_analyzer", analyzer);
                }
                properties.put(fieldname, m);
            }
        }
        jsonMap.put("properties", properties);
        putMappingRequest.source(jsonMap);
        AcknowledgedResponse putMappingResponse = restHighLevelClient.indices().putMapping(putMappingRequest,
                RequestOptions.DEFAULT);
        return putMappingResponse.isAcknowledged();
    }
}

ES数据访问

import cn.hutool.json.JSON;
import org.elasticsearch.action.search.SearchRequest;

import java.util.List;
import java.util.Map;

/**
 * @version 1.0
 * @date 2022/5/23 16:35
 * @since : JDK 11
 */
public interface IElasticsearchDataService {

    boolean saveOne(String indexName, Map<String, ?> data);

    boolean saveList(String indexName, List<Map<String, ?>> dataList);

    boolean saveObj(String indexName, Object data);

    boolean saveObjs(String indexName, List<Object> dataList);

    JSON searchBySearchRequest(SearchRequest request);

    List<Map<String, Object>> searchByIds(List<String> indexName, String... ids);

    boolean updateById(String indexName, Map<String, ?> data, String idMap);

    boolean deleteById(List<String> indexList, String id);

    R commonSearchDataForEs(SearchRequest req);


}
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
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.core.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

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

/**
 * @version 1.0
 * @date 2022/5/23 16:39
 * @since : JDK 11
 */
@Service
public class ElasticsearchDataServiceImpl implements IElasticsearchDataService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public boolean saveOne(String indexName, Map<String, ?> data) {
        if (StrUtil.isEmpty(indexName) || null == data) {
            return false;
        }
        IndexRequest request = new IndexRequest(indexName);
        request.source(data);
        IndexResponse response = null;
        try {
            response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
            if (response.getResult().name().equalsIgnoreCase("created")) {
                return true;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }

    @Override
    public boolean saveList(String indexName, List<Map<String, ?>> dataList) {
        if (!StrUtil.isLowerCase(indexName)) {
            // 索引名称必须全部小写
            return false;
        }
        if (CollectionUtils.isEmpty(dataList) || StrUtil.isEmpty(indexName)) {
            return false;
        }
        BulkRequest request = new BulkRequest();
        for (Map<String, ?> item : dataList) {
            request.add(new IndexRequest(indexName).source(item));
        }
        try {
            BulkResponse bulk = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
            if (bulk.status().getStatus() == HttpStatus.HTTP_OK) {
                return true;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }

    @Override
    public boolean saveObj(String indexName, Object data) {
        if (StrUtil.isEmpty(indexName) || null == data) {
            return false;
        }
        Map<String, ?> map = BeanMapTool.beanToMap(data);
        return this.saveOne(indexName, map);
    }

    @Override
    public boolean saveObjs(String indexName, List<Object> dataList) {
        if (StrUtil.isEmpty(indexName) || CollectionUtils.isEmpty(dataList)) {
            return false;
        }
        List<Map<String, ?>> maps = BeanMapTool.objectsToMaps(dataList);
        return this.saveList(indexName, maps);
    }

    @Override
    public JSON searchBySearchRequest(SearchRequest request) {
        if (null == request) {
            return null;
        }
        JSONArray res = new JSONArray();
        try {
            SearchHits hits = restHighLevelClient.search(request, RequestOptions.DEFAULT).getHits();
            if (hits.getTotalHits().value > 0) {
                for (SearchHit hit : hits) {
                    Map<String, Object> map = hit.getSourceAsMap();
                    res.add(map);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return res;
    }

    @Override
    public List<Map<String, Object>> searchByIds(List<String> indexName, String... ids) {
        if (CollectionUtil.isEmpty(indexName) || ArrayUtil.isEmpty(ids)) {
            return null;
        }
        SearchRequest request = new SearchRequest();
        request.indices(ArrayUtil.toArray(indexName, String.class));
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.filter(QueryBuilders.idsQuery().addIds(ids));
        builder.query(boolQueryBuilder);
        request.source(builder);
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            SearchHit[] searchHits = response.getHits().getHits();
            for (SearchHit hit : searchHits) {
                Map<String, Object> map = hit.getSourceAsMap();
                list.add(map);
            }
            return list;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public boolean updateById(String indexName, Map<String, ?> data, String idMap) {
        if (StrUtil.isEmpty(indexName) || null == data || StrUtil.isEmpty(idMap)) {
            return false;
        }
        UpdateRequest request = new UpdateRequest(indexName, data.get(idMap).toString()).doc(data);
        try {
            UpdateResponse update = restHighLevelClient.update(request, RequestOptions.DEFAULT);
            if (update.status().getStatus() == HttpStatus.HTTP_OK) {
                return true;
            } else {
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean deleteById(List<String> indexList, String id) {
        if (CollectionUtil.isEmpty(indexList) || StrUtil.isEmpty(id)) {
            return false;
        }
        DeleteByQueryRequest request = new DeleteByQueryRequest();
        request.indices(ArrayUtil.toArray(indexList, String.class));
        request.setQuery(new TermQueryBuilder("id.keyword", id));
        // 更新最大文档数
        request.setSize(10);
        // 批次大小
        request.setBatchSize(1000);
        // 并行
        request.setSlices(2);
        // 使用滚动参数来控制“搜索上下文”存活的时间
        request.setScroll(TimeValue.timeValueMinutes(10));
        // 超时
        request.setTimeout(TimeValue.timeValueMinutes(2));
        // 刷新索引
        request.setRefresh(true);
        BulkByScrollResponse response = null;
        try {
            response = restHighLevelClient.deleteByQuery(request, RequestOptions.DEFAULT);
            return response.getStatus().getUpdated() == 0;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }



    /**
     * rpc查询通用结果组装
     *
     * @param req
     * @return
     */
    @Override
    public R commonSearchDataForEs(SearchRequest req) {
        String msg = null;
        try {
            SearchResponse search = restHighLevelClient.search(req, RequestOptions.DEFAULT);
            SearchHits hits = search.getHits();
            long total = hits.getTotalHits().value;
            if (total > 0) {
                ArrayList<Object> data = new ArrayList<>();
                hits.forEach(a -> data.add(a.getSourceAsMap()));
                return R.ok(Dict.of("total", total, "data", data));
            }
        } catch (IOException e) {
            e.printStackTrace();
            msg = e.getMessage();
        }
        return R.fail(msg);
    }
}

【BeanMapTool】

import org.springframework.cglib.beans.BeanMap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * bean和map互转
 *
 * @author JHL
 * @version 1.0
 * @date 2022/5/5 13:45
 * @since : JDK 11
 */
public class BeanMapTool {

    public static <T> Map<String, ?> beanToMap(T bean) {
        BeanMap beanMap = BeanMap.create(bean);
        Map<String, Object> map = new HashMap<>();

        beanMap.forEach((key, value) -> {
            map.put(String.valueOf(key), value);
        });
        return map;
    }

    public static <T> T mapToBean(Map<String, ?> map, Class<T> clazz)
            throws IllegalAccessException, InstantiationException {
        T bean = clazz.newInstance();
        BeanMap beanMap = BeanMap.create(bean);
        beanMap.putAll(map);
        return bean;
    }

    public static <T> List<Map<String, ?>> objectsToMaps(List<T> objList) {
        List<Map<String, ?>> list = new ArrayList<>();
        if (objList != null && objList.size() > 0) {
            Map<String, ?> map = null;
            T bean = null;
            for (int i = 0, size = objList.size(); i < size; i++) {
                bean = objList.get(i);
                map = beanToMap(bean);
                list.add(map);
            }
        }
        return list;
    }

    public static <T> List<T> mapsToObjects(List<Map<String, ?>> maps, Class<T> clazz)
            throws InstantiationException, IllegalAccessException {
        List<T> list = new ArrayList<>();
        if (maps != null && maps.size() > 0) {
            Map<String, ?> map = null;
            for (int i = 0, size = maps.size(); i < size; i++) {
                map = maps.get(i);
                T bean = mapToBean(map, clazz);
                list.add(bean);
            }
        }
        return list;
    }
}

【EsRequestGenUtil】
```java
import cn.hutool.core.util.ObjectUtil;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Component;

/**
 * @author JHL
 * @version 1.0
 * @date 2023/3/20 15:28
 * @since : JDK 11
 */
@Component
public class EsRequestGenUtil {


    private Integer MAX_LIMIT = 10000;

    /**
     * 通用es查询请求对象构建
     * <p>
     * 根据指定字段查询
     * 指定字段排序
     * 指定数据条数
     * 时间范围查询
     *
     * @param indexName 索引名(必须)
     */
    public SearchRequest getEsSearchRequestInstance(String indexName,
                                                    String deviceIdentityFieldName,
                                                    String deviceIdentityFieldValue,
                                                    String extraFieldName,
                                                    String extraFieldValue,
                                                    String sortFieldName,
                                                    String sortType,
                                                    Integer limit,
                                                    String rangeFieldName,
                                                    Long beginTimestamp,
                                                    Long endTimestamp) {
        // 验参
        if (!ObjectUtil.isAllNotEmpty(indexName)) {
            return null;
        }
        SearchRequest req = new SearchRequest();
        req.indices(indexName);

        //搜索源构建对象
        SearchSourceBuilder builder = new SearchSourceBuilder();
        // bool类型查询构造器
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();

        // 指定mac条件
        TermQueryBuilder termQueryBuilderPk = QueryBuilders.termQuery(deviceIdentityFieldName, deviceIdentityFieldValue);
        boolBuilder.must(termQueryBuilderPk);


        // 排序
        if (ObjectUtil.isAllNotEmpty(sortFieldName, sortType)) {
            SortOrder sortOrder = null;
            if ("asc".equalsIgnoreCase(sortType)) {
                sortOrder = SortOrder.ASC;
            } else if ("desc".equalsIgnoreCase(sortType)) {
                sortOrder = SortOrder.DESC;
            }
            builder.sort(sortFieldName, sortOrder);
        }

        // 指定分页
        builder.from(0);
        if (null != limit) {
            if (limit > MAX_LIMIT) {
                limit = MAX_LIMIT;
            }
        } else {
            limit = MAX_LIMIT;
        }
        builder.size(limit);

        // 扩展字段精确匹配
        if (ObjectUtil.isAllNotEmpty(extraFieldName, extraFieldValue)) {
            MatchQueryBuilder termQueryBuilder = QueryBuilders.matchQuery(extraFieldName, extraFieldValue);
            boolBuilder.must(termQueryBuilder);
        }

        // 时间范围查询
        if (ObjectUtil.isAllNotEmpty(beginTimestamp, endTimestamp)) {
            RangeQueryBuilder range = QueryBuilders.rangeQuery(rangeFieldName).gte(beginTimestamp).lte(endTimestamp);
            boolBuilder.must(range);
        }

        // 应用布尔查询器
        builder.query(boolBuilder);

        // 构建查询器
        req.source(builder);
        return req;
    }
}
posted @ 2022-06-07 16:27  黄河大道东  阅读(118)  评论(0编辑  收藏  举报