You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从ElasticSearch迁移至OpenSearch时索引模板失效问题求助

Elasticsearch 7.6 迁移至 OpenSearch 2.3 索引模板不生效问题排查与解决

问题背景

我们正在将应用从Elasticsearch v7.6迁移至OpenSearch v2.3,提前在OpenSearch 2.3集群创建了如下索引模板:

{  
  "order": 0,  
  "index_patterns": [    
    "note-management-1.0-*"  
  ],  
  "settings": {    
    "index": {      
      "max_ngram_diff": "10",      
      "analysis": {        
        "filter": {          
          "ngram_filter": {            
            "type": "ngram",            
            "min_gram": "1",            
            "max_gram": "10"          
        }        
      },        
      "normalizer": {          
        "keyword_normalizer": {            
          "filter": [              
            "lowercase"            
          ],            
          "type": "custom"          
        }        
      },        
      "analyzer": {          
        "text_analyzer": {            
          "filter": [              
            "lowercase",              
            "ngram_filter"            
          ],            
          "type": "custom",            
          "tokenizer": "standard"          
        }        
      }      
    },      
    "number_of_shards": "5",      
    "number_of_replicas": "2"    
  }  
},  
"mappings": {    
  "properties": {      
    "owner": {        
      "copy_to": "permissionToView",        
      "type": "keyword"      
    },      
    "lastModifiedDate": {        
      "type": "date"      
    },      
    "contentReadOnly": {        
      "index": false,        
      "type": "boolean"      
    },      
    "lastModifiedBy": {        
      "index": false,        
      "type": "keyword"      
    },      
    "readOnly": {        
      "index": false,        
      "type": "boolean"      
    },      
    "title": {        
      "search_analyzer": "standard",        
      "analyzer": "text_analyzer",        
      "type": "text"      
    },      
    "permissionToView": {        
      "type": "keyword"      
    },      
    "version": {        
      "index": false,        
      "type": "long"      
    },      
    "content": {        
      "search_analyzer": "standard",        
      "analyzer": "text_analyzer",        
      "type": "text"      
    },      
    "tags": {        
      "normalizer": "keyword_normalizer",        
      "type": "keyword"      
    },      
    "noteType": {        
      "normalizer": "keyword_normalizer",        
      "type": "keyword"      
    },      
    "viewers": {        
      "copy_to": "permissionToView",        
      "index": false,        
      "type": "keyword"      
    },      
    "createdDate": {        
      "type": "date"      
    },      
    "externalObjects": {        
      "dynamic": false,        
      "type": "nested",        
      "properties": {          
        "displayName": {            
          "normalizer": "keyword_normalizer",            
          "type": "keyword"          
        },          
        "id": {            
          "normalizer": "keyword_normalizer",            
          "type": "keyword"          
        },          
        "type": {            
          "normalizer": "keyword_normalizer",            
          "type": "keyword"          
        },          
        "usersByPinned": {            
          "type": "keyword"          
        }        
      }      
    },      
    "deleters": {        
      "copy_to": "permissionToView",        
      "index": false,        
      "type": "keyword"      
    },      
    "id": {        
      "index": false,        
      "type": "keyword"      
    },      
    "outcome": {        
      "index": false,        
      "type": "keyword"      
    },      
    "editors": {        
      "copy_to": "permissionToView",        
      "index": false,        
      "type": "keyword"      
    }    
  }  
},  
"aliases": {    
  "note-management-1.0": {},    
  "note-management": {}  
}

当时OpenSearch中未创建note-management索引,预期应用写入首个文档时会自动匹配模板创建索引。

问题现象

应用成功创建索引和文档,但无法检索数据(OpenSearch判定查询格式有误)。删除该隐式创建的索引后,用Elasticsearch v7.6的索引定义手动创建,应用恢复正常索引和查询。

spring-boot-starter-data-elasticsearch 2.4.11自动创建的索引定义如下(不符合要求):

{  
  "note-management" : {    
    "aliases" : { },    
    "mappings" : {      
      "properties" : {        
        "_class" : {          
          "type" : "text",          
          "fields" : {            
            "keyword" : {              
              "type" : "keyword",              
              "ignore_above" : 256            
            }          
          }        
        },        
        "content" : {          
          "type" : "text",          
          "fields" : {            
            "keyword" : {              
              "type" : "keyword",              
              "ignore_above" : 256            
            }          
          }        
        },        
        "contentReadOnly" : {          
          "type" : "boolean"        
        },        
        "createdDate" : {          
          "type" : "long"        
        },        
        "editors" : {          
          "type" : "text",          
          "fields" : {            
            "keyword" : {              
              "type" : "keyword",              
              "ignore_above" : 256            
            }          
          }        
        },        
        "id" : {          
          "type" : "text",          
          "fields" : {            
            "keyword" : {              
              "type" : "keyword",              
              "ignore_above" : 256            
            }          
          }        
        },        
        "lastModifiedBy" : {          
          "type" : "text",          
          "fields" : {            
            "keyword" : {              
              "type" : "keyword",              
              "ignore_above" : 256            
            }          
          }        
        },        
        "lastModifiedDate" : {          
          "type" : "long"        
        },        
        "noteType" : {          
          "type" : "text",          
          "fields" : {            
            "keyword" : {              
              "type" : "keyword",              
              "ignore_above" : 256            
            }          
          }        
        },        
        "owner" : {          
          "type" : "text",          
          "fields" : {            
            "keyword" : {              
              "type" : "keyword",              
              "ignore_above" : 256            
            }          
          }        
        },        
        "readOnly" : {          
          "type" : "boolean"        
        },        
        "title" : {          
          "type" : "text",          
          "fields" : {            
            "keyword" : {              
              "type" : "keyword",              
              "ignore_above" : 256            
            }          
          }        
        },        
        "version" : {          
          "type" : "long"        
      }    
    }  
  },  
  "settings" : {    
    "index" : {      
      "creation_date" : "1676061494880",      
      "number_of_shards" : "1",      
      "number_of_replicas" : "1",      
      "uuid" : "udj4QFKzSLSRyo8laD7vJA",      
      "version" : {        
        "created" : "135238227"      
      },      
      "provided_name" : "note-management"    
    }  
  }  
}

手动创建的正确索引定义如下:

{  
  "note-management" : {    
    "aliases" : {  },    
    "mappings" : {      
      "properties" : {        
        "content" : {          
          "type" : "text",          
          "analyzer" : "text_analyzer",          
          "search_analyzer" : "standard"        
        },        
        "contentReadOnly" : {          
          "type" : "boolean",          
          "index" : false        
        },        
        "createdDate" : {          
          "type" : "date"        
        },        
        "deleters" : {          
          "type" : "keyword",          
          "index" : false,          
          "copy_to" : [            
            "permissionToView"          
          ]        
        },        
        "editors" : {          
          "type" : "keyword",          
          "index" : false,          
          "copy_to" : [            
            "permissionToView"          
          ]        
        },        
        "externalObjects" : {          
          "type" : "nested",          
          "dynamic" : "false",          
          "properties" : {            
            "displayName" : {              
              "type" : "keyword",              
              "normalizer" : "keyword_normalizer"            
            },            
            "id" : {              
              "type" : "keyword",              
              "normalizer" : "keyword_normalizer"            
            },            
            "type" : {              
              "type" : "keyword",              
              "normalizer" : "keyword_normalizer"            
            },            
            "usersByPinned" : {              
              "type" : "keyword"            
            }          
          }        
        },        
        "id" : {          
          "type" : "keyword",          
          "index" : false        
        },        
        "lastModifiedBy" : {          
          "type" : "keyword",          
          "index" : false        
        },        
        "lastModifiedDate" : {          
          "type" : "date"        
        },        
        "noteType" : {          
          "type" : "keyword",          
          "normalizer" : "keyword_normalizer"        
        },        
        "outcome" : {          
          "type" : "keyword",          
          "index" : false        
        },        
        "owner" : {          
          "type" : "keyword",          
          "copy_to" : [            
            "permissionToView"          
          ]        
        },        
        "permissionToView" : {          
          "type" : "keyword"        
        },        
        "readOnly" : {          
          "type" : "boolean",          
          "index" : false        
        },        
        "tags" : {          
          "type" : "keyword",          
          "normalizer" : "keyword_normalizer"        
        },        
        "title" : {          
          "type" : "text",          
          "analyzer" : "text_analyzer",          
          "search_analyzer" : "standard"        
        },        
        "version" : {          
          "type" : "long",          
          "index" : false        
        },        
        "viewers" : {          
          "type" : "keyword",          
          "index" : false,          
          "copy_to" : [            
            "permissionToView"          
          ]        
        }      
    }  
  },  
  "settings" : {    
    "index" : {      
      "number_of_shards" : "1",      
      "provided_name" : "note-management-1.0.0",      
      "creation_date" : "1676062153821",      
      "analysis" : {        
        "filter" : {          
          "ngram_filter" : {            
            "type" : "ngram",            
            "max_ngram_diff" : "10",            
            "min_ngram_diff" : "1"          
        }        
      },        
      "normalizer" : {          
        "keyword_normalizer" : {            
          "filter" : [              
            "lowercase"            
          ],            
          "type" : "custom"          
        }        
      },        
      "analyzer" : {          
        "text_analyzer" : {            
          "filter" : [              
            "lowercase",              
            "ngram_filter"            
          ],            
          "type" : "custom",            
          "tokenizer" : "standard"          
        }        
      }      
    },      
    "number_of_replicas" : "1",      
    "uuid" : "RGYrVMtvSFWrSF1GwxuWKw",      
    "version" : {        
      "created" : "135238227"      
    }    
  }  
}

原因分析

  1. 索引模板匹配规则不匹配:创建的模板index_patterns为note-management-1.0-*,但Spring Data自动创建的索引名是note-management,完全不符合通配符规则,导致模板未被应用。
  2. Spring Data Elasticsearch自动生成逻辑缺陷:2.4.11版本默认根据实体类生成映射,不会自动带上版本前缀,且生成的映射缺失关键配置:
    • 未应用模板中定义的analyzer、search_analyzer、copy_to、index: false等配置
    • 错误将date类型字段映射为long
    • 额外生成_class字段用于实体类型识别
  3. OpenSearch自动创建索引的优先级:当索引名不匹配任何模板时,OpenSearch会使用默认规则创建索引,结合Spring Data生成的映射,最终导致索引结构不符合业务要求。

解决方法

  1. 调整索引模板的匹配规则:修改模板的index_patterns,使其覆盖应用创建的索引名,例如:
    "index_patterns": ["note-management", "note-management-1.0-*"]
    
  2. 指定Spring Data的索引名称:在实体类上通过@Document(indexName = "note-management-1.0-0")指定符合模板匹配规则的索引名,确保自动创建时触发模板应用。
  3. 禁用Spring Data自动创建索引:在application.yml中添加配置:
    spring:
      data:
        elasticsearch:
          repositories:
            create-index: false
    
    提前通过模板或手动方式创建索引后,再启动应用写入数据。
  4. 升级Spring Data Elasticsearch版本:升级到2.7.x及以上版本,该版本对OpenSearch的兼容性更好,能更准确地映射实体字段并支持模板匹配。
  5. 在实体类上配置完整映射注解:为实体字段添加对应注解,确保自动生成的映射符合要求,例如:
    • @Field(type = FieldType.Keyword, index = false, copyTo = "permissionToView")
    • @Field(type = FieldType.Text, analyzer = "text_analyzer", searchAnalyzer = "standard")
    • @Field(type = FieldType.Date)

内容的提问来源于stack exchange,提问作者RohitG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:14:50