索引列舉:
@Getter
@AllArgsConstructor
public enum ElasticsearchIndex {
AAA("aaa", true),
;
@Getter(AccessLevel.PROTECTED)
private final String mainName;
//是否是滾動索引
@Getter(AccessLevel.PRIVATE)
private final boolean rolling;
@Setter(AccessLevel.PROTECTED)
private static String prefix;
private static final String SUFFIX = "-alias";
private static final String SEQUENCE_START = "000001";
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private static final DateTimeFormatter YEAR_MONTH_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM");
public String getAlias(LocalDate date) {
return String.join("_", prefix, mainName, DATE_TIME_FORMATTER.format(date)) + SUFFIX;
}
public String getAlias(YearMonth yearMonth) {
return String.join("_", prefix, mainName, YEAR_MONTH_DATE_TIME_FORMATTER.format(yearMonth)) + SUFFIX;
}
public List<String> getAliases(LocalDate date) {
if (!rolling) {
return getAliases();
}
return Collections.singletonList(String.join("_", prefix, mainName, DATE_TIME_FORMATTER.format(date)) + SUFFIX);
}
public List<String> getAliases() {
if (rolling) {
return getAliases(LocalDate.now());
}
return Collections.singletonList(String.join("_", prefix, mainName)+ SUFFIX);
}
public List<String> getAliases(LocalDate start, LocalDate end) {
if (!rolling) {
return getAliases();
}
if (start.isAfter(end)) {
LocalDate buff = start;
start = end;
end = buff;
} else if (start.equals(end)) {
return getAliases(start);
}
int len = (int) ChronoUnit.DAYS.between(start, end) + 1;
List<String> res = new ArrayList<>(len);
for (int i = 0; i < len; i++) {
res.add(getAlias(start));
start = start.plusDays(1);
}
return res;
}
String getFirstIndex(LocalDate date) {
return String.join("_", prefix, mainName, DATE_TIME_FORMATTER.format(date)) + "-" + SEQUENCE_START;
}
}
對映獲取方法:
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class MappingUtils {
private static final String MAPPING_PATH = File.separator + "elasticsearch_index" + File.separator;
public static InputStream getInputStream(String fileName) throws IOException {
fileName = fileName + ".json";
Resource resource = new ClassPathResource(MAPPING_PATH + fileName);
return resource.getInputStream();
}
}
索引建立方法:
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Slf4j
public class ElasticsearchIndexUtil {
@Setter(AccessLevel.PROTECTED)
private static ElasticsearchClient client;
@Setter(AccessLevel.PROTECTED)
private static Map<String, String> lifecycle;
/*
* 建立索引
* */
public static boolean createIndex(ElasticsearchIndex index, LocalDate date, Reader mapping) throws IOException {
String rollingIndex = index.getFirstIndex(date);
Map<String, Alias> aliasMap = Maps.newHashMapWithExpectedSize(2);
aliasMap.put(index.getAlias(date), Alias.of(b -> b.isWriteIndex(true)));
aliasMap.put(index.getAlias(YearMonth.from(date)), Alias.of(b -> b.isWriteIndex(false)));
CreateIndexRequest request = CreateIndexRequest.of(
a -> a.index(rollingIndex).mappings(m -> m.withJson(mapping))
.settings(setting -> setting.numberOfReplicas("1").numberOfShards("3")
.lifecycle(lc -> lc.name(lifecycle.get(index.getMainName())).rolloverAlias(index.getAlias(date))))
.aliases(aliasMap));
CreateIndexResponse response;
try {
response = client.indices().create(request);
} catch (ElasticsearchException e) {
if ("resource_already_exists_exception".equals(e.response().error().type())) {
log.info("索引已存在:{}", rollingIndex);
} else {
log.info("建立索引失敗:{}", rollingIndex, e);
}
return false;
}
return response.acknowledged();
}
}
索引建立定時任務:
@Service
@DependsOn("elasticsearchClient")
public class ElasticSearchIndexGenerator {
@PostConstruct
public void init() throws IOException {
generate(LocalDate.now());
}
@Scheduled(cron = "0 0 22 * * ?")
@ScheduledLock(1000 * 60 * 10)
protected void generate() throws IOException {
generate(LocalDate.now().plusDays(1));
}
protected void generate(LocalDate date) throws IOException {
try (InputStream inputStream = MappingUtils.getInputStream(ElasticsearchIndex.AAA.getMainName())) {
InputStreamReader mapping = new InputStreamReader(inputStream);
ElasticsearchIndexUtil.createIndex(ElasticsearchIndex.AAA, date, mapping);
}
}
}