索引CRUD
# 索引CRUD
提示
EE的索引在前面索引托管章节已有介绍,是支持自动化处理的.但仍有个别场景,用户期望自己来操作索引,也就是前面索引托管章节提到的手动挡模式, 此篇重点介绍手动挡模式下提供的所有API能力,帮助用户快速上手手动挡CRUD索引.
# 前置配置
索引CRUD相关的API都属于手动挡范畴,因此我们执行下述所有API前必须先配置开启手动挡,以免和自动挡冲突.
easy-es:
global-config:
process_index_mode: manual # 手动挡模式
1
2
3
2
3
# 创建索引
API介绍
// 1.根据当前mapper对应实体类信息及其注解配置生成索引信息 适用于大多数场景
Boolean createIndex();
// 2.根据当前mapper对应实体类信息及其注解配置生成索引信息 可指定索引名进行创建 适用于定时任务按日期创建索引场景
Boolean createIndex(String indexName);
// 3.根据自定义条件创建索引
Boolean createIndex(Wrapper<T> wrapper);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
创建索引一共提供了上述三种方式,使用难度: 方式1 <= 方式2 < 方式3 , 灵活度 方式3 > 方式2 >= 方式1
使用案例:
/**
* 方式1
*/
@Test
public void testCreateIndexByEntity() {
// 绝大多数场景推荐使用 简单至上
documentMapper.createIndex();
}
/**
* 方式2
*/
@Test
public void testCreateIndexByEntity() {
// 适用于定时任务按日期创建索引场景
String indexName = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
documentMapper.createIndex(indexName);
}
/**
* 方式3
*/
@Test
public void testCreateIndex() {
// 复杂场景使用
LambdaEsIndexWrapper<Document> wrapper = new LambdaEsIndexWrapper<>();
// 此处简单起见 索引名称须保持和实体类名称一致,字母小写 后面章节会教大家更如何灵活配置和使用索引
wrapper.indexName(Document.class.getSimpleName().toLowerCase());
// 此处将文章标题映射为keyword类型(不支持分词),文档内容映射为text类型(支持分词查询)
wrapper.mapping(Document::getTitle, FieldType.KEYWORD, 2.0f)
.mapping(Document::getLocation, FieldType.GEO_POINT)
.mapping(Document::getGeoLocation, FieldType.GEO_SHAPE)
.mapping(Document::getContent, FieldType.TEXT, Analyzer.IK_SMART, Analyzer.IK_MAX_WORD);
// 0.9.8+版本,增加对符串字段名称的支持,Document实体中须在对应字段上加上@Tablefield(value="wu-la")用于映射此字段值
wrapper.mapping("wu-la", FieldType.TEXT, Analyzer.IK_MAX_WORD, Analyzer.IK_MAX_WORD);
// 设置分片及副本信息,可缺省
wrapper.settings(3, 2);
// 设置别名信息,可缺省
String aliasName = "daily";
wrapper.createAlias(aliasName);
// 设置父子信息,若无父子文档关系则无需设置
wrapper.join("joinField", "document", "comment");
// 创建索引
boolean isOk = documentMapper.createIndex(wrapper);
Assertions.assertTrue(isOk);
}
/**
* 方式3 变体,使用难度最高,但灵活性也最高
*/
@Test
public void testCreateIndexByMap() {
// 演示通过自定义map创建索引,最为灵活 可支持es本身能支持的所有索引场景
LambdaEsIndexWrapper<Document> wrapper = new LambdaEsIndexWrapper<>();
wrapper.indexName(Document.class.getSimpleName().toLowerCase());
wrapper.settings(3, 2);
Map<String, Object> map = new HashMap<>();
Map<String, Object> prop = new HashMap<>();
Map<String, String> field = new HashMap<>();
field.put("type", FieldType.KEYWORD.getType());
prop.put("this_is_field", field);
map.put("properties", prop);
wrapper.mapping(map);
boolean isOk = documentMapper.createIndex(wrapper);
Assertions.assertTrue(isOk);
}
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# 查询索引
API介绍
// 是否存在索引
Boolean existsIndex(String indexName);
// 获取当前mapper对应索引信息
GetIndexResponse getIndex();
// 获取指定索引信息
GetIndexResponse getIndex(String indexName);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
使用案例:
@Test
public void testExistsIndex() {
// 测试是否存在指定名称的索引
String indexName = Document.class.getSimpleName().toLowerCase();
boolean existsIndex = documentMapper.existsIndex(indexName);
Assertions.assertTrue(existsIndex);
}
@Test
public void testGetIndex() {
GetIndexResponse indexResponse = documentMapper.getIndex();
// 这里打印下索引结构信息 其它分片等信息皆可从indexResponse中取
indexResponse.getMappings().forEach((k, v) -> System.out.println(v.getSourceAsMap()));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 更新索引
API介绍
// 根据条件更新索引
Boolean updateIndex(Wrapper<T> wrapper);
1
2
2
使用案例:
/**
* 更新索引
*/
@Test
public void testUpdateIndex() {
// 测试更新索引
LambdaEsIndexWrapper<Document> wrapper = new LambdaEsIndexWrapper<>();
// 指定要更新哪个索引
String indexName = Document.class.getSimpleName().toLowerCase();
wrapper.indexName(indexName);
wrapper.mapping(Document::getCreator, FieldType.KEYWORD);
wrapper.mapping(Document::getGmtCreate, FieldType.DATE);
boolean isOk = documentMapper.updateIndex(wrapper);
Assertions.assertTrue(isOk);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 删除索引
API介绍
// 删除指定索引 支持同时删多个索引,谨慎操作,后果自负,删除索引后数据也会被一起删除,类似Mysql中的删库跑路...
Boolean deleteIndex(String... indexNames);
1
2
2
使用案例:
@Test
public void testDeleteIndex() {
// 指定要删除哪个索引
String indexName = Document.class.getSimpleName().toLowerCase();
boolean isOk = documentMapper.deleteIndex(indexName);
Assertions.assertTrue(isOk);
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 更新索引
提示
ES中数据的写入是近实时的,并不像传统关系型数据库,ES的数据写入后存在一定的延迟,写完立即查询很可能查不到,具体延迟多少是需要结合机器和ES配置共同决定的,ES从内存刷数据至磁盘是一个批处理,所以存在一定延迟,如果您对数据的实时性要求比较高, 我们推荐您参考配置章节配置数据刷新策略refresh-policy,当然您也可以通过调用下面提供的两个API,来实现刷新指定索引的数据,执行后数据将从内存load至磁盘.
API介绍
// 刷新当前mapper对应索引, 返回刷新成功分片数
Integer refresh();
// 刷新指定索引列表, 返回总刷新成功分片数
Integer refresh(String... indexNames);
1
2
3
4
5
2
3
4
5
使用案例:
@Test
public void testRefresh() {
// 刷新当前mapper对应索引
int successShardsCount = documentMapper.refresh();
}
1
2
3
4
5
2
3
4
5
帮助我们改善此文档 (opens new window)
上次更新: 2024/05/18