spring对接elasticsearch

本文提供了一系列教程链接,详细介绍了如何使用JavaRestHighLevelClient来操作Elasticsearch,包括创建和删除索引、增删改查文档、查询优化等内容,适用于Elasticsearch7.14版本。
摘要由CSDN通过智能技术生成

教程

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.14/java-rest-high.html

https://blog.csdn.net/Amnesiar/article/details/108855006?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167334291616800182159515%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=167334291616800182159515&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-8-108855006-null-null.142^v70^wechat_v2,201^v4^add_ask&utm_term=%E8%85%BE%E8%AE%AF%E4%BA%91es%E5%BC%80%E5%8F%91%E5%85%A5%E9%97%A8&spm=1018.2226.3001.4187

https://blog.csdn.net/XJ0927/article/details/111999742

https://blog.csdn.net/gouzhengju1454/article/details/117707976?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167340112816800217043555%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167340112816800217043555&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-117707976-null-null.142^v70^wechat_v2,201^v4^add_ask&utm_term=%E7%8B%82%E7%A5%9Eelasticsearch&spm=1018.2226.3001.4187

https://blog.csdn.net/Koikoi12/article/details/120182936

https://blog.csdn.net/weixin_46115287/article/details/120974337?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-120974337-blog-110364612.pc_relevant_multi_platform_whitelistv3&spm=1001.2101.3001.4242.2&utm_relevant_index=4

https://blog.csdn.net/guaotianxia/article/details/124249348?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167374774516800182796599%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167374774516800182796599&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-124249348-null-null.142^v71^one_line,201^v4^add_ask&utm_term=es%E6%9F%A5%E8%AF%A2&spm=1018.2226.3001.4187

添加依赖
    <properties>
        <!-- 统一版本 -->
        <elasticsearch.version>7.14.2</elasticsearch.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
    </dependencies>
配置接入信息
spring:
  elasticsearch:
  uris: http://172.0.0.1:9200
  username: elastic
  password: xxxxxxxxxx
工具类

注意不同客户端版本的接口有所不同;当前对接的是7.14版本的Java High Level REST Client.


import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.model.es.ESGamerTitle;
import com.ruoyi.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
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.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.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Component;

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


/**
 * ES工具类
 * <p>
 * es的index == mysql的database-table
 * es的document == mysql的row
 * es的field == mysql的column
 * <p>
 * GET http:// == select * from table...
 * PUT http:// == update table set...
 *
 * 修改数据后需要设置刷新策略为立即刷新,否则数据刷新有延迟
 * 刷新索引的策略:NONE(“false”)、IMMEDIATE(“true”)、WAIT_UNTIL(“wait_for”)
 *
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class ESUtil {

    private final RestHighLevelClient client;

    /**
     * 设置超时时间为1s
     */
    public final static TimeValue timeValue = TimeValue.timeValueSeconds(1);
    /**
     * 设置请求方式为默认
     */
    public final static RequestOptions requestOptions = RequestOptions.DEFAULT;

    /**
     * index列表
     */
    public final static String GAMER_TITLE_INDEX = "gamer-title-index";
    public final static String ROOM_TITLE_INDEX = "room-title-index";
    public final static String GAMER_BAG_INDEX = "gamer-bag-index";

    public final static String TROUBLE_RANK_INDEX = "trouble-rank-index";

//    public final static String GIFT_RECORD_INDEX = "gift-record-index";
//    public final static String COMMENTS_INDEX = "comments-index";


    /**
     * 创建索引
     *
     * @param index 索引名
     * @return 是否成功
     */
    @SneakyThrows
    public boolean createIndex(String index) {
        CreateIndexRequest request = new CreateIndexRequest(index);
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        log.info("ES创建索引={}, 返回={}", index, JSONUtil.toJsonStr(response));
        return response.isAcknowledged();
    }

    /**
     * 查询索引是否存在
     *
     * @param index 索引名
     * @return 是否成功
     */
    @SneakyThrows
    public boolean existIndex(String index) {
        GetIndexRequest request = new GetIndexRequest(index);
        boolean exists = client.indices().exists(request, requestOptions);
        log.info("ES查询索引是否存在={}, 返回={}", index, exists);
        return exists;
    }

    /**
     * 删除索引
     *
     * @param index 索引名
     * @return 是否成功
     */
    @SneakyThrows
    public boolean delIndex(String index) {
        DeleteIndexRequest request = new DeleteIndexRequest(index);
        AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
        log.info("ES删除索引={}, 返回={}", index, JSONUtil.toJsonStr(response));
        return response.isAcknowledged();
    }

    /**
     * 增加文档
     *
     * @param index 索引名
     * @param id    文档id 为空则自动创建id
     * @param json  文档jsonstr
     * @return 是否成功
     */
    @SneakyThrows
    public boolean addDocument(String index, String id, String json) {
        IndexRequest request = new IndexRequest(index);
        if (StrUtil.isNotBlank(id)) {
            request.id(id);
        }
        request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        request.source(json, XContentType.JSON);
        request.timeout(timeValue);
        IndexResponse response = client.index(request, requestOptions);
        log.info("ES增加文档={}, id={}, json={}, 返回={}", index, id, json, JSONUtil.toJsonStr(response));
        return response.status().name().equals("CREATED");
    }

    /**
     * 更新文档
     *
     * @param index 索引名
     * @param id    文档id
     * @param json  文档jsonstr
     * @return 是否成功
     */
    @SneakyThrows
    public boolean updateDocument(String index, String id, String json) {
        IndexRequest request = new IndexRequest(index).id(id).source(json,XContentType.JSON);
        request.timeout(timeValue);
        request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        IndexResponse response = client.index(request, requestOptions);
        log.info("ES更新文档={}, id={}, 返回={}", index, id, JSONUtil.toJsonStr(response));
        return response.status().name().equals("OK");
    }

    /**
     * 删除文档
     *
     * @param index 索引名
     * @param id    文档id
     * @return 是否成功
     */
    @SneakyThrows
    public boolean delDocument(String index, String id) {
        DeleteRequest request = new DeleteRequest(index, id);
        request.timeout(timeValue);
        request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        DeleteResponse response = client.delete(request, requestOptions);
        log.info("ES删除文档={}, id={}, 返回={}", index, id, JSONUtil.toJsonStr(response));
        return response.status().name().equals("OK");
    }

    /**
     * 查询文档
     *
     * @param index 索引名
     * @param id    文档id
     * @return json 文档jsonstr
     */
    @SneakyThrows
    public GetResponse getDocument(String index, String id) {
        GetRequest request = new GetRequest(index, id);
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        log.info("ES查询文档={}, id={}, 返回={}", index, id, JSONUtil.toJsonStr(response));
        return response;
    }

    /**
     * 查询文档列表
     *
     * @param index 索引名
     * @param map   匹配条件 不能为空 全等
     * @return json 文档jsonstr
     */
    @SneakyThrows
    public SearchHit[] getDocuments(String index, Map<String, Object> map) {
        SearchRequest request = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> next = iterator.next();
            boolQuery.filter(QueryBuilders.termQuery(next.getKey(), next.getValue()));
            builder.query(boolQuery);
        }
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        log.info("ES查询文档列表={}, map={}, 返回={}", index, JSONUtil.toJsonStr(map), JSONUtil.toJsonStr(response));
        return response.getHits().getHits();
    }

    /**
     * 排序设置大小 查询文档列表
     *
     * @param index 索引名
     * @param map   匹配条件 不能为空 全等
     * @return json 文档jsonstr
     */
    @SneakyThrows
    public SearchHit[] getDocuments(String index, Map<String, Object> map, String sortField, Integer size) {
        SearchRequest request = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> next = iterator.next();
            boolQuery.filter(QueryBuilders.termQuery(next.getKey(), next.getValue()));
            builder.query(boolQuery);
        }
        builder.sort(sortField, SortOrder.DESC);
        builder.size(size);
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        log.info("ES查询文档列表排序={}, map={}, 返回={}", index, JSONUtil.toJsonStr(map), JSONUtil.toJsonStr(response));
        return response.getHits().getHits();
    }

    /**
     * 查询文档
     *
     * @param index 索引名
     * @param map   匹配条件 不能为空 全等
     * @return json 文档jsonstr
     */
    @SneakyThrows
    public SearchHit findOne(String index, Map<String, Object> map) {
        SearchRequest request = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> next = iterator.next();
            boolQuery.filter(QueryBuilders.termQuery(next.getKey(), next.getValue()));
            builder.query(boolQuery);
        }
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        log.info("ES查询文档列表={}, map={}, 返回={}", index, JSONUtil.toJsonStr(map), JSONUtil.toJsonStr(response));
        if (response.getHits().getHits() == null || response.getHits().getHits().length == 0) {
            return null;
        } else {
            return response.getHits().getHits()[0];
        }
    }

    /**
     * 更新玩家佩戴的称号 有问题
     *
     * @param index
     * @param map
     * @return
     */
    @SneakyThrows
    public void updateGamerWearTitle(String index, Map<String, Object> map) {
        SearchHit[] hits = getDocuments(index, map);
        if (hits == null || hits.length == 0){
            return;
        }
        BulkRequest request = new BulkRequest();

        for (int i = 0; i < hits.length; i++) {
            ESGamerTitle title = JSONUtil.toBean(hits[i].getSourceAsString(), ESGamerTitle.class);
            title.setWear(false);
            request.add(new UpdateRequest().id(hits[i].getId()).doc(JSONUtil.toJsonStr(title)));
        }

        BulkResponse response = client.bulk(request, requestOptions);
        log.info("ES按条件更新文档={}, map={}, 返回={}", index, JSONUtil.toJsonStr(map), JSONUtil.toJsonStr(response));
    }

    /**
     * 按条件删除文档
     *
     * @param index
     * @param map
     * @return
     */
    @SneakyThrows
    public void delByMap(String index, Map<String, Object> map) {
        DeleteByQueryRequest request = new DeleteByQueryRequest(index);
        Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> next = iterator.next();
            request.setQuery(QueryBuilders.termQuery(next.getKey(), next.getValue()));
        }
        request.setRefresh(true);
        BulkByScrollResponse response = client.deleteByQuery(request, requestOptions);
        log.info("ES按条件删除文档={}, map={}, 返回={}", index, JSONUtil.toJsonStr(map), JSONUtil.toJsonStr(response));
    }


    public void insertOrUpdateOne(String index, String id, String data) {
        IndexRequest request = new IndexRequest(index);
        request.id(id);
        request.source(data, XContentType.JSON);
        try {
            client.index(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("error save info", e);
        }
    }

    public void updateOne(String index, String id, Map<String, Object> map) {
        UpdateRequest updateRequest = new UpdateRequest(index, id);
        updateRequest.doc(map);
        try {
            UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
            log.info("updateOne result:{}", JSON.toJSONString(updateResponse));
        } catch (Exception e) {
            log.warn("updateOne to ES Exception : ", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 批量插入文档
     *
     * @param index     ES索引
     * @param documents 待提交的批量文档
     * @param uuidKey   文档中ID字段对应的key值
     */
    public BulkResponse insertDocumentsAsBatch(String index, List<Map<String, Object>> documents, String uuidKey) {
        BulkResponse response = null;
        if (StringUtils.isBlank(index) || CollectionUtils.isEmpty(documents)) {
            log.warn("Es index is blank or documents is empty.");
            return response;
        }

        try {
            BulkRequest bulkRequest = new BulkRequest();
            for (Map<String, Object> document : documents) {
                if (MapUtils.isEmpty(document) || !document.containsKey(uuidKey)) {
                    continue;
                }
                bulkRequest.add(new IndexRequest(index).opType("create").id(document.get(uuidKey).toString()).source(document));
            }
            response = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("Insert documents to es as batch failed!", e);
        }
        return response;
    }

    /**
     * 批量更新文档
     *
     * @param index     ES索引
     * @param documents 待提交的批量文档
     * @param uuidKey   文档中ID字段对应的key值
     */
    public BulkResponse updateDocumentsAsBatch(String index, List<Map<String, Object>> documents, String uuidKey) {
        BulkResponse response = null;
        if (StringUtils.isBlank(index) || CollectionUtils.isEmpty(documents)) {
            log.warn("Es index is blank or documents is empty.");
            return response;
        }

        try {
            BulkRequest bulkRequest = new BulkRequest();
            for (Map<String, Object> document : documents) {
                if (MapUtils.isEmpty(document) || !document.containsKey(uuidKey)) {
                    continue;
                }
                bulkRequest.add(new UpdateRequest(index, document.get(uuidKey).toString()).doc(document));
            }
            response = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("Update documents to es as batch failed!", e);
        }
        return response;
    }

    /**
     * 批量删除多个文档数组
     *
     * @param index     ES索引
     * @param documents 待提交的批量文档
     * @param uuidKey   文档中ID字段对应的key值
     */
    public BulkResponse deleteDocumentsAsBatch(String index, List<Map<String, Object>> documents, String uuidKey) {
        BulkResponse response = null;
        if (StringUtils.isBlank(index) || CollectionUtils.isEmpty(documents)) {
            log.warn("Es index is blank or documents is empty.");
            return response;
        }

        try {
            BulkRequest bulkRequest = new BulkRequest();
            for (Map<String, Object> document : documents) {
                if (MapUtils.isEmpty(document) || !document.containsKey(uuidKey)) {
                    continue;
                }
                bulkRequest.add(new DeleteRequest(index, document.get(uuidKey).toString()));
            }
            response = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("Update documents to es as batch failed!", e);
        }
        return response;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值