使用OpenSearch Java客户端创建索引时遇未知配置错误求助
问题:OpenSearch Java客户端创建索引时出现未知配置错误
索引配置JSON
{ "settings": { "index": { "analysis": { "analyzer": { "my_synonym_analyzer": { "type": "custom", "tokenizer": "whitespace", "filter": [ "my_synonym_filter" ] } }, "filter": { "my_synonym_filter": { "type": "synonym_graph", "synonyms": [] } } } } } }
Java创建索引代码
import jakarta.json.stream.JsonParser; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.util.Objects; import lombok.extern.slf4j.Slf4j; import org.opensearch.client.json.JsonpMapper; import org.opensearch.client.opensearch.OpenSearchClient; import org.opensearch.client.opensearch._types.mapping.TypeMapping; import org.opensearch.client.opensearch.indices.CreateIndexRequest; import org.opensearch.client.opensearch.indices.CreateIndexResponse; import org.opensearch.client.opensearch.indices.IndexSettings; import org.opensearch.common.io.Streams; import org.springframework.beans.factory.annotation.Autowired; public class IndexManager { @Autowired private OpenSearchClient searchClient; protected void create() throws IOException { if (this.indexExists()) { this.delete(); } JsonpMapper mapper = searchClient._transport().jsonpMapper(); try (Reader readerSettings = new InputStreamReader( Objects.requireNonNull( this.getClass() .getResourceAsStream("testindex-index-settings.json"))); Reader readerMappings = new InputStreamReader( Objects.requireNonNull( this.getClass() .getResourceAsStream("testindex-index-mappings.json"))); JsonParser settingsParser = mapper .jsonProvider() .createParser(new StringReader(Streams.copyToString(readerSettings))); JsonParser mappingsParser = mapper .jsonProvider() .createParser(new StringReader(Streams.copyToString(readerMappings))); ) { String indexName = "testindex"; IndexSettings indexSettings = IndexSettings._DESERIALIZER.deserialize(settingsParser, mapper); TypeMapping typeMapping = TypeMapping._DESERIALIZER.deserialize(mappingsParser, mapper); CreateIndexRequest indexRequest = new CreateIndexRequest.Builder() .index(indexName) .settings(indexSettings) .mappings(typeMapping) .build(); CreateIndexResponse indexResponse = searchClient.indices().create(indexRequest); // line 93 log.info("Index {} created with response [{}]", indexName, indexResponse.toString()); } } }
报错信息
org.opensearch.client.opensearch._types.OpenSearchException: Request failed: [illegal_argument_exception] unknown setting [index.settings.analysis.analyzer.my_synonym_analyzer.filter] please check that any required plugins are installed, or check the breaking changes documentation for removed settings at org.opensearch.client.transport.rest_client.RestClientTransport.getHighLevelResponse(RestClientTransport.java:273) ~[opensearch-java-2.4.0.jar:na] at org.opensearch.client.transport.rest_client.RestClientTransport.performRequest(RestClientTransport.java:143) ~[opensearch-java-2.4.0.jar:na] at org.opensearch.client.opensearch.indices.OpenSearchIndicesClient.create(OpenSearchIndicesClient.java:248) ~[opensearch-java-2.4.0.jar:na] at com.joinhobnob.crm.service.search.command.IndexManager.create(IndexManager.java:93) ~[main/:na]
curl创建成功案例
curl -XPUT "http://opensearch:9200/test_index?pretty" -H 'Content-Type: application/json' -d' { "settings": { "index": { "analysis": { "analyzer": { "my_synonym_analyzer": { "type": "custom", "tokenizer": "whitespace", "filter": [ "my_synonym_filter" ] } }, "filter": { "my_synonym_filter": { "type": "synonym_graph", "synonyms": [] } } } } } }'
响应:
{ "acknowledged": true, "shards_acknowledged": true, "index": "test_index" }
解决方案
问题根源在于Java客户端的IndexSettings类反序列化逻辑:它对应OpenSearch索引配置中index.settings层级的内容,但你的JSON配置把analysis放在了settings.index下,反序列化后导致发送给OpenSearch的请求多嵌套了一层settings,路径变成index.settings.analysis...,而OpenSearch期望的是index.analysis...,因此抛出未知配置错误。
提供两种解决方式:
方式一:修改JSON配置文件
移除JSON中多余的index层级,让analysis直接放在settings下:
{ "analysis": { "analyzer": { "my_synonym_analyzer": { "type": "custom", "tokenizer": "whitespace", "filter": [ "my_synonym_filter" ] } }, "filter": { "my_synonym_filter": { "type": "synonym_graph", "synonyms": [] } } } }
这样IndexSettings反序列化后就能正确匹配OpenSearch的配置结构。
方式二:直接使用JSON字符串构建请求
绕开IndexSettings和TypeMapping的反序列化,直接将配置文件内容以字符串形式传入请求,和curl发送的内容保持完全一致:
修改Java代码中的请求构建部分:
// 读取配置文件为字符串 String settingsStr = Streams.copyToString(readerSettings); String mappingsStr = Streams.copyToString(readerMappings); String indexName = "testindex"; CreateIndexRequest indexRequest = new CreateIndexRequest.Builder() .index(indexName) .settings(settingsStr, JsonpMapper.DEFAULT) // 直接传入JSON字符串 .mappings(mappingsStr, JsonpMapper.DEFAULT) .build(); CreateIndexResponse indexResponse = searchClient.indices().create(indexRequest);
这种方式不需要修改原JSON配置,直接复用现有文件即可。
内容的提问来源于stack exchange,提问作者Sabu Shakya
相关产品推荐
相关产品推荐

