elasticSearch使用LocaldateTime

elasticSearch版本6.8.12 springboot版本2.2.7 springdataelasticSearch版本3.2.7

使用 

ElasticsearchRepository  向elasticSearch 中添加 时间类型为LocaldateTime 的记录

entity

package com.aila.elasticSearch.POJO;

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.*;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * <p>
 * 艾拉项目  音乐表
 * </p>
 *
 * @author chenzhichao
 * @since 2020-12-08
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Document(indexName = "music",shards=5,replicas = 2)
public class MusicElasticEntity implements Serializable{

    @ApiModelProperty(value = "音乐表主键id")
    @Field(index = true, store = true, type = FieldType.Keyword)
    @Id
    private Long id;

    @ApiModelProperty(value = "音乐名称")
    @Field(index = true, store = true, type = FieldType.Text, analyzer = "ik_smart")
    private String name;

    @ApiModelProperty(value = "歌手名称")
    @Field(index = true, store = true, type = FieldType.Text)
    private String singer;

    @ApiModelProperty(value = "歌曲链接地址")
    @Field(index = false, store = true, type = FieldType.Text)
    private String linkUrl;

    @ApiModelProperty(value = "专辑名称")
    @Field(index = true, store = true, type = FieldType.Text)
    private String albumName;

    @ApiModelProperty(value = "mv链接地址")
    @Field(index = false, store = true, type = FieldType.Text)
    private String mvUrl;

    @ApiModelProperty(value = "封面Url")
    @Field(index = false, store = true, type = FieldType.Text)
    private String cover;

    @ApiModelProperty(value = "状态 1 上架状态  0下架状态 ")
    @Field(index = true, store = true, type = FieldType.Integer)
    private Integer status;

    @ApiModelProperty(value = "删除标志 1删除  0未删除")
    @Field(index = true, store = true, type = FieldType.Integer)
    private Integer deleteFlag;

    @ApiModelProperty(value = "歌词链接Url")
    @Field(index = false, store = true, type = FieldType.Text)
    private String lyricLinkUrl;

    @ApiModelProperty(value = "歌曲时长")
    @Field(index = false, store = true, type = FieldType.Date,format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    //@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    //@JSONField(format = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime duration;

    @ApiModelProperty(value = "发行商")
    @Field(index = true, store = true, type = FieldType.Text)
    private String publisher;

    @ApiModelProperty(value = "发行时间")
    @Field(index = false, store = true, type = FieldType.Date)
    private LocalDateTime issueTime;

    @ApiModelProperty(value = "一级分类")
    @Field(index = true, store = true, type = FieldType.Integer)
    private Integer musicTypeId;

    @ApiModelProperty(value = "二级分类")
    @Field(index = true, store = true, type = FieldType.Integer)
    private Integer parentMusicTypeId;

    @ApiModelProperty(value = "三级分类")
    @Field(index = true, store = true, type = FieldType.Integer)
    private Integer grandpaMusicTypeId;

    @ApiModelProperty(value = "创建时间")
    private LocalDateTime createdTime;

    @ApiModelProperty(value = "更新时间")
    private LocalDateTime updateTime;

    @ApiModelProperty(value = "更新人 userId")
    private Long updateBy;

    @ApiModelProperty(value = "创建人 userId")
    private Long createdBy;


}

test类

package com.aila.elasticSearch.service.impl;

import com.aila.elasticSearch.POJO.MusicElasticEntity;
import com.aila.elasticSearch.service.IMusicService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.time.LocalDateTime;


/**
 * @author chenzhichao
 * @date 2020/12/8 16:38
 * 使用es版本  6-8-12 ik分词器版本6-8-12
 */
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest
public class MusicServiceImplTest {

    @Resource
    private IMusicService iMusicService;
    @Test
    public void add() {
        MusicElasticEntity entity = new MusicElasticEntity();
        entity.setId(16L).setName("亲情式的爱情").setSinger("许嵩")
                .setAlbumName("梦游计").setStatus(1).setDeleteFlag(0).setMusicTypeId(3)
                .setParentMusicTypeId(4).setGrandpaMusicTypeId(5)
                //时间这块没有解决
                .setDuration(LocalDateTime.of(2020,12,8,0,4,44));
                //.setDuration(new Date());
                //.setDuration("2020-12-08 00:04:44");
        iMusicService.add(entity);
    }
    @Test
    public void findByEntityId() {
        //MusicElasticEntity entity = iMusicService.findByEntityId(13L);
        MusicElasticEntity entity = iMusicService.findByEntityId(15L);
        System.out.println(entity);
    }
    @Test
    public void deleteMappingAndIndex() {
        iMusicService.deleteMappingAndIndex("com.aila.elasticSearch.POJO.MusicElasticEntity");
    }
    @Test
    public void createMappingAndIndex() {
        iMusicService.createMappingAndIndex("com.aila.elasticSearch.POJO.MusicElasticEntity");
    }
}

serviceImpl

package com.aila.elasticSearch.service.impl;

import com.aila.elasticSearch.POJO.MusicElasticEntity;
import com.aila.elasticSearch.entity.Music;
import com.aila.elasticSearch.mapper.MusicElasticMapper;
import com.aila.elasticSearch.mapper.MusicMapper;
import com.aila.elasticSearch.service.IMusicService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.Optional;

/**
 * <p>
 * 艾拉项目  音乐表 服务实现类
 * </p>
 *
 * @author chenzhichao
 * @since 2020-12-08
 */
@Service
@Slf4j
public class MusicServiceImpl extends ServiceImpl<MusicMapper, Music> implements IMusicService {

    @Autowired
    private MusicElasticMapper musicElasticMapper;
    @Resource
    private ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    private Gson gson;

    @Override
    public void createMappingAndIndex(String className) {
        Class<?> targetClass = null;
        try {
            targetClass = Class.forName(className);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Assert.notNull(targetClass,"创建class对象失败");
        elasticsearchTemplate.createIndex(targetClass);
        elasticsearchTemplate.putMapping(targetClass);
    }

    @Override
    public void deleteMappingAndIndex(String className) {
        Class<?> targetClass = null;
        try {
            targetClass = Class.forName(className);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Assert.notNull(targetClass,"创建class对象失败");
        elasticsearchTemplate.deleteIndex(targetClass);
    }

    @Override
    public void add(MusicElasticEntity entity) {
        log.error("开始添加"+gson.toJson(entity));
        musicElasticMapper.save(entity);
        log.error("结束");
    }

    @Override
    public MusicElasticEntity findByEntityId(Long id) {
        Optional<MusicElasticEntity> optional = musicElasticMapper.findById(id);
        MusicElasticEntity elasticEntity=null;
        if (optional.isPresent()) {
            elasticEntity = optional.get();
        }
        return elasticEntity;
    }
}

配置类

package com.aila.elasticSearch.config;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.elasticsearch.client.Client;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.EntityMapper;
import org.springframework.data.elasticsearch.core.geo.CustomGeoModule;
import org.springframework.data.mapping.MappingException;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author chenzhichao
 * @date 2020/12/14 11:15
 */
@Configuration
public class ElasticSearchConfiguration {
    @Bean
    public ElasticsearchTemplate elasticsearchTemplate(Client client) {
        return new ElasticsearchTemplate(client, new CustomEntityMapper());
    }

    public static class CustomEntityMapper implements EntityMapper {

        private final ObjectMapper objectMapper;

        public CustomEntityMapper() {
            objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
            objectMapper.registerModule(new CustomGeoModule());
            objectMapper.registerModule(new JavaTimeModule());
        }

        @Override
        public String mapToString(Object object) throws IOException {
            return objectMapper.writeValueAsString(object);
        }

        @Override
        public <T> T mapToObject(String source, Class<T> clazz) throws IOException {
            return objectMapper.readValue(source, clazz);
        }

        @Override
        public Map<String, Object> mapObject(Object source) {
            try {
                return objectMapper.readValue(mapToString(source), HashMap.class);
            } catch (IOException e) {
                throw new MappingException(e.getMessage(), e);
            }
        }

        @Override
        public <T> T readObject(Map<String, Object> source, Class<T> targetType) {
            try {
                return mapToObject(mapToString(source), targetType);
            } catch (IOException e) {
                throw new MappingException(e.getMessage(), e);
            }
        }
    }
}

如果没有这个配置类  LocaldateTime 会被转成

一个类似下面的json 串 而elasticSearch 序列化不了这个json

"creationDate": {
    "dayOfYear": 123,
    "dayOfWeek": "FRIDAY",
    "month": "MAY",
    "dayOfMonth": 3,
    "year": 2019,
    "monthValue": 5,
    "hour": 11,
    "minute": 54,
    "second": 12,
    "nano": 238000000,
    "chronology": {
        "id": "ISO",
        "calendarType": "iso8601"
    }
},

所以需要自定义entityMapper的对象使用jackson 来转化 对应的localdateTIme来实现

posted @ 2020-12-14 13:42  kyousuke  阅读(2929)  评论(0编辑  收藏  举报