ElasticSearch动态索引名称
ElasticSearch动态索引名称
cmyang1. 需求背景
在使用springframework.data.elasticsearch时,@Document指定的索引名称indexName,都是固定的,但是有些需求,需要动态生成不同的索引名称,但是索引的映射是相同的。
2. 解决方案
3. 代码实现
创建动态索引的类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59package com.xxx.web.cloud.bot.es.config;
import cn.hutool.core.util.StrUtil;
import com.xxx.web.cloud.bot.enums.EnvironmentEnum;
import com.xxx.web.cloud.bot.util.CustomConstant;
/**
* ES动态索引
* @author iseven.yang
* @date 2023/10/9 10:37
*/
public class DynamicIndex {
private static final ThreadLocal<String> THREAD_LOCAL = new ThreadLocal<>();
/**
* 设置当前机器人id,索引名必须是小写
* @param botId
*/
public static void setIndexName(String indexName) {
THREAD_LOCAL.set(indexName);
}
/**
* 获取当前机器人id
* @return
*/
public static String getIndexName() {
return THREAD_LOCAL.get();
}
/**
* 移除变量
*/
public static void remove() {
THREAD_LOCAL.remove();
}
/**
* 获取意图索引名称
* @param environmentEnum
* @param botId
* @return
*/
public static String getIntentIndexName(EnvironmentEnum environmentEnum, Long botId) {
return CustomConstant.INDEX_INTENT_PREFIX + environmentEnum.name().toLowerCase() + StrUtil.UNDERLINE + botId;
}
/**
* 获取问题索引名称
* @param environmentEnum
* @param botId
* @return
*/
public static String getQuestionIndexName(EnvironmentEnum environmentEnum, Long botId) {
return CustomConstant.INDEX_QUESTION_PREFIX + environmentEnum.name().toLowerCase() + StrUtil.UNDERLINE + botId;
}
}创建Document
- createIndex = false,不能自动创建索引
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23package com.xxx.web.cloud.bot.es.doc;
import lombok.Data;
import org.springframework.data.annotation.Id;
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.Score;
/**
* 问题对象
* @author iseven.yang
* @date 2023/10/8 19:03
*/
public class QuestionDOC {
...
}创建索引
- elasticsearchRestTemplate.createIndex创建索引不会自动创建映射Mapping
- 创建完索引之后要再创建一下映射elasticsearchRestTemplate.putMapping
1
2
3
4
5
6
7
8
9
10
11
12
13try {
String questionIndexName = DynamicIndex.getQuestionIndexName(env, botId);
DynamicIndex.setIndexName(questionIndexName);
if (elasticsearchRestTemplate.indexExists(questionIndexName)) {
questionEsDao.deleteAll();
} else {
elasticsearchRestTemplate.createIndex(QuestionDOC.class);
elasticsearchRestTemplate.putMapping(QuestionDOC.class);
}
questionEsDao.saveAll(questionDOCS);
} finally {
DynamicIndex.remove();
}使用
- DynamicIndex.setIndexName(questionIndex);先设置当前索引名称
- 操作完索引之后,需要清除线程本地变量DynamicIndex.remove();
1
2
3
4
5
6
7
8try {
DynamicIndex.setIndexName(questionIndex);
for (Long faqId : faqIds) {
questionEsDao.deleteByIntentId(faqId);
}
} finally {
DynamicIndex.remove();
}