锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. JAVA
  4. Elasticsearch8搭建及Springboot中集成使用

Elasticsearch8搭建及Springboot中集成使用

0
  • JAVA
  • 发布于 2024-08-08
  • 0 次阅读
黄健
黄健

本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net

  1. 搭建

1.1. 下载地址

Elasticsearch:https://www.elastic.co/cn/downloads/elasticsearch
Kibana:https://www.elastic.co/cn/downloads/kibana

1.2. 具体过程

下载安装包:访问上述链接,下载适合你操作系统的 Elasticsearch 和 Kibana 安装包。

1.3. 安装 Elasticsearch

解压下载的安装包。
进入解压后的目录。
如果是 Windows 系统,直接进入 bin 目录,双击 elasticsearch.bat 文件。看到命令行中打印日志中出现 “started”,说明 Elasticsearch 启动完成。

linux 中进入 bin 目录,然后执行./elasticsearch 命令

详情参见 linux 系统安装 elasticsearch 教程_linux 安装 es-CSDN 博客

1.4. 配置 Elasticsearch 集群

修改 elasticsearch.yml 文件,设置集群名称、节点名称、网络主机和种子节点等。
对于集群中的其他节点,重复上述步骤,并确保每个节点的配置文件中都有所有节点的 IP 地址。

启动其他节点:在每个节点上重复上述安装步骤,并启动 Elasticsearch 服务。

检查集群健康状态:通过访问 Elasticsearch 的 API 或使用 Kibana 界面,查看集群的健康状态。

请注意,这只是一个基本的搭建指南。在生产环境中,你可能需要更详细的配置和优化。此外,确保你的网络设置允许 Elasticsearch 集群通信所需的端口。

1.5. 注意点

  1. 不能用 root 权限启动,需要新建用户,如:

更改文件夹的用户为 user1  chown -R user1:user1 /local
修改 user1 对文件夹的权限  chmod 777 /local

  1. 获取账号密码

elasticsearch 的 bin 目录下,输入命令行:elasticsearch-reset-password -u elastic

2.springboot 中集成 ES8

2.1. 依赖

<dependency>
    <groupId>co.elastic.clients</groupId>
    <artifactId>elasticsearch-java</artifactId>
    <version>8.1.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.3</version>
</dependency>
<dependency>
    <groupId>jakarta.json</groupId>
    <artifactId>jakarta.json-api</artifactId>
    <version>2.0.1</version>
</dependency>

2.2.elasticsearch.properties

spring.elasticsearch.uris = IP:port
spring.elasticsearch.username = 用户名
spring.elasticsearch.password = 密码

2.3.ElasticSearchConfig

@Configuration
public class ElasticSearchConfig {
 
    @Value("${spring.elasticsearch.uris}")
    private String hosts;
 
    @Value("${spring.elasticsearch.username}")
    private String userName;
 
    @Value("${spring.elasticsearch.password}")
    private String passWord;
 
    @Bean()
    public ElasticsearchClient elasticsearchClient(){
        HttpHost[] httpHosts = toHttpHost();
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(
                AuthScope.ANY, new UsernamePasswordCredentials(userName, passWord));
 
        RestClientBuilder builder = RestClient.builder(httpHosts);
        builder.setRequestConfigCallback(
                new RestClientBuilder.RequestConfigCallback() {
                    @Override
                    public RequestConfig.Builder customizeRequestConfig(
                            RequestConfig.Builder requestConfigBuilder) {
                        return requestConfigBuilder.setSocketTimeout(60000).setConnectTimeout(5000);
                    }
                });
        builder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
            @Override
            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {
 
                return httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
            }
        });
        RestClient restClient = builder.build();
        ElasticsearchTransport transport = new RestClientTransport(restClient,new JacksonJsonpMapper());
        return new ElasticsearchClient(transport);
    }
 
    private HttpHost[] toHttpHost() {
        if (!StringUtils.hasLength(hosts)) {
            throw new RuntimeException("invalid elasticsearch configuration. elasticsearch.hosts不能为空!");
        }
        // 多个IP逗号隔开
        String[] hostArray = hosts.split(",");
        HttpHost[] httpHosts = new HttpHost[hostArray.length];
        HttpHost httpHost;
        for (int i = 0; i < hostArray.length; i++) {
            String[] strings = hostArray[i].split(":");
            httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "http");
            httpHosts[i] = httpHost;
        }
        return httpHosts;
    }
}

2.4. 通用类

2.4.1. 枚举类,ES 实体类注解

@Target({ElemantType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ElasticSearchDocument {
   String index() default "";
   int shards() default 0;
   int replicas() default 0;
}

2.4.2. 查询实体类

@Data
public class EsQueryDTO {
 
    private String indexName;//索引名称
    private String field;//关键字属性
    private String word;//关键字值
    private List<String> words;//关键字值数组
    private Integer from;//起始行
    private Integer index;//当前页
    private Integer size;//分页条数
    private String order;//排序字段
    private String orderType;//排序方式 Asc/Desc
    private String dateField;//时间字段
    private String startTime;//时间范围-开始时间
    private String endTime;//时间范围-开始时间
 
    public String getOrderType() {
        if (StringUtils.isBlank(orderType)) {
            orderType = SortOrder.Desc.name();
        }
        return orderType;
    }
 
    public Integer getSize() {
        return size == 0 ? 30 : size;
    }
 
    public Integer getFrom() {
        return getIndex() != 0 ? ((getIndex() - 1) * getSize()) : 0;
    }
 
    public Integer getIndex() {
        return null == index ? 0 : index;
    }
 
    public String getStartTime(int offset) {
        if (StringUtils.isBlank(startTime)) {
            startTime = DateUtil.format(DateUtil.offsetDay(new Date(), offset), "yyyy-MM-dd 00:00:00");
            return String.valueOf(DateUtil.parse(startTime, "yyyy-MM-dd 00:00:00").getTime());
        }
        return startTime;
    }
 
    public String getEndTime() {
        if (StringUtils.isBlank(endTime)) {
            endTime = String.valueOf(System.currentTimeMillis());
        }
        return endTime;
    }
}

2.4.3. 查询工具类

@Component
public class ElasticClientUtils<T> {
 
    /**
     * @param
     * @param client
     * @param dto
     * @param target
     * @return java.util.List<T>
     * @author liuch
     * @description 根据关键字查询
     * @date 2022/4/2 17:15
     */
    public List<T> queryByFiled(ElasticsearchClient client, EsQueryDTO dto, Class<T> target) throws Exception {
        List<T> result = new ArrayList<>();
        List<SortOptions> sorts = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getOrder())) {
            SortOptions sortOptions = SortOptions.of(s -> s.field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
            sorts.add(sortOptions);
        }
        SearchResponse<HashMap> search = client.search(s -> s
                        .index(dto.getIndexName())
                        .query(q -> q.term(t -> t
                                .field(dto.getField())
                                .value(dto.getWord())
                        )).sort(sorts),
                HashMap.class);
        return getResult(target, result, search);
    }
 
    /**
     * @param
     * @param client
     * @param dto
     * @param target
     * @return java.util.List<T>
     * @author liuch
     * @description 根据关键字查询,基于游标查询scroll
     * @date 2022/4/2 17:15
     */
    public List<T> queryByFileds(ElasticsearchClient client, EsQueryDTO dto, List<Query> queries, Class<T> target) throws Exception {
        List<T> result = new ArrayList<>();
        List<SortOptions> sorts = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getOrder())) {
            SortOptions sortOptions = SortOptions.of(s -> s.field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
            sorts.add(sortOptions);
        }
        getFieldValues(dto, queries);
        //使用scroll深度分页查询
        SearchResponse<HashMap> search = client.search(s -> s
                        .index(dto.getIndexName()).query(q -> q.bool(b -> b.must(queries))).size(5000).scroll(t -> t.time("5s"))
                        .sort(sorts),
                HashMap.class);
        StringBuffer scrollId = new StringBuffer(search.scrollId());
        //循环查询,直到查不到数据
        do {
            getResult(target, result, search);
            StringBuffer finalScrollId = scrollId;
            search = client.scroll(s -> s.scrollId(finalScrollId.toString()).scroll(t -> t.time("5s")), HashMap.class);
            scrollId = new StringBuffer(search.scrollId());
        } while (!search.hits().hits().isEmpty());
        //getResult(target, result, search)
        return result;
    }
 
    /**
     * @param
     * @param client
     * @param dto
     * @param target
     * @return java.util.List<T>
     * @author liuch
     * @description 根据关键字分页查询
     * @date 2022/4/2 17:15
     */
    public List<T> queryByFiledWithPage(ElasticsearchClient client, EsQueryDTO dto, Class<T> target) throws Exception {
        List<T> result = new ArrayList<>();
        List<SortOptions> sorts = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getOrder())) {
            SortOptions sortOptions = SortOptions.of(s -> s.field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
            sorts.add(sortOptions);
        }
        SearchResponse<HashMap> search = client.search(s -> s
                        .index(dto.getIndexName())
                        .query(q -> q.term(t -> t
                                .field(dto.getField())
                                .value(dto.getWord())
                        )).sort(sorts).from(dto.getFrom()).size(dto.getSize()),
                HashMap.class);
        return getResult(target, result, search);
    }
 
 
    private List<T> getResult(Class<T> target, List<T> result, SearchResponse<HashMap> search) {
        List<Hit<HashMap>> hits = search.hits().hits();
        Iterator<Hit<HashMap>> iterator = hits.iterator();
        while (iterator.hasNext()) {
            Hit<HashMap> decodeBeanHit = iterator.next();
            Map<String, Object> docMap = decodeBeanHit.source();
            docMap.put("id", decodeBeanHit.id());
            String json = JSON.toJSONString(docMap);
            T obj = JSON.parseObject(json, target);
            result.add(obj);
        }
        return result;
    }
 
    /**
     * @param
     * @param client
     * @param dto
     * @return long
     * @author liuch
     * @description 根据关键字查询总条数
     * @date 2022/4/2 17:15
     */
    public static long queryCountByFiled(ElasticsearchClient client, EsQueryDTO dto) throws Exception {
        CountResponse count = client.count(c -> c.index(dto.getIndexName()).query(q -> q.term(t -> t
                .field(dto.getField())
                .value(dto.getWord())
        )));
        long total = count.count();
        return total;
    }
 
    /**
     * @param
     * @param client
     * @param dto
     * @return long
     * @author liuch
     * @description 根据关键字查询总条数-复合查询
     * @date 2022/4/2 17:15
     */
    public static long queryCountByFileds(ElasticsearchClient client, List<Query> queries, EsQueryDTO dto) throws Exception {
        getFieldValues(dto, queries);
        CountResponse count = client.count(c -> c.index(dto.getIndexName()).query(q -> q.bool(b -> b.must(queries))));
        long total = count.count();
        return total;
    }
 
 
    /**
     * @param client
     * @param dto
     * @param target
     * @return java.util.List<T>
     * @author liuch
     * @description 根据关键字分页查询- 复合查询  must
     * @date 2022/4/2 17:15
     */
    public List<T> queryMustByFiledsWithPage(ElasticsearchClient client, EsQueryDTO dto, List<Query> queries, Class<T> target) throws Exception {
        List<T> result = new ArrayList<>();
        List<SortOptions> sorts = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getOrder())) {
            SortOptions sortOptions = SortOptions.of(s -> s
                    .field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
            sorts.add(sortOptions);
        }
        SearchResponse<HashMap> search = client.search(s -> s
                        .index(dto.getIndexName())
                        .query(q -> q.bool(b -> b.must(queries)))
                        .sort(sorts).from(dto.getFrom()).size(dto.getSize()),
                HashMap.class);
        return getResult(target, result, search);
    }
 
/**
     * @param client
     * @param dto
     * @param target
     * @return java.util.List<T>
     * @author liuch
     * @description 根据关键字分页查询- 复合查询  must 过滤
     * @date 2022/4/2 17:15
     */
    public List<T> queryMustByFiledsWithPage(ElasticsearchClient client, EsQueryDTO dto, List<Query> queries, List<Query> filters, Class<T> target) throws Exception {
        List<T> result = new ArrayList<>();
        List<SortOptions> sorts = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getOrder())) {
            SortOptions sortOptions = SortOptions.of(s -> s
                    .field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
            sorts.add(sortOptions);
        }
        SearchResponse<HashMap> search = client.search(s -> s
                        .index(dto.getIndexName())
                        .query(q -> q.bool(b -> b.must(queries).filter(filters)))
                        .sort(sorts).from(dto.getFrom()).size(dto.getSize()),
                HashMap.class);
        return getResult(target, result, search);
    }
 
 
    /**
     * @param client
     * @param dto
     * @param target
     * @return java.util.List<T>
     * @author liuch
     * @description 根据关键字分页查询- 复合查询  should
     * @date 2022/4/2 17:15
     */
    public List<T> queryShouldByFiledsWithPage(ElasticsearchClient client, EsQueryDTO dto, List<Query> queries, Class<T> target) throws Exception {
        List<T> result = new ArrayList<>();
        List<SortOptions> sorts = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getOrder())) {
            SortOptions sortOptions = SortOptions.of(s -> s
                    .field(f -> f.field(dto.getOrder()).order(SortOrder.valueOf(dto.getOrderType()))));
            sorts.add(sortOptions);
        }
        SearchResponse<HashMap> search = client.search(s -> s
                        .index(dto.getIndexName())
                        .query(q -> q.bool(b -> b.should(queries)))
                        .sort(sorts).from(dto.getFrom()).size(dto.getSize()),
                HashMap.class);
        return getResult(target, result, search);
    }
 
    /**
     * 构件复合查询条件
     *
     * @param dto
     * @param queries
     */
    private static void getFieldValues(EsQueryDTO dto, List<Query> queries) {
        List<FieldValue> fieldValues = new ArrayList<>();
        //根据关键字列表构件复合查询的值
        dto.getWords().stream().forEach(word -> fieldValues.add(FieldValue.of(word)));
        //查询条件列表
        queries.add(Query.of(q -> q.terms(t -> t.field(dto.getField()).terms(v -> v.value(fieldValues)))));
    }
 
 
    /**
     * @param
     * @param client
     * @param dto
     * @param target
     * @return java.lang.Object
     * @author liuch
     * @description 根据文档id查询
     * @date 2022/4/2 17:16
     */
    public Object queryByDocumentId(ElasticsearchClient client, EsQueryDTO dto, Class<T> target) throws Exception {
        GetResponse<HashMap> getResponse = client.get(s -> s
                        .index(dto.getIndexName()).id(dto.getWord()),
                HashMap.class);
        getResponse.source();
        Map<String, Object> docMap = getResponse.source();
        String json = JSON.toJSONString(docMap);
        T obj = JSON.parseObject(json, target);
        return obj;
    }
 
}

2.4.4. 基础操作接口

/**
 * 基础操作---接口
 */
public interface IElasticSearchIRepository<T, V> {
 
 
    int delete(V id);
 
    int update(T entity);
 
    T getById(V id);
   
    List<T> getAll();
 
    long count();
 
    PageInfo<T> getListByPage(int pageIndex, int pageSize);
 
    /**
     * 新增一个文档
     *
     * @param entity 实体类
     * @return
     */
    IndexResponse createByFluentDSL(T entity);
 
    /**
     * 新增一个文档
     *
     * @param entity 实体类
     * @return
     */
    IndexResponse createByBuilderPattern(T entity);
 
    /**
     * 批量增加文档
     *
     * @param list 对象集合
     * @return 批量操作的结果
     */
    BulkResponse bulkCreate(List<T> list);
 
   /**
     * 根据文档id查找文档,返回类型是ObjectNode
     *
     * @param id  文档id
     * @return ObjectNode类型的查找结果
     */
    ObjectNode getObjectNodeById(V id);
 
 
    /**
     * 批量删除文档
     *
     * @param docIds  要删除的文档id集合
     * @return
     * @throws Exception
     */
    BulkResponse bulkDeleteByIds(List<V> docIds);
 
    /**
     * 根据文档id删除文档
     *
     * @param idxName 索引名
     * @param docId   文档id
     * @return Object类型的查找结果
     * @throws Exception
     */
    Boolean deleteById(String idxName, String docId) throws IOException;
 
    
    /**
     * 新建索引,指定索引名称
     *
     */
    Boolean createIndex();
 
    /**
     * 创建索引,指定索引名称和setting和mapping
     *
     * @param settingFn - 索引参数
     * @param mappingFn - 索引结构
     */
    Boolean createIndex(Function<IndexSettings.Builder, ObjectBuilder<IndexSettings>> settingFn,
                     Function<TypeMapping.Builder, ObjectBuilder<TypeMapping>> mappingFn);
 
    /**
     * 删除索引
     * @throws IOException
     */
    Boolean deleteIndex();
 
    /**
     * 修改索引字段信息 <br/>
     * 字段可以新增,已有的字段只能修改字段的 search_analyzer 属性。
     *
     * @param propertyMap - 索引字段,每个字段都有自己的property
     * @throws IOException
     */
    Boolean updateIndexProperty(HashMap<String, Property> propertyMap);
 
    
 
    /**
     * 查询索引列表
     *
     * @return
     * @throws IOException
     */
    GetIndexResponse getIndexList();
 
    /**
     * 查询索引详情
     *
     * @return
     * @throws IOException
     */
    GetIndexResponse getIndexDetail();
 
    /**
     * 检查指定名称的索引是否存在
     *
     * @return - true:存在
     * @throws IOException
     */
    boolean indexExists();
 
}

2.4.5. 基础操作接口实现类

public abstract class ElasticSearchIRepository<T,V> implements IElasticSearchIRepository<T,V> {
 
    @Autowired(required =false)
    @Qualifier("elasticsearchClient")
    private ElasticsearchClient elasticsearchClient;
 
    protected ElasticSearchDocument getEntityProperties() {
        Class<T> cls = getEntityClass();
        ElasticSearchDocument esDoc = cls.getAnnotation(ElasticSearchDocument .calss);
        return esDoc;
    }
 
    /**设置索引全局配置*/
    protected abstract Function<IndexSettings.builder, ObjectBuilder<IndexSettings>> getIndexSettings();
 
    /**手动设置映射(不手动设置会自动创建映射,同时在插入时若手动映射时没有的字段也会自动创建)*/
    protected abstract Function<TypeMapping.builder, ObjectBuilder<TypeMapping>> getIndexMappings();
 
    protected abstract Class<T> getEntityClass();
 
 
    @Override
    public int update(T entity) {
         try {
            ElasticSearchDocument doc = getEntityProperties();
            UpdateRequest updateRequest = new UpdateRequest.Builder()
                    .index(doc.index())
                    .id(entity.getId().toString())
                    .doc(entity)
                    .build();
            UpdateResponse updateResponse = elasticsearchClient.update(updateRequest, entity.getClass());
            return updateResponse != null && StringUtils.isNotEmpty(updateResponse.id()) ? 1 : 0;
         }
         catch (IOException e) {
            log.error(e);
         }
         return 0;
    }
 
   @Override
    public PageInfo<T> getListByPage(int pageIndex, int pageSize) {
         List<T> list = new ArrayList<>();
         try {
            ElasticSearchDocument doc = getEntityProperties();
            ElasticClientUtils elasticClientUtils = new ElasticClientUtils();
            EsQueryDTO dto = new EsQueryDTO();
            dto.setIndex(paeIndex);
            dto.setSize(pageSize);
            dto.setIndexName(doc.index());
            list = elasticClientUtils.queryPage(elasticsearchClient, dto, getEntityClass());
            return new PageInde<T>(pageIndex, pageSize, (long)list.size(), list);
         }
         catch (IOException e) {
            log.error(e);
         }
         return new PageInde<T>(pageIndex, pageSize, 0L, list);
    }
 
   @Override
    public int delete(V id) {
         try {
            ElasticSearchDocument doc = getEntityProperties();
            DeleteResponse delete = elasticsearchClient.delete(d -> d
                    .index(doc.index())
                    .id(id.toString()));
            return delete.forcedRefresh() ? 1 : 0;
         }
         catch (IOException e) {
            log.error(e);
         }
         return 0;
    }
 
    @Override
    public List<T> getAll() {
         try {
            ElasticSearchDocument doc = getEntityProperties();
            ElasticClientUtils elasticClientUtils = new ElasticClientUtils();
            EsQueryDTO dto = new EsQueryDTO();
            dto.setIndexName(doc.index());
            return elasticClientUtils.queryAll(elasticsearchClient, dto, getEntityClass());
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }
 
    @Override
    public long count() {
         try {
            ElasticSearchDocument doc = getEntityProperties();
            EsQueryDTO dto = new EsQueryDTO();
            dto.setIndexName(doc.index());
            return ElasticClientUtils.queryCountByFiled(elasticsearchClient, dto);
         }
         catch (IOException e) {
            log.error(e);
         }
         return 0;
    }
 
    @Override
    public IndexResponse createByFluentDSL(T entity) {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            IndexResponse response = elasticsearchClient.index(index -> idx
                     .index(doc.index())
                     .id(entity.getId().toString())
                     .document(entity));
            return response;
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }
 
    @Override
    public IndexResponse createByBuilderPattern(T entity) {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            IndexRequest.Builder<Object> indexReqBuilder = new IndexRequest.Builder<>();
 
            indexReqBuilder.index(doc.index());
            indexReqBuilder.id(entity.getId().toString());
            indexReqBuilder.document(entity);
            return elasticsearchClient.index(indexReqBuilder.build());
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }
 
    @Override
    public BulkResponse bulkCreate(List<T> documents) {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            BulkRequest.Builder br = new BulkRequest.Builder();
            documents.stream()
                .forEach(esDocument -> br
                        .operations(op -> op
                                .index(idx -> idx
                                        .index(doc.index())
                                        .id(esDocument.getId().toString())
                                        .document(esDocument))));
 
            return elasticsearchClient.bulk(br.build());
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }
 
    @Override
    public T getById(V id) {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            GetResponse<Object> response = elasticsearchClient.get(g -> g
                        .index(doc.index())
                        .id(id.toString()),
                Object.class);
        return response.found() ? FastJsonUtil.fromJson(response.source().toString(), getEntityClass()) : null;
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }
 
    @Override
    public ObjectNode getObjectNodeById(V id) {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            GetResponse<ObjectNode> response = elasticsearchClient.get(g -> g
                        .index(doc.index())
                        .id(id.toString()),
                ObjectNode.class);
 
        return response.found() ? response.source() : null;
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }
 
   
 
    @Override
    public BulkResponse bulkDeleteByIds(List<V> docIds) {
 
        try {
            ElasticSearchDocument doc = getEntityProperties();
            BulkRequest.Builder br = new BulkRequest.Builder();
 
             // 将每一个对象都放入builder中
             docIds.stream().forEach(id -> br
                .operations(op -> op
                        .delete(d -> d
                                .index(doc.index())
                                .id(id.toString()))));
 
             return elasticsearchClient.bulk(br.build());
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }
 
   /**自动创建映射*/
    @Override
    public Boolean createIndex() {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            CreateIndexResponse response = elasticsearchClient.indices().create(c -> c.index(doc.index()));
        log.info("createIndex方法,acknowledged={}", response.acknowledged());
        return response.acknowledged();
         }
         catch (IOException e) {
            log.error(e);
         }
         return false;
    }
 
    /**手动创建映射*/
    @Override
    public Boolean createIndex(Function<IndexSettings.Builder, ObjectBuilder<IndexSettings>> settingFn,
                            Function<TypeMapping.Builder, ObjectBuilder<TypeMapping>> mappingFn) {
 
        try {
            ElasticSearchDocument doc = getEntityProperties();
            CreateIndexResponse response = elasticsearchClient
                .indices()
                .create(c -> c
                        .index(doc.index())
                        .settings(settingFn)
                        .mappings(mappingFn)
                );
        log.info("createIndex方法,acknowledged={}", response.acknowledged());
          return response.acknowledged();
         }
         catch (IOException e) {
            log.error(e);
         }
         return false;
        
    }
 
    @Override
    public Boolean deleteIndex() {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            DeleteIndexResponse response = elasticsearchClient.indices().delete(c -> c.index(doc.index()));
        log.info("deleteIndex方法,acknowledged={}", response.acknowledged());
        return response.acknowledged();
         }
         catch (IOException e) {
            log.error(e);
         }
         return false;
        
    }
 
    @Override
    public Boolean updateIndexProperty(HashMap<String, Property> propertyMap) {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            PutMappingResponse response = elasticsearchClient.indices()
                .putMapping(typeMappingBuilder ->
                        typeMappingBuilder
                                .index(doc.index())
                                .properties(propertyMap)
                );
        log.info("updateIndexMapping方法,acknowledged={}", response.acknowledged());
        return response.acknowledged();
         }
         catch (IOException e) {
            log.error(e);
         }
         return false;
    }
 
    @Override
    public GetIndexResponse getIndexList() {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            //使用 * 或者 _all都可以
        GetIndexResponse response = elasticsearchClient.indices().get(builder -> builder.index("_all"));
        log.info("getIndexList方法,response.result()={}", response.result().toString());
        return response;
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }
 
    @Override
    public GetIndexResponse getIndexDetail() {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            GetIndexResponse response = elasticsearchClient.indices().get(builder -> builder.index(doc.index()));
        log.info("getIndexDetail方法,response.result()={}", response.result().toString());
        return response;
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
        
    }
 
    @Override
    public boolean indexExists() {
        try {
            ElasticSearchDocument doc = getEntityProperties();
            return elasticsearchClient.indices().exists(b -> b.index(doc.index())).value();
         }
         catch (IOException e) {
            log.error(e);
         }
         return null;
    }  
 
}

2.5. 业务

2.5.1. 接口

pulbic interface testRepo extends IElasticSearchIRepository<TestESDO, Long> {
 
}

2.5.2. 实现类

@component
pulbic calss testRepo extends ElasticSearchIRepository<TestESDO, Long> implements testRepo{
    /**设置索引全局配置*/
    @Override
    protected Function<IndexSettings.builder, ObjectBuilder<IndexSettings>> getIndexSettings() {
        return builder -> builder.numberOfShards("3").numberOfReplicas("1");
     }
 
    /**手动设置映射(不手动设置会自动创建映射,同时在插入时若手动映射时没有的字段也会自动创建)*/
    @Override
    protected Function<TypeMapping.builder, ObjectBuilder<TypeMapping>> getIndexMappings() {
    return builder -> {
        HashMap<String, Property> propertiesMap = new HashMap<>();
        propertiesMap.put("id", new Property.Builder().Long_(new LongNumberProperty.Builder().build()).build());
        return builder.properties(propertiesMap);
    }
 }
 
    @Override
    protected Class<T> getEntityClass() {
    return TestESDO.clas;    
}
}

2.5.3. 实体类

@Data
@ElasticSearchCocument(index="test")
public class TestESDO {
 
   private Long id;
}

2.5.4. 常见查询方法

  1. 使用 MultiMatch 可以多字段,如果想要把搜索词当成一个整体来匹配查询还需要增加 TextQueryType.Phrase,如
//must复合查询
List<Query> queries = new ArrayLict<>();
MultiMatchQuery multiMatchQuery = new MultiMatchQuery.Builder()
        .query("搜索词")
         .type(TextQueryType.Phrase)
         .fields("字段1", "字段2")
         .build();
Query query = new Query.Builder()
         .multiMatch(multiMatchQuery).build();
queries.add(multiMatchQuery);
  1. 使用 TermsQuery 进行数组过滤,如对某个字段 [1,2,3,4] 进行过滤,要求只有搜索词中包含这些数字就进行匹配,如 4,5 或者 1,2,3 或者 1,代码如下
//过滤
List<Query> filters = new ArrayLict<>();
List<FieldValue> fieldValueList = new ArrayList<>();
fieldValueList.add(new FieldValue.Builder().longValue(1).buld());
TermsQuery termsQuery = new TermsQuery .Builder()
         .field("字段1")
         .terms(new TermsQueryField.Builder().value(fieldValueList).build())
         .build();
Query filter = new Query.Builder()
         .terms(termsQuery).build();
filters.add(filter);
  1. 更多查询参见:ElasticSearch 使用教程、设计到实战 - CSDN 博客
标签: #JAVA 991
相关文章

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

SpringBoot整合异步任务执行 2024-10-08 11:24

同步任务: 同步任务是在单线程中按顺序执行,每次只有一个任务在执行,不会引发线程安全和数据一致性等 并发问题 同步任务需要等待任务执行完成后才能执行下一个任务,无法同时处理多个任务,响应慢,影响用 户体验 异步任务: 异步任务是在多线程中同时执行,多个任务可以并发执行,同时处理多个请求,响应快,资源

springboot kafka多数据源,通过配置动态加载发送者和消费者 2024-10-08 11:24

前言 最近做项目,需要支持kafka多数据源,实际上我们也可以通过代码固定写死多套kafka集群逻辑,但是如果需要不修改代码扩展呢,因为kafka本身不处理额外逻辑,只是起到削峰,和数据的传递,那么就需要对架构做一定的设计了。 准备test kafka本身非常容易上手,如果我们需要单元测试,引入ja

SpringBoot 集成 Redis 2024-10-08 11:24

一:SpringBoot 集成 Redis ①Redis是一个 NoSQL(not only)数据库, 常作用缓存 Cache 使用。 ②Redis是一个中间件、是一个独立的服务器;常用的数据类型: string , hash ,set ,zset , list ③通过Redis客户端可以使用多种语

SpringBoot整合QQ邮箱 2024-10-08 11:24

SpringBoot可以通过导入依赖的方式集成多种技术,这当然少不了我们常用的邮箱,现在本章演示SpringBoot整合QQ邮箱发送邮件…. 下面按步骤进行: 1.获取QQ邮箱授权码 1.1 登录QQ邮箱 1.2 开启SMTP服务 找到下图中的SMTP服务区域,如果当前账号未开启的话自己手动开启。

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.