注意:该代码是建立在ES7.0以上,如果版本不一致,请参考官网修改创建映射那部分代码。
枚举类:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Document {
String indexName();
String type() default "";
short shards() default 5;
short replicas() default 1;
String refreshInterval() default "1s";
String indexStoreType() default "fs";
boolean createIndex() default true;
}
package com.voice.elastics.model.annotation;
import com.voice.elastics.model.enums.FieldType;
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({ElementType.FIELD})
@Retention(RUNTIME)
@Documented
public @interface ESField {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
FieldType type() default FieldType.Keyword;
boolean index() default true;
String pattern() default "";
boolean store() default false;
boolean fielddata() default false;
String searchAnalyzer() default "";
String analyzer() default "";
String normalizer() default "";
String[] ignoreFields() default {};
boolean includeInParent() default false;
String[] copyTo() default {};
}
public enum FieldType {
Text,
Byte,
Short,
Integer,
Long,
Date,
Half_Float,
Float,
Double,
Boolean,
Object,
Auto,
Nested,
Ip,
Attachment,
Keyword;
private FieldType() {
}
}
在实体类上添加自定义枚举
package com.voice.elastics.model;
import com.voice.elastics.model.annotation.Document;
import com.voice.elastics.model.annotation.ESField;
import com.voice.elastics.model.enums.DictDataEnum;
import com.voice.elastics.model.enums.FieldType;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
/**
* @author salted fish
* @Date 2020/11/17
*/
@Data
@Document(indexName = "t_record_interface")
public class RecordInterface {
private static Logger log = LoggerFactory.getLogger(RecordInterface.class);
/**
* 唯一主键
*/
@ESField(type = FieldType.Long)
private Integer id;
/**
* 接口调用时间
*/
@ESField(type = FieldType.Date)
private Date createTime;
/**
* 0自身黑名单或记录命中,1外部黑名单命中
*/
@ESField(type = FieldType.Long)
private Integer blackModel;
/**
* 0失败,1成功
*/
@ESField(type = FieldType.Long)
private Integer result;
}
使用工具类加反射机制,构建你的索引
package com.voice.elastics.utils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.voice.elastics.model.annotation.Document;
import com.voice.elastics.model.annotation.ESField;
import com.voice.elastics.model.enums.FieldType;
import org.apache.http.client.utils.DateUtils;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.PutMappingRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* @author salted fish
* @Date 2021/5/8
*/
@Component
public class ESUtil {
private Logger logger = LoggerFactory.getLogger(ESUtil.class);
@Autowired
private RestHighLevelClient restHighLevelClient;
/**
* 创建索引
*/
public <T> void createIndex(T t) throws Exception {
Document document = t.getClass().getAnnotation(Document.class);
if (Objects.isNull(document)) {
throw new RuntimeException("Document缺失, 无法创建索引");
}
String indexName = document.indexName();
CreateIndexRequest request = new CreateIndexRequest(indexName);
fillIndex(request, document);
setMapping(request, t);
CreateIndexResponse result = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
if (result.isAcknowledged()) {
logger.info("创建索引成功,索引名称: " + indexName);
} else {
logger.error("创建索引失败,索引名称: " + indexName);
}
}
/**
* 创建映射 startObject== { endObject== }
*/
private <T> void setMapping(CreateIndexRequest request, T t) throws Exception {
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject();
mapping.startObject("properties");
Field[] fields = t.getClass().getDeclaredFields();
for (Field field : fields) {
ESField esField = field.getAnnotation(ESField.class);
if (Objects.nonNull(esField)) {
mapping.startObject(field.getName())
.field("type", esField.type().name().toLowerCase())
.field("store", esField.store());
if (StringUtils.isNotBlank(esField.searchAnalyzer())) {
mapping.field("search_analyzer", esField.searchAnalyzer());
}
if (StringUtils.isNotBlank(esField.analyzer())) {
mapping.field("analyzer", esField.analyzer());
}
mapping.endObject();
}
}
mapping.endObject().endObject();
request.mapping(mapping);
}
/**
* 填充索引参数
*/
private void fillIndex(CreateIndexRequest request, Document document) {
request.settings(Settings.builder().put("index.number_of_shards", document.shards())
.put("index.number_of_replicas", document.replicas())
.put("index.refresh_interval", document.refreshInterval())
/*.put("index.index_store_type", document.indexStoreType())*/);
}
}