Elastichsearch使用wildcard字段模糊匹配
# Elasticsearch 使用 wildcard
字段及数据迁移的实践
# 背景
在 Elasticsearch 中,wildcard
类型是为了解决高效通配符查询的问题。为了优化性能并减少存储空间,尤其是处理大量复杂查询时,可以将原 text
类型的字段迁移到 wildcard
类型。本文记录了我们在生产环境中添加 wildcard
字段并迁移数据的实践。
# 需求分析
目标:
- 为索引
mytestindex_2024_11
和mytestindex_2024_12
添加wildcard
类型的字段mytest_info2
。 - 将
text
类型字段mytest_info
中的数据迁移到新字段mytest_info2
。 - 仅对
mytest_info2
字段为空的文档进行更新,避免重复写入。
挑战:
- 数据量大,更新操作可能影响集群性能。
- 需要确保更新操作高效且数据完整。
# 解决方案
# 1. 更新字段映射
在索引 mytestindex_2024_11
和 mytestindex_2024_12
中添加新字段 mytest_info2
,并定义为 wildcard
类型。
PUT mytestindex_2024_11/_mapping
{
"properties": {
"mytest_info2": {
"type": "wildcard"
}
}
}
PUT mytestindex_2024_12/_mapping
{
"properties": {
"mytest_info2": {
"type": "wildcard"
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 2. 数据迁移脚本
使用 _update_by_query
API 进行数据迁移,将 mytest_info
的值复制到 mytest_info2
。同时,保证只更新 mytest_info2
字段为空的文档。
脚本内容:
POST mytestindex_2024_11,mytestindex_2024_12/_update_by_query?wait_for_completion=false&slices=8
{
"script": {
"lang": "painless",
"source": "ctx._source['mytest_info2'] = ctx._source['mytest_info']"
},
"query": {
"bool": {
"must_not": [
{
"exists": {
"field": "mytest_info2"
}
}
],
"must": [
{
"exists": {
"field": "mytest_info"
}
}
]
}
}
}
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
参数解释:
wait_for_completion=false
:异步执行,避免操作超时。slices=8
:将任务分片并行执行,提高处理效率。must_not
条件:确保仅更新mytest_info2
字段为空的文档。must
条件:确保mytest_info
字段存在。
# 3. 异步任务监控
由于任务是异步执行的,需要监控其状态:
GET _tasks?detailed=true&actions=*/_update_by_query
1
通过上述命令,可以实时查看任务进度,确保迁移过程顺利完成。
# 4. 验证数据完整性
迁移完成后,可以验证迁移结果是否正确:
GET mytestindex_2024_11/_search
{
"query": {
"exists": {
"field": "mytest_info2"
}
}
}
GET mytestindex_2024_12/_search
{
"query": {
"exists": {
"field": "mytest_info2"
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 总结
通过使用 wildcard
字段和 _update_by_query
API,我们在不影响集群性能的情况下完成了数据迁移。以下是一些关键经验:
异步执行和分片更新:
- 使用
wait_for_completion=false
和slices
参数将任务分片,可以显著提高执行效率并减少集群压力。
- 使用
条件过滤:
- 通过
must_not
和must
条件,确保只更新必要的文档,避免冗余操作。
- 通过
实时监控:
- 使用
_tasks
API 监控任务进度,及时处理可能的异常情况。
- 使用
验证结果:
- 在大规模操作后,验证数据的完整性和正确性是必要的。
wildcard
类型的引入为我们带来了更高效的通配符查询能力,适用于大量复杂字符串匹配的场景。通过本文的实践,相信你也可以在自己的场景中成功应用 wildcard
字段。
上次更新: 4/24/2025