我们知道elasticsearch中的索引一旦设置了映射规则之后就不能修改了,因为lucene实现的倒排索引生成后不允许修改。但有时我们需要对旧的索引使用新的mapping映射,以支持需要的查询。
比如旧的索引有个"testText"字段,其类型为text类型。text会进行分词分析,因此对此字段进行聚合之类的操作时会出现问题,具体可以看这篇文章。那么有没有其他方式实现修改映射呢?答案是有的,但不是直接修改,而是备份旧索引,然后同步到新的索引中。
下面是简单地实现过程。
使用到的命令是_reindex
1.首先创建一个旧索引my_index,并设置字段testText的类型为text
PUT my_index
{
"mappings" : {
"my_type" : {
"properties" : {
"testText" : {
"type" : "text"
}
}
}
}
}
2.插入一条文档
POST my_index/my_type
{
"testText":"v1/v2"
}
3.因为text会进行分词,因此这时候用下面的命令精确查找“v1/v2”应该是找不到数据的
GET my_index/my_type/_search
{
"query": {
"term": {
"testText": {
"value": "v1/v2"
}
}
}
}
4.备份旧索引my_index数据到备份索引my_index_back
POST _reindex
{
"source": {"index": "my_index"},
"dest": {"index": "my_index_back"}
}
此时可以查看旧索引和备份索引,他们的数据是一样的,但备份索引的mapping有所不同,如下
{
"my_index_back": {
"mappings": {
"my_type": {
"properties": {
"testText": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
这就是说进行reindex的时候,elasticsearch默认会进行一些修改mapping的操作,但具体是什么机制还不知道,先不管。
5.接下来建立新索引my_index_new,并设置testText字段的类型为keyword
PUT my_index_new
{
"mappings" : {
"my_type" : {
"properties" : {
"testText" : {
"type" : "keyword"
}
}
}
}
}
6.将备份索引的数据迁移到新索引中
POST _reindex
{
"source": {"index": "my_index_back"},
"dest": {"index": "my_index_new"}
}
7.在新索引中查找“v1/v2”,发现可以精确查找到数据了
GET my_index_new/my_type/_search
{
"query": {
"term": {
"testText": {
"value": "v1/v2"
}
}
}
}
初步说明,数据迁移并修改映射规则成功!