Java封装原生ES

news2024/11/18 15:41:12

文章目录

  • 🌞 Sun Frame:SpringBoot 的轻量级开发框架(个人开源项目推荐)
    • 🌟 亮点功能
    • 📦 spring cloud模块概览
      • 常用工具
    • 🔗 更多信息
    • 1.spring-data-es操作ES
        • 1.引入依赖
        • 2.application.yml配置uris
        • 3.SubjectInfoEs.java 创建ES实体类(指定映射和索引)
        • 4.SubjectEsRepository.java 依赖注入一个接口(对应于实体类)
        • 5.SubjectEsService.java
        • 6.SubjectEsServiceImpl.java
        • 7.TestFeignController.java 测试
        • 8.测试
          • 1.请求,注意要加上loginId因为没走网关,不加就会空指针
        • 9.添加文档
          • 1.SubjectEsService.java
          • 2.SubjectEsServiceImpl.java
          • 3.TestFeignController.java
          • 4.测试
        • 10.查找文档
          • 1.SubjectEsService.java
          • 2.SubjectEsServiceImpl.java
          • 3.TestFeignController.java
          • 4.测试
    • 2.自定义封装ES
        • 1.环境准备
          • 1.删除上面引入的ES依赖
          • 2.删除application.yml中的ES配置
          • 3.删除原来的文件
          • 4.sun-club-infra 引入原生的ES依赖
        • 2.自定义封装集群es连接统一管理
          • 1.目录结构
          • 2.EsClusterConfig.java ES的集群配置的实体类
          • 3.EsConfigProperties.java 读取配置文件的es集群配置
          • 3.编写配置文件
          • 4.EsRestClient.java Es工具类,将每个集群节点对应的某个客户端放到Map
          • 5.启动测试,可以读取到配置信息
        • 3.封装ES常用操作(全)
          • 1.EsClusterConfig.java ES的集群配置的实体类
          • 2.EsConfigProperties.java 读取配置文件的集群配置
          • 3.EsIndexInfo.java Es的索引信息
          • 4.EsSourceData.java Es源数据
          • 5.EsSearchRequest.java Es查询的请求实体类
          • 6.EsRestClient.java
          • 7.配置文件和依赖同上

🌞 Sun Frame:SpringBoot 的轻量级开发框架(个人开源项目推荐)

Sun Frame Banner

轻松高效的现代化开发体验

Sun Frame 是我个人开源的一款基于 SpringBoot 的轻量级框架,专为中小型企业设计。它提供了一种快速、简单且易于扩展的开发方式。

我们的开发文档记录了整个项目从0到1的任何细节,实属不易,请给我们一个Star!🌟
您的支持是我们持续改进的动力。

🌟 亮点功能

  • 组件化开发:灵活选择,简化流程。
  • 高性能:通过异步日志和 Redis 缓存提升性能。
  • 易扩展:支持多种数据库和消息队列。

📦 spring cloud模块概览

  • Nacos 服务:高效的服务注册与发现。
  • Feign 远程调用:简化服务间通信。
  • 强大网关:路由与限流。

常用工具

  • 日志管理:异步处理与链路追踪。
  • Redis 集成:支持分布式锁与缓存。
  • Swagger 文档:便捷的 API 入口。
  • 测试支持:SpringBoot-Test 集成。
  • EasyCode:自定义EasyCode模板引擎,一键生成CRUD。

🔗 更多信息

  • 开源地址:Gitee Sun Frame
  • 详细文档:语雀文档
    在这里插入图片描述

1.spring-data-es操作ES

1.引入依赖
<!-- ES -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    <version>2.4.2</version>
</dependency>
2.application.yml配置uris
3.SubjectInfoEs.java 创建ES实体类(指定映射和索引)
package com.sunxiansheng.subject.infra.basic.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.util.Date;

/**
 * Description: 题目ES,相当于db中的表结构
 * @Author sun
 * @Create 2024/6/17 16:01
 * @Version 1.0
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "subject_index", createIndex = false) // 指定索引名,这里的createIndex=true,默认自动创建索引
public class SubjectInfoEs {

    // 使用es必须的
    @Field(type = FieldType.Long)
    @Id
    private Long id;

    @Field(type = FieldType.Text, analyzer = "ik_smart")
    private String subjectName;

    @Field(type = FieldType.Text, analyzer = "ik_smart")
    private String subjectAnswer;

    @Field(type = FieldType.Text, analyzer = "ik_smart")
    private String createUser;

    @Field(type = FieldType.Date, index = false)
    private Date createTime;
}
4.SubjectEsRepository.java 依赖注入一个接口(对应于实体类)
package com.sunxiansheng.subject.infra.basic.esRepo;

import com.sunxiansheng.subject.infra.basic.entity.SubjectInfoEs;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Component;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/17 16:09
 * @Version 1.0
 */
@Component
public interface SubjectEsRepository extends ElasticsearchRepository<SubjectInfoEs, Long> {

}
5.SubjectEsService.java
package com.sunxiansheng.subject.infra.basic.service;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/17 16:11
 * @Version 1.0
 */
public interface SubjectEsService {

    void createIndex();

    void getDocs();

    void find();

    void search();
}
6.SubjectEsServiceImpl.java
package com.sunxiansheng.subject.infra.basic.service.impl;

import com.sunxiansheng.subject.infra.basic.entity.SubjectInfoEs;
import com.sunxiansheng.subject.infra.basic.service.SubjectEsService;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/17 16:12
 * @Version 1.0
 */
@Service
public class SubjectEsServiceImpl implements SubjectEsService {

    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    /**
     * 创建索引
     */
    @Override
    public void createIndex() {
        // 得到ES实体类中的索引信息然后创建
        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(SubjectInfoEs.class);
        // 创建索引
        indexOperations.create();
        // 绑定映射
        Document mapping = indexOperations.createMapping(SubjectInfoEs.class);
        indexOperations.putMapping(mapping);
    }

    /**
     *
     */
    @Override
    public void getDocs() {

    }

    @Override
    public void find() {

    }

    @Override
    public void search() {

    }
}
7.TestFeignController.java 测试

image-20240617163237070

8.测试
1.请求,注意要加上loginId因为没走网关,不加就会空指针

image-20240617163558768

9.添加文档
1.SubjectEsService.java
void addDocs();
2.SubjectEsServiceImpl.java

image-20240617164738844

/**
 * 添加文档,也就相当于添加一条数据
 */
@Override
public void addDocs() {
    List<SubjectInfoEs> list = new LinkedList<>();
    // 添加两条数据
    list.add(new SubjectInfoEs(1L, "Java", "Java", "sun", null));
    list.add(new SubjectInfoEs(2L, "Spring", "Spring", "sun", null));
    // 批量添加
    subjectEsRepository.saveAll(list);
}
3.TestFeignController.java
@RequestMapping("/addDocs")
public void createaddDocsIndex() {
    subjectEsService.addDocs();
}
4.测试

image-20240617164759151

image-20240617164823117

10.查找文档
1.SubjectEsService.java
void find();
2.SubjectEsServiceImpl.java
/**
 * 查找列对应的元素
 */
@Override
public void find() {
    NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
            .withQuery(QueryBuilders.matchQuery("subjectName", "Java"))
            .build();
    SearchHits<SubjectInfoEs> search = elasticsearchRestTemplate.search(nativeSearchQuery, SubjectInfoEs.class);
    List<SearchHit<SubjectInfoEs>> searchHits = search.getSearchHits();
    log.info("searchHits:{}", searchHits);

}
3.TestFeignController.java
@RequestMapping("/find")
public void find() {
    subjectEsService.find();
}
4.测试

image-20240617165534922

image-20240617165627333

2.自定义封装ES

1.环境准备
1.删除上面引入的ES依赖
2.删除application.yml中的ES配置
3.删除原来的文件
4.sun-club-infra 引入原生的ES依赖
<!-- 封装自定义ES -->
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>7.5.2</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>7.5.2</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.5.2</version>
</dependency>
<!-- 集合工具类,配合封装自定义ES -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.4</version>
</dependency>
2.自定义封装集群es连接统一管理
1.目录结构

image-20240618174602620

2.EsClusterConfig.java ES的集群配置的实体类
package com.sunxiansheng.subject.infra.basic.es;

import lombok.Data;

import java.io.Serializable;

/**
 * Description: ES的集群配置的实体类
 * @Author sun
 * @Create 2024/6/17 17:08
 * @Version 1.0
 */
@Data
public class EsClusterConfig implements Serializable {

    /*
    集群名称
     */
    private String name;

    /*
    集群节点
     */
    private String nodes;
}
3.EsConfigProperties.java 读取配置文件的es集群配置
package com.sunxiansheng.subject.infra.basic.es;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * Description: 读取配置文件的集群配置
 * @Author sun
 * @Create 2024/6/17 17:10
 * @Version 1.0
 */
@Component
@ConfigurationProperties(prefix = "es.cluster") // 这个就相当于将esConfigs对应于配置文件的es.cluster.esConfigs
public class EsConfigProperties {

    private List<EsClusterConfig> esConfigs = new ArrayList<>();

    public List<EsClusterConfig> getEsConfigs() {
        return esConfigs;
    }

    public void setEsConfigs(List<EsClusterConfig> esConfigs) {
        this.esConfigs = esConfigs;
    }
}
3.编写配置文件
es:
  cluster:
    es-configs[0]:
      name: 98bd89b5ccaf
      nodes: ip:9200
4.EsRestClient.java Es工具类,将每个集群节点对应的某个客户端放到Map
package com.sunxiansheng.subject.infra.basic.es;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.http.HttpHost;
import org.apache.http.client.methods.HttpPost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Description: Es工具类
 * @Author sun
 * @Create 2024/6/17 17:43
 * @Version 1.0
 */
@Component
@Slf4j
public class EsRestClient {

    /*
    表示某个集群节点对应的某个客户端的map
    RestHighLevelClient:是由集群的ip端口数组生成的
     */
    public static Map<String, RestHighLevelClient> clientMap = new HashMap<>();

    /*
    获取配置文件中填写的es.cluster.es-configs的集群信息
     */
    @Resource
    private EsConfigProperties esConfigProperties;

    /**
     * @PostConstruct:注解用于标记一个方法,该方法会在依赖注入完成后自动调用
     * 这里将从配置文件中读取的集群信息封装到map中
     */
    @PostConstruct
    public void initialize() {
        // 获取集群节点的信息
        List<EsClusterConfig> esConfigs = esConfigProperties.getEsConfigs();
        esConfigs.forEach(esClusterConfig -> {
            String name = esClusterConfig.getName();
            String nodes = esClusterConfig.getNodes();
            log.info("initialize.esClusterConfig.name:{},nodes:{}", name, nodes);
            // 将每个集群的ip端口数组转换为RestHighLevelClient
            RestHighLevelClient restHighLevelClient = initRestClient(esClusterConfig);
            if (restHighLevelClient != null) {
                // 如果不为空就放到clientMap中
                clientMap.put(name, restHighLevelClient);
            } else {
                // 如果为空,打印日志
                log.error("initialize.esClusterConfig.name:{},nodes:{} is null", name, nodes);
            }
        });
    }

    /**
     * 通过一个集群节点来初始化该集群节点对应的客户端
     * @param esClusterConfig
     * @return
     */
    private RestHighLevelClient initRestClient(EsClusterConfig esClusterConfig) {
        // 得到该集群节点的IP端口数组
        String[] ipPortArr = esClusterConfig.getNodes().split(",");
        // 初始化一个HttpHost的列表
        List<HttpHost> httpHostList = new ArrayList<>(ipPortArr.length);
        // 对每一个ip端口进行处理
        for (String ipPort : ipPortArr) {
            // 分割ip端口
            String[] ipPortInfo = ipPort.split(":");
            // 校验
            if (ipPortInfo.length == 2) {
                // 创建一个HttpPost的对象,存放ip和端口
                HttpHost httpHost = new HttpHost(ipPortInfo[0], NumberUtils.toInt(ipPortInfo[1]));
                // 放到list中
                httpHostList.add(httpHost);
            }
        }
        // 创建一个HttpHost的数组,存放HttpHost
        HttpHost[] httpHosts = new HttpHost[httpHostList.size()];
        // httpHostList的数据放到这个数组里
        httpHostList.toArray(httpHosts);
        // 得到RestClient
        RestClientBuilder builder = RestClient.builder(httpHosts);
        // 升级一下
        RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);

        return restHighLevelClient;
    }


}
5.启动测试,可以读取到配置信息
3.封装ES常用操作(全)
1.EsClusterConfig.java ES的集群配置的实体类
package com.sunxiansheng.subject.infra.basic.es;

import lombok.Data;

import java.io.Serializable;

/**
 * Description: ES的集群配置的实体类
 * @Author sun
 * @Create 2024/6/17 17:08
 * @Version 1.0
 */
@Data
public class EsClusterConfig implements Serializable {

    /*
    集群名称
     */
    private String name;

    /*
    集群节点
     */
    private String nodes;
}
2.EsConfigProperties.java 读取配置文件的集群配置
package com.sunxiansheng.subject.infra.basic.es;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * Description: 读取配置文件的集群配置
 * @Author sun
 * @Create 2024/6/17 17:10
 * @Version 1.0
 */
@Component
@ConfigurationProperties(prefix = "es.cluster") // 这个就相当于将esConfigs对应于配置文件的es.cluster.esConfigs
public class EsConfigProperties {

    private List<EsClusterConfig> esConfigs = new ArrayList<>();

    public List<EsClusterConfig> getEsConfigs() {
        return esConfigs;
    }

    public void setEsConfigs(List<EsClusterConfig> esConfigs) {
        this.esConfigs = esConfigs;
    }
}
3.EsIndexInfo.java Es的索引信息
package com.sunxiansheng.subject.infra.basic.es;

import lombok.Data;

import java.io.Serializable;

/**
 * Description: Es的索引信息
 * @Author sun
 * @Create 2024/6/17 17:17
 * @Version 1.0
 */
@Data
public class EsIndexInfo implements Serializable {

    /*
    集群名称
     */
    private String clusterName;

    /*
    索引名称
     */
    private String indexName;

}
4.EsSourceData.java Es源数据
package com.sunxiansheng.subject.infra.basic.es;

import lombok.Data;

import java.io.Serializable;
import java.util.Map;

/**
 * Description: Es源数据
 * @Author sun
 * @Create 2024/6/17 17:41
 * @Version 1.0
 */
@Data
public class EsSourceData implements Serializable {

    private String docId;

    private Map<String, Object> data;

}
5.EsSearchRequest.java Es查询的请求实体类
package com.sunxiansheng.subject.infra.basic.es;

import lombok.Data;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;

/**
 * Description: Es查询的请求实体类
 * @Author sun
 * @Create 2024/6/17 17:20
 * @Version 1.0
 */
@Data
public class EsSearchRequest {

    /**
     * 查询条件
     */
    private BoolQueryBuilder bq;

    /**
     * 查询字段
     */
    private String[] fields;

    /**
     * 页数
     */
    private int from;

    /**
     * 条数
     */
    private int size;

    /**
     * 需要快照
     */
    private Boolean needScroll;

    /**
     * 快照缓存时间
     */
    private Long minutes;

    /**
     * 排序字段
     */
    private String sortName;

    /**
     * 排序类型
     */
    private SortOrder sortOrder;

    /**
     * 高亮builder
     */
    private HighlightBuilder highlightBuilder;

}
6.EsRestClient.java
package com.sunxiansheng.subject.infra.basic.es;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.http.HttpHost;
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.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.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.Scroll;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.ScoreSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;

/**
 * Description: Es工具类
 * @Author sun
 * @Create 2024/6/17 17:43
 * @Version 1.0
 */
@Component
@Slf4j
public class EsRestClient {

    /*
    表示某个集群节点对应的某个客户端的map
    RestHighLevelClient:是由集群的ip端口数组生成的
     */
    public static Map<String, RestHighLevelClient> clientMap = new HashMap<>();

    /*
    获取配置文件中填写的es.cluster.es-configs的集群信息
     */
    @Resource
    private EsConfigProperties esConfigProperties;

    /*

     */
    private static final RequestOptions COMMON_OPTIONS;

    /**
     * 为COMMON_OPTIONS进行静态初始化,在类加载的时候会执行
     */
    static {
        RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
        COMMON_OPTIONS = builder.build();
    }

    /**
     * @PostConstruct:注解用于标记一个方法,该方法会在依赖注入完成后自动调用
     * 这里将从配置文件中读取的集群信息封装到map中
     */
    @PostConstruct
    public void initialize() {
        // 获取集群节点的信息
        List<EsClusterConfig> esConfigs = esConfigProperties.getEsConfigs();
        esConfigs.forEach(esClusterConfig -> {
            String name = esClusterConfig.getName();
            String nodes = esClusterConfig.getNodes();
            log.info("initialize.esClusterConfig.name:{},nodes:{}", name, nodes);
            // 将每个集群的ip端口数组转换为RestHighLevelClient
            RestHighLevelClient restHighLevelClient = initRestClient(esClusterConfig);
            if (restHighLevelClient != null) {
                // 如果不为空就放到clientMap中
                clientMap.put(name, restHighLevelClient);
            } else {
                // 如果为空,打印日志
                log.error("initialize.esClusterConfig.name:{},nodes:{} is null", name, nodes);
            }
        });
    }

    /**
     * 通过一个集群节点来初始化该集群节点对应的客户端
     * @param esClusterConfig
     * @return
     */
    private RestHighLevelClient initRestClient(EsClusterConfig esClusterConfig) {
        // 得到该集群节点的IP端口数组
        String[] ipPortArr = esClusterConfig.getNodes().split(",");
        // 初始化一个HttpHost的列表
        List<HttpHost> httpHostList = new ArrayList<>(ipPortArr.length);
        // 对每一个ip端口进行处理
        for (String ipPort : ipPortArr) {
            // 分割ip端口
            String[] ipPortInfo = ipPort.split(":");
            // 校验
            if (ipPortInfo.length == 2) {
                // 创建一个HttpPost的对象,存放ip和端口
                HttpHost httpHost = new HttpHost(ipPortInfo[0], NumberUtils.toInt(ipPortInfo[1]));
                // 放到list中
                httpHostList.add(httpHost);
            }
        }
        // 创建一个HttpHost的数组,存放HttpHost
        HttpHost[] httpHosts = new HttpHost[httpHostList.size()];
        // httpHostList的数据放到这个数组里
        httpHostList.toArray(httpHosts);
        // 得到RestClient
        RestClientBuilder builder = RestClient.builder(httpHosts);
        // 升级一下
        RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);

        return restHighLevelClient;
    }

    /**
     * 获取集群名对应的RestHighLevelClient
     * @param clusterName
     * @return
     */
    private static RestHighLevelClient getClient(String clusterName) {
        return clientMap.get(clusterName);
    }

    /**
     * 新增文档(新增一条记录)
     * @param esIndexInfo 包含集群名和索引名
     * @param esSourceData 文档id和map类型的data
     * @return
     */
    public static boolean insertDoc(EsIndexInfo esIndexInfo, EsSourceData esSourceData) {
        try {
            // ==========构建表的一条数据==========
            // 获取es的索引名(表名)对应的请求
            IndexRequest indexRequest = new IndexRequest(esIndexInfo.getIndexName());
            // 设置源数据
            indexRequest.source(esSourceData.getData());
            // 设置记录的id
            indexRequest.id(esSourceData.getDocId());
            // ==========构建表的一条数据==========

            // 根据集群名获取client
            getClient(esIndexInfo.getClusterName()).index(indexRequest, COMMON_OPTIONS);

            // 如果没报错就返回true
            return true;
        } catch (Exception e) {
            // 打日志
            log.error("insertDoc.error:{}", e.getMessage(), e);
        }
        // 如果报错就返回false
        return false;
    }

    /**
     * 更新文档(更新记录)
     * @param esIndexInfo
     * @param esSourceData
     * @return
     */
    public static boolean updateDoc(EsIndexInfo esIndexInfo, EsSourceData esSourceData) {
        try {
            // 构建更新请求
            UpdateRequest updateRequest = new UpdateRequest();
            // 设置索引
            updateRequest.index(esIndexInfo.getIndexName());
            // 设置文档
            updateRequest.id(esSourceData.getDocId());
            // 设置源数据
            updateRequest.doc(esSourceData.getData());

            // 根据集群名获取client,执行更新操作
            getClient(esIndexInfo.getClusterName()).update(updateRequest, COMMON_OPTIONS);

            // 如果没报错就返回true
            return true;
        } catch (Exception e) {
            // 打日志
            log.error("updateDoc.error:{}", e.getMessage(), e);
        }
        // 如果报错就返回false
        return false;
    }

    /**
     * 批量更新文档(更新记录)
     * @param esIndexInfo
     * @param esSourceDataList
     * @return
     */
    public static boolean batchUpdateDoc(EsIndexInfo esIndexInfo, List<EsSourceData> esSourceDataList) {
        try {
            // 标志位
            boolean flag = false;
            // 创建一个多请求对象
            BulkRequest bulkRequest = new BulkRequest();
            // 遍历源数据的列表
            for (EsSourceData esSourceData : esSourceDataList) {
                // 获取文档id
                String docId = esSourceData.getDocId();
                // 构建一个更新请求放到BulkRequest中
                if (StringUtils.isNotBlank(docId)) {
                    // 构建更新请求
                    UpdateRequest updateRequest = new UpdateRequest();
                    // 设置索引
                    updateRequest.index(esIndexInfo.getIndexName());
                    // 设置文档
                    updateRequest.id(esSourceData.getDocId());
                    // 设置源数据
                    updateRequest.doc(esSourceData.getData());
                    // 将更新请求放到BulkRequest
                    bulkRequest.add(updateRequest);
                    flag = true;
                }
            }
            // 如果flag为true,就说明更新请求已经存放完毕,可以更新了
            if (flag) {
                // 根据集群名获取客户端执行批量更新
                BulkResponse bulk = getClient(esIndexInfo.getClusterName()).bulk(bulkRequest, COMMON_OPTIONS);
                // 如果有失败的,就返回false
                if (bulk.hasFailures()) {
                    return false;
                }
            }
            // 如果没报错就返回true
            return true;
        } catch (Exception e) {
            // 打日志
            log.error("batchUpdateDoc.error:{}", e.getMessage(), e);
        }
        // 如果报错就返回false
        return false;
    }


    /**
     * 删除索引下的所有文档
     * @param esIndexInfo
     * @return
     */
    public static boolean delete(EsIndexInfo esIndexInfo) {
        try {
            // 根据索引构建一个请求
            DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(esIndexInfo.getIndexName());
            // 设置查询
            deleteByQueryRequest.setQuery(QueryBuilders.matchAllQuery());

            // 指定集群得到客户端进行删除操作
            BulkByScrollResponse response = getClient(esIndexInfo.getClusterName()).deleteByQuery(
                    deleteByQueryRequest, COMMON_OPTIONS
            );

            // 获取删除的数量
            long deleted = response.getDeleted();
            log.info("deleted.size:{}", deleted);
            return true;
        } catch (Exception e) {
            // 打日志
            log.error("delete.error:{}", e.getMessage(), e);
        }

        return false;
    }

    /**
     * 根据id删除文档
     * @param esIndexInfo
     * @return
     */
    public static boolean deleteDoc(EsIndexInfo esIndexInfo, String docId) {
        try {
            // 根据索引获取删除请求
            DeleteRequest deleteRequest = new DeleteRequest(esIndexInfo.getIndexName());
            // 设置要删除的文档id
            deleteRequest.id(docId);

            // 根据集群名获取客户端,执行删除操作
            DeleteResponse response = getClient(esIndexInfo.getClusterName()).delete(deleteRequest, COMMON_OPTIONS);

            // 打日志
            log.info("deleted.response:{}", JSON.toJSONString(response));
            return true;
        } catch (Exception e) {
            // 打日志
            log.error("deleteDoc.error:{}", e.getMessage(), e);
        }

        return false;
    }

    /**
     * 根据id判断文档是否存在
     * @param esIndexInfo
     * @param docId
     * @return
     */
    public static boolean isExistDocById(EsIndexInfo esIndexInfo, String docId) {
        try {
            // 根据索引获取请求
            GetRequest getRequest = new GetRequest(esIndexInfo.getIndexName());
            // 设置文档id
            getRequest.id(docId);

            // 根据集群名返回客户端,判断文档是否存在
            return getClient(esIndexInfo.getClusterName()).exists(getRequest, COMMON_OPTIONS);
        } catch (Exception e) {
            // 打日志
            log.error("isExistDocById.error:{}", e.getMessage(), e);
        }

        return false;
    }

    /**
     * 根据id查询文档(一条记录)
     * @param esIndexInfo
     * @param docId
     * @return
     */
    public static Map<String, Object> getDocById(EsIndexInfo esIndexInfo, String docId) {
        try {
            // 根据索引获取请求
            GetRequest getRequest = new GetRequest(esIndexInfo.getIndexName());
            // 设置文档id
            getRequest.id(docId);

            // 根据集群名返回客户端,根据id查询文档
            GetResponse response = getClient(esIndexInfo.getClusterName()).get(getRequest, COMMON_OPTIONS);
            // 获取文档信息
            Map<String, Object> source = response.getSource();

            return source;
        } catch (Exception e) {
            // 打日志
            log.error("getDocById.error:{}", e.getMessage(), e);
        }

        return null;
    }

    /**
     * 根据id查询指定字段的文档
     * @param esIndexInfo
     * @param docId
     * @param fields
     * @return
     */
    public static Map<String, Object> getDocById(EsIndexInfo esIndexInfo, String docId, String[] fields) {
        try {
            // 根据索引获取请求
            GetRequest getRequest = new GetRequest(esIndexInfo.getIndexName());
            // 设置文档id
            getRequest.id(docId);
            // 设置要查询文档的指定字段
            FetchSourceContext fetchSourceContext = new FetchSourceContext(true, fields, null);
            getRequest.fetchSourceContext(fetchSourceContext);

            // 根据集群名返回客户端,根据id查询文档
            GetResponse response = getClient(esIndexInfo.getClusterName()).get(getRequest, COMMON_OPTIONS);
            // 获取文档信息
            Map<String, Object> source = response.getSource();

            return source;
        } catch (Exception e) {
            // 打日志
            log.error("getDocById.error:{}", e.getMessage(), e);
        }

        return null;
    }

    /**
     * 条件查询
     * @param esIndexInfo
     * @param esSearchRequest
     * @return
     */
    public static SearchResponse searchWithTermQuery(EsIndexInfo esIndexInfo, EsSearchRequest esSearchRequest) {
        try {
            // 获取BoolQueryBuilder
            BoolQueryBuilder bq = esSearchRequest.getBq();

            // 获取查询条件
            String[] fields = esSearchRequest.getFields();
            int from = esSearchRequest.getFrom();
            int size = esSearchRequest.getSize();
            Boolean needScroll = esSearchRequest.getNeedScroll();
            Long minutes = esSearchRequest.getMinutes();
            String sortName = esSearchRequest.getSortName();
            SortOrder sortOrder = esSearchRequest.getSortOrder();
            HighlightBuilder highlightBuilder = esSearchRequest.getHighlightBuilder();

            // 构建查询条件
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            searchSourceBuilder.query(bq);
            // 查询的字段、分页、大小
            searchSourceBuilder.fetchSource(fields, null).from(from).size(size);

            // 如果有高亮的就加入条件
            if (Objects.nonNull(highlightBuilder)) {
                searchSourceBuilder.highlighter(highlightBuilder);
            }

            // 如果有排序字段就加入条件
            if (StringUtils.isNotBlank(sortName)) {
                searchSourceBuilder.sort(sortName);
            }

            // 降序排序
            searchSourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));

            // 构建查询请求
            SearchRequest searchRequest = new SearchRequest();
            // 设置查询类型
            searchRequest.searchType(SearchType.DEFAULT);
            // 设置索引名
            searchRequest.indices(esIndexInfo.getIndexName());
            // 设置查询条件
            searchRequest.source(searchSourceBuilder);
            // 需要快照的情况
            if (needScroll) {
                Scroll scroll = new Scroll(TimeValue.timeValueMinutes(minutes));
                searchRequest.scroll(scroll);
            }
            // 通过集群名来获取客户端执行查询请求
            SearchResponse searchResponse = getClient(esIndexInfo.getClusterName()).search(searchRequest, COMMON_OPTIONS);
            return searchResponse;
        } catch (Exception e) {
            // 打日志
            log.error("searchWithTermQuery.error:{}", e.getMessage(), e);
        }

        return null;
    }

}
7.配置文件和依赖同上

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1991398.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浮点数及其计算

目录 引言 1.浮点数的表示 1.1浮点数的作用和基本原理 1.2浮点数规格化 左规 右规 2.IEEE 754 标准 2.1图示&#xff1a; 2.2 阶码的全零全一有特殊含义: 2.3 IEEE 754 表示的范围&#xff1a; 2.4 十进制转IEEE 754&#xff1a; 2.5 IEEE 754转十进制&#xff1a…

Electron-builder 打包

项目比较简单&#xff0c;仅使用了 Electron 原生js 安装 electron-builder npm install electron-builder --dev配置 package.json 中的打包命令 {"script":{// ..."dev": "electron .","pack": "electron-builder"} }添…

【QT】Qt 音视频

Qt 音视频 Qt 音视频1. Qt 音频2. Qt 视频 Qt 音视频 在 Qt 中&#xff0c;音频主要是通过 QSound 类来实现。但是需要注意的是 QSound 类只支持播放 wav 格式的音频文件。也就是说如果想要添加音频效果&#xff0c;那么首先需要将非 wav 格式的音频文件转换为 wav 格式。 通…

MySQL 5.7 DDL 与 GH-OST 对比分析

作者&#xff1a;来自 vivo 互联网存储研发团队- Xia Qianyong 本文首先介绍MySQL 5.7 DDL以及GH-OST的原理&#xff0c;然后从效率、空间占用、锁阻塞、binlog日志产生量、主备延时等方面&#xff0c;对比GH-OST和MySQL5.7 DDL的差异。 一、背景介绍 在 MySQL 数据库中&…

普元Devops学习笔记-devops构建后jenkins流水线sleep 1hr 23min的问题

1 背景 java项目命名为 simple2。 命名有点随意&#xff0c;不要在意这个&#xff0c;不重要。 simple2的代码维护在gitlab中。 simple2项目有两个git分支&#xff1a; dev 和 master 开发中的代码在 dev分支&#xff0c;dev分支需要合并(merge)到master主分支。 基于此目…

电机控制器遇上第三代半导体,杀手锏是什么?

导语 华东电机控制器市场的创新方向&#xff0c;文中参考答案都有了。 前言 随着工业自动化和智能化进程的加速推进&#xff0c;电机控制器作为驱动系统的核心部件&#xff0c;在推动产业升级转型中扮演着至关重要的角色。华东电机控制器市场以其独特的优势异军突起&#xff0c…

【C++ STL】unordered_mapunordered_set (哈希表)

文章目录 unordered_map&unordered_set1. unordered容器1.1 效率对比 2. 哈希2.1 哈希的定义哈希函数除留余数法自定义哈希函数 哈希冲突 2.2 哈希冲突的解决闭散列/开放定址法两种探测方式闭散列扩容 开散列/拉链法/哈希桶开散列实现 3. 模拟实现3.1 改造哈希表3.2 封装容…

GPIO输入模式之按键控制及光敏传感器控制应用案例

系列文章目录 STM32之GPIO&#xff08;General Purpose Input/Output&#xff0c;通用型输入输出&#xff09; GPIO输出控制之LED闪烁、LED流水灯以及蜂鸣器应用案例 文章目录 系列文章目录前言一、按键简介二、传感器模块简介2.1 AO模拟量输出模块2.2 DO数字量输出模块2.3 指…

【C语言加油站】数据在内存中的存储

数据在内存中的存储 导读一、计算机中的数据类型二、整数在计算机中的存储2.1 整数的存储形式——原码、反码与补码2.2 三种形式之间的相互转换2.3 采用补码存储整数的原因 三、大小端字节序与字节序判断3.1 大端存储与小端存储3.2 为什么会出现大小端存储&#xff1f;3.3 大端…

家用设备轻松搭建 AI 集群,畅跑 Llama 3.1 405B

作者:老余捞鱼 原创不易,转载请标明出处及原作者。 写在前面的话: 本文主要介绍如何在家用设备上运行大型开源语言模型Llama 3.1 405B,首先我会解释构建人工智能集群来提高运行效率的原理,随后会演示如何通过Distributed Llama项目支持在多个设备上运行LLM模型,并…

【STL】05.vector的模拟实现

一、vector的实现 1.1 基本框架 template<class T> class vector {typedef T* iterator;typedef const T* const_iterator; public:private:iterator _startnullptr;iterator _finishnullptr;iterator _end_of_storagenullptr; };1.2 vector的默认成员函数 1.2.1 构造…

如何通过大模型生成业务需要的数据集

现在大模型训练数据的主力都是LLM自己贡献的了。但是也不是说你让它输出什么&#xff0c;然后它就一劳永逸地不停地输出你想要的东西。受限于LLM本身的能力、上下文规定的长度、训练方式导致的有限变化&#xff0c;你需要不断变更你的prompt&#xff0c;以让输出更多样。 接下…

录屏为什么没有声音?一款软件为您解决无声难题

录屏已经成为我们日常工作和生活中不可或缺的一部分。然而&#xff0c;有时在录屏过程中&#xff0c;我们可能会遇到一个令人困惑的问题&#xff1a;录屏为什么没有声音&#xff1f;本文将详细解析电脑录屏没有声音的可能原因&#xff0c;并提供相应的解决方案。同时&#xff0…

YOLOv10问世,登顶GiTHub!性能飞升,【多尺度目标检测】值得大看特看!

【多尺度目标检测】是近年来在深度学习领域中备受关注的一项技术&#xff0c;它通过处理图像中不同尺度的目标&#xff0c;显著提升了模型在复杂场景中的检测精度和鲁棒性。多尺度目标检测技术已经在自动驾驶、安防监控和遥感图像分析等多个领域取得了显著成果&#xff0c;其独…

SQL Server Management Studio的使用

之前在 https://blog.csdn.net/fengbingchun/article/details/140961550 介绍了在Windows10上安装SQL Server 2022 Express和SSMS&#xff0c;这里整理下SSMS的简单使用&#xff1a; SQL Server Management Studio(SSMS)是一种集成环境&#xff0c;提供用于配置、监视和管理SQL…

前端工程师学习springboot2.x之配置idea热更新实现高效率开发节奏

目前已经学习springboot实现了增删改查分页查询&#xff0c;每次修改业财或者是代码重启项目都让我觉得很闹心&#xff0c;现在给出idea2021版本自带热更新操作设置&#xff0c;设置过程分享给大家 总结&#xff1a;以上就是配置的全部过程&#xff0c;祝大家写代码快乐…

鸿蒙(Harmony) NEXT - AlphabetIndexer实现联系人字母索引

鸿蒙(Harmony) NEXT 9月份就要正式上架了&#xff0c;并且不会再兼容安卓平台&#xff0c;于是我也赶紧给App开发鸿蒙版本&#xff0c;接下来会写一系列的Harmony开发教程。 今天使用AlphabetIndexer实现联系人字母索引&#xff0c;AlphabetIndexer是官方封装好的组件 咱们实…

【驱动程序】3.5寸SPI液晶屏_ILI9488_stm32f103c8t6_CubeMX_HAL库

【驱动程序】3.5寸SPI液晶屏_ILI9488_stm32f103c8t6_CubeMX_HAL库 主控芯片&#xff1a; stm32f103c8t6 接线&#xff1a; LED-3.3v其他管脚按main.h文件接: #define LCD_CS_Pin GPIO_PIN_1 #define LCD_CS_GPIO_Port GPIOA #define LCD_RS_Pin GPIO_PIN_2…

武汉流星汇聚:全球化与多元化并进,亚马逊展望电商领域无限可能

在全球电商的浩瀚星空中&#xff0c;亚马逊无疑是最为耀眼的一颗星辰。凭借其多年在跨境市场的深耕细作&#xff0c;亚马逊不仅积累了庞大的高活跃用户群&#xff0c;还构建了显著的平台流量优势。根据Similar Web的权威数据&#xff0c;亚马逊的独立访问用户数量已超过26.59亿…

EGO-Swarm 仿真环境搭建

EGO-Swarm仿真环境搭建 参考教程&#xff1a; https://github.com/ZJU-FAST-Lab/ego-planner-swarm EGO-Swarm是一种分散的异步系统解决方案&#xff0c;用于仅使用机载资源在未知的障碍物丰富的场景中进行多机器人自主导航。 1. 查看系统环境 要运行本仿真程序&#xff0c…