升级Elasticsearch 8.9后用客户端创建索引遇token_chars字段错误
解决Elasticsearch 8.9客户端创建索引时的JsonpMappingException错误
报错co.elastic.clients.json.JsonpMappingException: Error deserializing co.elastic.clients.elasticsearch._types.analysis.NGramTokenFilter: Unknown field 'token_chars'的核心原因是:Elasticsearch客户端的强类型模型无法识别JSON配置中的token_chars字段——要么是客户端版本与8.9服务端不匹配,要么是使用强类型API时字段映射逻辑不一致。Kibana直接将JSON转发给服务端,跳过了客户端的模型解析校验,所以能正常创建索引。
解决方案
1. 对齐客户端与服务端版本
确保你的Elasticsearch客户端依赖版本和服务端的8.9版本完全一致。以Java客户端为例,调整Maven依赖:
<!-- Maven --> <dependency> <groupId>co.elastic.clients</groupId> <artifactId>elasticsearch-java</artifactId> <version>8.9.0</version> </dependency>
2. 发送原始JSON请求(绕过模型解析)
直接用原始JSON字符串构建请求,避免客户端对配置做反序列化校验。Java客户端示例:
String indexConfig = """ { "mappings" : { "properties": { "suggestion": { "type": "text", "fields": { "analyzed": { "type": "text", "analyzer": "nGram_analyzer", "search_analyzer": "whitespace" } } }, "weight": { "type": "integer" } } }, "settings" : { "number_of_shards": 1, "number_of_replicas": 1, "max_ngram_diff" : 20, "index": { "analysis": { "analyzer": { "nGram_analyzer": { "type": "custom", "tokenizer": "whitespace", "filter": [ "lowercase", "asciifolding", "nGram_filter" ] } }, "filter": { "nGram_filter": { "type": "ngram", "min_gram": 2, "max_gram": 20, "token_chars": [ "letter", "digit", "punctuation", "symbol" ] } } } } } } """; CreateIndexRequest request = CreateIndexRequest.of(req -> req.rawJson(indexConfig)); client.indices().create(request);
3. 使用强类型API正确配置
如果偏好强类型API,要使用客户端提供的对应方法设置token_chars(Java客户端中为tokenChars方法):
CreateIndexRequest request = CreateIndexRequest.of(req -> req .settings(settings -> settings .numberOfShards("1") .numberOfReplicas("1") .maxNgramDiff(20) .analysis(analysis -> analysis .analyzers(analyzers -> analyzers .put("nGram_analyzer", analyzer -> analyzer .custom(custom -> custom .tokenizer("whitespace") .filters("lowercase", "asciifolding", "nGram_filter") ) ) ) .filters(filters -> filters .put("nGram_filter", filter -> filter .ngram(ngram -> ngram .minGram(2) .maxGram(20) .tokenChars(Arrays.asList( TokenChar.Letter, TokenChar.Digit, TokenChar.Punctuation, TokenChar.Symbol )) ) ) ) ) ) .mappings(mappings -> mappings .properties("suggestion", prop -> prop .text(text -> text .fields(fields -> fields .put("analyzed", field -> field .text(textField -> textField .analyzer("nGram_analyzer") .searchAnalyzer("whitespace") ) ) ) ) ) .properties("weight", prop -> prop.integer(integer -> integer)) ) ); client.indices().create(request);
验证
调整后重新执行索引创建操作,即可避免该反序列化错误,通过客户端完成索引创建。
内容的提问来源于stack exchange,提问作者Rohit Gaur
相关产品推荐
相关产品推荐

