package com.zzsn.knowbase.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.zzsn.knowbase.entity.Knowledge;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkItemResponse;
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.WriteRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.core.MainResponse;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
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.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;

/**
 * Es操作相关工具栏
 *
 * @author kongliufeng
 * @create 2020-08-03 16:48
 */
@Slf4j
@Component
public class EsOpUtil {

    //    @Resource(name = "restHighLevelClient")
    @Autowired
    RestHighLevelClient client;

    public Boolean isClinet() {
        return false;
    }

    /**
     * 获取节点相关信息
     *
     * @return
     */
    public Map<String, Object> getEsInfo() {
        try {
            Map<String, Object> map = new HashMap<>();
            //获取Es相关集群信息
            MainResponse response = client.info(RequestOptions.DEFAULT);
            String clusterName = response.getClusterName();
            String clusterUuid = response.getClusterUuid();
            String nodeName = response.getNodeName();
            MainResponse.Version version = response.getVersion();
            String buildDate = version.getBuildDate();
            String buildFlavor = version.getBuildFlavor();
            String buildHash = version.getBuildHash();
            String buildType = version.getBuildType();
            String luceneVersion = version.getLuceneVersion();
            String minimumIndexCompatibilityVersion = version.getMinimumIndexCompatibilityVersion();
            String minimumWireCompatibilityVersion = version.getMinimumWireCompatibilityVersion();
            String number = version.getNumber();
            map.put("clusterName", clusterName);
            map.put("clusterUuid", clusterUuid);
            map.put("nodeName", nodeName);
            map.put("version", version);
            map.put("buildDate", buildDate);
            map.put("buildFlavor", buildFlavor);
            map.put("buildHash", buildHash);
            map.put("buildType", buildType);
            map.put("luceneVersion", luceneVersion);
            map.put("minimumIndexCompatibilityVersion", minimumIndexCompatibilityVersion);
            map.put("minimumWireCompatibilityVersion", minimumWireCompatibilityVersion);
            map.put("number", number);
            return map;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取低级客户端
     *
     * @return
     */
    public RestClient getLowLevelClient() {
        return client.getLowLevelClient();
    }

    /**
     * 创建索引
     *
     * @param index
     * @return
     */
    public boolean indexCreate(String index) {
        try {
            if (!indexExist(index)) {
                CreateIndexRequest request = new CreateIndexRequest(index);
                CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
                log.info(createIndexResponse.isAcknowledged() ? "创建索引[{}]成功" : "创建索引[{}]失败", index);
                return createIndexResponse.isAcknowledged();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 判断索引是否存在
     *
     * @param indices
     * @return
     */
    @SneakyThrows
    public boolean indexExist(String... indices) {
        GetIndexRequest request = new GetIndexRequest(indices);
        return client.indices().exists(request, RequestOptions.DEFAULT);
    }

    /**
     * 删除索引
     *
     * @param index
     * @return
     */
    @SneakyThrows
    public boolean deleteIndex(String index) {
        DeleteIndexRequest request = new DeleteIndexRequest(index);
        AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
        return delete.isAcknowledged();
    }

    /**
     * 判断doc是否存在
     *
     * @param index
     * @param id
     * @return
     */
    @SneakyThrows
    public boolean docExists(String index, String id) {
        GetRequest request = new GetRequest(index, id);
        //禁用提取_source
        request.fetchSourceContext(new FetchSourceContext(false));
        //禁用获取存储的字段
        request.storedFields("_none_");
        boolean exists = client.exists(request, RequestOptions.DEFAULT);
        return exists;
    }

    public void docGet(String index, String id) {
        try {
            GetRequest getRequest = new GetRequest(index, id);
            GetResponse documentFields = client.get(getRequest, RequestOptions.DEFAULT);
            Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();
            System.out.println(documentFields.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Boolean isNotExistUrl(String url, String index) {
        try {
            SearchRequest searchRequest = new SearchRequest(index);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            TermsQueryBuilder sourceAddress = QueryBuilders.termsQuery("sourceAddress", url);
            searchSourceBuilder.query(sourceAddress);
            //不返回文本内容
            searchSourceBuilder.fetchSource(false);
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            SearchHits hits = searchResponse.getHits();
            Long total = hits.getTotalHits().value;
            if (total == 0) {//不存在
                return true;
            } else if (total == 1) {//存在
                return false;
            } else if (total > 1) {//存在多条,异常
                log.warn("url为[{}]在es库中存在[{}]条数据", url, total);
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }

    /**
     * 批量插入数据
     *
     * @param index 索引库
     * @param list  List<ESBaseData> 批量保存的list,根据实际需求实体集成ESBaseData
     */
    public void docSavaBulk(String index, List<Knowledge> list) {
        BulkRequest request = new BulkRequest();
        request.timeout(TimeValue.timeValueMinutes(10));
        for (int i = 0; i < list.size(); i++) {
            Knowledge b = list.get(i);
            request.add(new IndexRequest(index).id(b.getId()).source(
                    JSON.toJSONString(list.get(i)), XContentType.JSON
            ));
        }
        try {
            BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);
            BulkItemResponse[] bulkItemResponses = bulk.getItems();
            int length = bulkItemResponses.length;
            for (int i = 0; i < length; ++i) {
                BulkItemResponse response = bulkItemResponses[i];
                if (response.isFailed()) {//查看所有请求失败结果
                    log.info("批量保存[{}]过程中,id为[{}]的保存失败,失败原因[{}]", response.getIndex(), response.getId(), response.getFailureMessage());
                } else {//请求成功的
                    log.info("批量保存[{}]过程中,id为[{}]的保存成功,状态[{}],version[{}]", response.getIndex(), response.getId(), response.status(), response.getVersion());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.warn("批量[{}]保存失败", index);
        }
    }

    /**
     * 批量插入数据(异步)
     *
     * @param index 索引库
     * @param list  List<ESBaseData> 批量保存的list,根据实际需求实体集成ESBaseData
     */
    public void docSavaBulkAsync(String index, List<Knowledge> list) {
        BulkRequest request = new BulkRequest();
        request.timeout(TimeValue.timeValueMinutes(10));
        for (int i = 0; i < list.size(); i++) {
            Knowledge b = list.get(i);
            request.add(new IndexRequest(index).id(b.getId()).source(
                    JSON.toJSONString(list.get(i)), XContentType.JSON
            ));
        }
        client.bulkAsync(request, RequestOptions.DEFAULT, new ActionListener<BulkResponse>() {
            @Override
            public void onResponse(BulkResponse bulkItemResponses) {
                BulkItemResponse[] bulkItems = bulkItemResponses.getItems();
                int length = bulkItems.length;
                for (int i = 0; i < length; ++i) {
                    BulkItemResponse response = bulkItems[i];
                    if (response.isFailed()) {//查看所有请求失败结果
                        log.info("批量保存[{}]过程中,id为[{}]的保存失败,失败原因[{}]", response.getIndex(), response.getId(), response.getFailureMessage());
                    } else {//请求成功的
                        log.info("批量保存[{}]过程中,id为[{}]的保存成功,状态[{}],version[{}]", response.getIndex(), response.getId(), response.status(), response.getVersion());
                    }
                }
            }

            @Override
            public void onFailure(Exception e) {
                log.warn("批量[{}]保存失败,失败原因[{}]", index, e.getMessage());
            }
        });
    }

    /**
     * 插入数据
     *
     * @param index
     * @param id
     * @param object
     * @return
     */
    public String docSavaByEntity(String index, String id, Object object) {
        return docSaveByJson(index, id, JSON.toJSONString(object, SerializerFeature.WriteMapNullValue));
    }


    public void docSavaByEntityAsync(String index, String id, Object object) {
        docSaveByJsonAsync(index, id, JSON.toJSONString(object, SerializerFeature.WriteMapNullValue));
    }

    /**
     * 保存json
     *
     * @param index
     * @param id
     * @param jsonStr
     * @return
     */
    public String docSaveByJson(String index, String id, String jsonStr) {
        try {
            IndexRequest request = new IndexRequest(index)
                    .id(id)
                    .source(jsonStr, XContentType.JSON);
            IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
            return indexResponse.getId();
        } catch (IOException e) {
            log.warn("同步保存doc失败, _index=[{}], _id=[{}]", index, id);
        }
        return index;
    }

    /**
     * 异步创建doc
     *
     * @param index
     * @param id
     * @param jsonStr
     * @return
     */
    public void docSaveByJsonAsync(String index, String id, String jsonStr) {
        IndexRequest request = new IndexRequest(index);
        request.id(id);
        request.source(jsonStr, XContentType.JSON);
        client.indexAsync(request, RequestOptions.DEFAULT, new ActionListener<IndexResponse>() {
            @Override
            public void onResponse(IndexResponse indexResponse) {
                log.info("异步保存doc, _index=[{}], _id=[{}]成功, _version=[{}], _result=[{}]", index, indexResponse.getId(), indexResponse.getVersion(), indexResponse.getResult());
            }

            @Override
            public void onFailure(Exception e) {
                e.printStackTrace();
                log.warn("异步保存失败，尝试同步方式保存doc, ex=[{}]", e.getMessage());
                try {
                    IndexResponse response = client.index(request, RequestOptions.DEFAULT);
                    DocWriteResponse.Result result = response.getResult();
                    if (!(result == DocWriteResponse.Result.UPDATED || result == DocWriteResponse.Result.CREATED)) {
                        log.warn("同步保存doc失败,_index=[{}], _id=[{}], _body=[{}]", index, id, jsonStr);
                    }
                } catch (IOException io) {
                    io.printStackTrace();
                }
            }
        });
    }

    public String docSaveByMap(String index, String id, Map<String, Object> map) {
        try {
            IndexRequest request = new IndexRequest(index).id(id)
                    .source(map);
            IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
            return indexResponse.getId();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return index;
    }

    /**
     * 插入数据
     *
     * @param index
     * @param id
     * @param object
     * @return
     */
    public String docSaveByJSIONObject(String index, String id, JSONObject object) {
        IndexRequest request = new IndexRequest(index);
        request.id(id);
        try {
            request.source(JSON.toJSONString(object), XContentType.JSON);
            IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
            return indexResponse.getId();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据id删除doc
     *
     * @param index
     * @param id
     * @return
     */
    public Boolean docDeleteById(String index, String id) {
        try {
            DeleteRequest deleteRequest = new DeleteRequest(index, id);
            DeleteResponse delete = client.delete(deleteRequest, RequestOptions.DEFAULT);
            if (delete.status() == RestStatus.OK) {
                log.info("DELETE /{}/_doc/{}/\r\n", index, id);
                return true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public void docDeleteByIdAsync(String index, String id) {
        DeleteRequest request = new DeleteRequest(index, id);
        try {
            client.deleteAsync(request, RequestOptions.DEFAULT, new ActionListener<DeleteResponse>() {
                @Override
                public void onResponse(DeleteResponse deleteResponse) {
                    log.info("删除doc成功, _index=[{}], _id=[{}]", index, deleteResponse.getId());
                }

                @Override
                public void onFailure(Exception e) {
                    e.printStackTrace();
                    log.warn("删除doc失败, _index=[{}], _id=[{}]", index, id);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据条件删除
     *
     * @param index
     * @param query
     * @return
     */
    public Long docDeleteByQuery(final String index, QueryBuilder query) {
        try {
            DeleteByQueryRequest request = new DeleteByQueryRequest(index);
            request.setQuery(query).setRefresh(true);
            BulkByScrollResponse bulkByScrollResponse = client.deleteByQuery(request, RequestOptions.DEFAULT);
            return bulkByScrollResponse.getDeleted();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public boolean docUpdateById(String index, String id, String jsonStr) {
        UpdateRequest request = new UpdateRequest(index, id);
        //刷新策略，默认
        request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        request.setRefreshPolicy("true");
        request.doc(jsonStr, XContentType.JSON);
        try {
            UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
            return response.status() == RestStatus.OK;
        } catch (IOException e) {
            e.printStackTrace();
            log.warn("更新doc失败, _index=[{}], _id=[{}],_jsonStr=[{}]", index, id, jsonStr);
        }
        return false;
    }


    /**
     * 根据index,id索引文件
     *
     * @param index
     * @param id
     * @return
     */
    public Map<String, Object> searchDoc(String index, String id) {
        try {
            GetRequest searchRequest = new GetRequest(index, id);
            GetResponse documentFields = client.get(searchRequest, RequestOptions.DEFAULT);
            Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();
            //sourceAsMap.put("score",documentFields.getSource());
            return sourceAsMap;
        } catch (IOException e) {
            log.warn("查询doc异常，index=[{}],id=[{}], ex=[{}]", index, id, e.getMessage());
        }
        return null;
    }

    /**
     * @Description 判断该专题下的内容是否重复导入
     * @author kongliufeng
     * @创建时间 2020/9/11 18:05
     * @Version 1.0
     */
    public Boolean isExistSubjectAndArticle(String index, String id, String subjectId) {
        try {
            SearchRequest searchRequest = new SearchRequest(index);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("subjectId", subjectId);
            boolQueryBuilder.must(matchQueryBuilder);
            MatchQueryBuilder matchQueryBuilder1 = QueryBuilders.matchQuery("id", id);
            boolQueryBuilder.must(matchQueryBuilder1);
            searchSourceBuilder.query(boolQueryBuilder);
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            SearchHits hits = searchResponse.getHits();
            Long total = hits.getTotalHits().value;
            if (total > 0) {
                log.info("isExistSubjectAndArticle[index:{}][id:{}][subject:{}]重复,库中已存在", index, id, subjectId);
                return true;
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.info("isExistSubjectAndArticle[index:{}][id:{}][subject:{}]发生异常,异常信息为[{}]", index, id, subjectId);
            return false;
        }
        return false;
    }

    /**
     * 按条件查询数据
     *
     * @param index
     * @param start
     * @param size
     * @param queryBuilder
     * @return
     */
    public Map<String, Object> searchByQuery(String index, int start, int size, QueryBuilder queryBuilder) {
        try {
            Map<String, Object> resultMap = new HashMap<>();
            SearchRequest searchRequest = new SearchRequest(index);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            if (queryBuilder != null) {
                searchSourceBuilder.query(queryBuilder);
            }
            if (start >= 0 && size >= 0) {
                searchSourceBuilder.from(start);
                searchSourceBuilder.size(size);
            }
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            SearchHits hits = searchResponse.getHits();
            Long total = hits.getTotalHits().value;
            resultMap.put("total", total);
            SearchHit[] searchHits = hits.getHits();
            List<Map<String, Object>> mapList = new ArrayList<>(searchHits.length);
            for (SearchHit hit : searchHits) {
                //存储的字段
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                //得分
                sourceAsMap.put("score", hit.getScore());
                mapList.add(sourceAsMap);
            }
            resultMap.put("data", mapList);
            return resultMap;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public boolean existBySourceAddress(String index, String sourceAddress) {
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //创建查询对象
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.termQuery("sourceAddress.keyword", sourceAddress));
        searchSourceBuilder.query(boolQuery);
        searchRequest.source(searchSourceBuilder);
        long count = 0;
        try {
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            count = searchResponse.getHits().getTotalHits().value;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return count == 0;
    }

    public boolean existByTitle(String index, String title) {
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //创建查询对象
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.termQuery("title.keyword", title));
        searchSourceBuilder.query(boolQuery);
        searchRequest.source(searchSourceBuilder);
        long count = 0;
        try {
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            count = searchResponse.getHits().getTotalHits().value;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return count == 0;
    }

    /**
     * 批量更新部分字段(异步)
     *
     * @param index  es索引名称
     * @param params 参数
     * @author lkg
     * @date 2023/7/26
     */
    public void updateFieldsBulk(String index, Map<String, Map<String, Object>> params) {
        try {
            BulkRequest bulkRequest = new BulkRequest();
            for (Map.Entry<String, Map<String, Object>> entry : params.entrySet()) {
                String id = entry.getKey();
                Map<String, Object> fieldsMap = entry.getValue();
                UpdateRequest updateRequest = new UpdateRequest();
                XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject();
                fieldsMap.forEach((key, value) -> {
                    try {
                        xContentBuilder.field(key, value);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
                xContentBuilder.endObject();
                updateRequest.index(index).id(id).doc(xContentBuilder);
                bulkRequest.add(updateRequest);
            }
            client.bulk(bulkRequest, RequestOptions.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 通用查询，
     */
    public <T> List<T> queryList(String index, QueryBuilder queryBuilder, Class<T> entry, int size) {
        List<T> list = new ArrayList<>();

        try {
            SearchRequest searchRequest = new SearchRequest(index);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.size(size);
            searchSourceBuilder.query(queryBuilder);
            searchRequest.source(searchSourceBuilder);

            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            // 处理搜索结果
            SearchHit[] hits = searchResponse.getHits().getHits();
            if (hits.length > 0) {
                Arrays.stream(hits).forEach(e -> {
                    T t = JSON.parseObject(e.getSourceAsString(), entry);
                    list.add(t);
                });
            }
            return list;
        } catch (IOException e) {
            log.info("查询异常{}", e.getMessage(), e);
            return list;
        }
    }

    /**
     * 通用分页查询
     */
    public <T> Page<T> queryPage(String index, QueryBuilder queryBuilder, Class<T> entry, Integer pageNo, Integer pageSize) {
        List<T> list = new ArrayList<>();
        Page<T> pageData = new Page<>(pageNo, pageSize);
        try {
            SearchRequest searchRequest = new SearchRequest(index);
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            //设置分页参数
            searchSourceBuilder.size(pageSize);
            searchSourceBuilder.from((pageNo - 1) * pageSize);
            //默认最大数量是10000，设置为true后，显示准确数量
            searchSourceBuilder.trackTotalHits(true);
            searchSourceBuilder.query(queryBuilder);
            searchRequest.source(searchSourceBuilder);
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            // 处理搜索结果
            SearchHit[] hits = searchResponse.getHits().getHits();
            if (hits.length > 0) {
                Arrays.stream(hits).forEach(e -> {
                    T t = JSON.parseObject(e.getSourceAsString(), entry);
                    list.add(t);
                });
            }
            pageData.setTotal(searchResponse.getHits().getTotalHits().value);
            pageData.setRecords(list);
            return pageData;
        } catch (IOException e) {
            log.info("查询异常{}", e.getMessage(), e);
            return pageData;
        }
    }

    /**
     * 通用分页查询
     */
    public <T> Page<T> queryPage(String index, SearchSourceBuilder searchSourceBuilder, Class<T> entry, Integer pageNo, Integer pageSize) throws IOException {
        List<T> list = new ArrayList<>();
        Page<T> pageData = new Page<>(pageNo, pageSize);
        SearchRequest searchRequest = new SearchRequest(index);
        searchSourceBuilder.size(pageSize);
        searchSourceBuilder.from((pageNo - 1) * pageSize);
        //默认最大数量是10000，设置为true后，显示准确数量
        searchSourceBuilder.trackTotalHits(true);
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        // 处理搜索结果
        SearchHit[] hits = searchResponse.getHits().getHits();
        if (hits.length > 0) {
            Arrays.stream(hits).forEach(e -> {
                T t = JSON.parseObject(e.getSourceAsString(), entry);
                list.add(t);
            });
        }
        pageData.setTotal(searchResponse.getHits().getTotalHits().value);
        pageData.setRecords(list);
        return pageData;

    }

}
