SpringDataElasticsearch生成动态数据源

        在项目中遇到一个需求,要对es进行动态存储,按月来存储,按月来查询。在网上找了一圈没一个靠谱的,然后自己琢磨搞出来的

        本项目是一个SpringBoot的单体架构,具体配置就不讲了,直接上代码

1.首先创建用于切换数据源的bean

package com.aaa.config;

import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * 坐标点动态索引名
 *
 * @author handsome
 */
@Component(value = "EsConfigBean")
public class EsConfigBean {

    private static String indexName;

    public static String getIndexName() {
        return indexName;
    }

    public static void setIndexName(String name, LocalDate date) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy_MM");
        EsConfigBean.indexName = name + "_" + date.format(formatter);
    }
}

2.然后是将bean所生成的索引名放在要存储的索引上,记住一定要注意写法,并且一定要加上createIndex = false,这样启动项目的时候才不会自动去es里创建这个索引,你也可以试试不加,看看项目启动效果,嘻嘻嘻。

package com.aaa.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import org.elasticsearch.common.geo.GeoPoint;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.GeoPointField;
import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.format.annotation.DateTimeFormat;

import java.time.LocalDateTime;

/**
 * 工程师索引
 *
 * @author handsome
 */
@Getter
@Setter
@Document(indexName = "#{@EsConfigBean.indexName}", createIndex = false)
@Setting(replicas = 0)
public class PointEntity {

    /**
     * 工程师坐标点id
     */
    @Id
    private String id;

3.最最最重要的一步,写好了,我们该在什么地方切换呢并存储数据呢?

package com.aaa.service.impl;

import com.aaa.config.EsConfigBean;
import com.aaa.entity.PointEntity;
import com.aaa.service.DocumentIndexService;
import lombok.AllArgsConstructor;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.stereotype.Service;

import java.time.LocalDate;

/**
 * @author handsome
 */
@Service
@AllArgsConstructor
public class DocumentIndexServiceImpl implements DocumentIndexService {

    private final ElasticsearchRestTemplate restTemplate;

    @Override
    public void switchExistsIndex(String indexName, LocalDate localDate) {
        EsConfigBean.setIndexName(indexName, localDate);
        boolean exists = restTemplate.indexOps(IndexCoordinates.of(EsConfigBean.getIndexName())).exists();
        if (!exists) {
            IndexOperations indexOps = restTemplate.indexOps(PointEntity.class);
            indexOps.createWithMapping();
        }
    }
}

我是把切换索引这个操作放在一个service里面,方便其他service要用的时候,直接调用就可以啦。

讲一下这儿的逻辑,方便大家理解,其实也很简单啦。

传入索引名,再传入一个日期,然后setIndexName,再去根据这个IndexName去查询es里有没有这个索引,然后进行判断,如果没有,进入下一步逻辑,为PointEntity类创建一个索引,一定要用ceateWithMapping()这个方法,不然创建出来的索引没有映射。

这里有ElasticsearchRestTemplate和ElasticsearchTemplate两种选择,其实都可以用ET,但我们项目不允许用过时的方法 【吐血】,新版本的SpringDataES一般就用的ERT。

4.最后就是使用了,太多引用了,这儿就不放出来了。

package com.aaa.service.impl;

/**
 * @author handsome
 */
@Service
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class PointServiceImpl implements PointService {

    private static final Logger LOGGER = LoggerFactory.getLogger(PointServiceImpl.class);

    private final PointRepo pointRepo;
    private final DocumentIndexService indexService;
    
    @Override
    public PointEntity savePoint(PointEntity pointEntity) {
        indexService.switchExistsIndex(IndexNameEnum.POINT_INDEX.getIndexName(), pointEntity.getCollectTime().toLocalDate());
        return pointRepo.save(pointEntity);
    }
}

这儿的逻辑很简单了吧,切换索引,然后用数据层进行存储,就完成啦。

这样做可以达到按月建索引的目的,但有个缺陷,不能分月查询数据,比如我要查询6月到8月的数据,切换索引的操作就很繁琐。

5.最终的效果

 只能透露这么多啦!!!

各位大佬们,有什么问题可以在评论区讨论哦。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值