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來實現


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM