我一直在用6.4上的映射遇到相同的问题,我想知道我做错了什么。
我只是创建一个映射以在创建索引时添加到索引,但是它总是用java.lang.IllegalStateException: Failed to close the XContentBuilder
破坏我的测试
这就是我为映射创建XContentBuilder对象的方式
[更新]:发现罪魁祸首-映射缺少.endObject()
public XContentBuilder buildIndexMapping() throws IOException{
XContentBuilder mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject("_doc")
.startObject("_routing")
.field( "required", true )
.endObject()
.startObject( "properties" )
.startObject( "launchCode" )
.field( "type", "text" )
.endObject()
.startObject( "tenant_id" )
.field("type", "keyword")
.endObject()
.startObject( "environment_id" )
.field( "type", "keyword" )
.endObject()
.startObject("app_id")
.field( "type", "keyword" )
.endObject() //Culprit
.startObject( "launch_id" )
.field( "type", "keyword" )
.endObject()
.startObject( "timestamp" )
.field( "type", "date" )
.endObject()
.startObject( "data" )
.startObject( "properties" )
.startObject( "changed" )
.field( "type", "boolean" )
.endObject()
.startObject( "census_groups" )
.field( "type", "object" )
.endObject()
.startObject( "local_member_id" )
.field( "type", "keyword" )
.endObject()
.startObject( "last_service_counter" )
.field( "type", "integer" )
.endObject()
.startObject( "last_election_counter" )
.field( "type", "integer" )
.endObject()
.startObject( "last_election_update_counter" )
.field( "type", "integer" )
.endObject()
.startObject( "last_membership_counter" )
.field( "type", "integer" )
.endObject()
.startObject( "last_service_config_counter" )
.field( "type", "integer" )
.endObject()
.startObject( "last_service_file_counter" )
.field( "type", "integer" )
.endObject()
.endObject() //properties
.endObject() //data
.endObject() //properties
.endObject() //doc
.endObject(); //root
return mapping;
}
这就是我创建索引请求的方式。
public CreateIndexRequest buildIndexRequest( String indexType, List<String> tenantList ) throws IOException{
SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd" );
String date = format.format( new Date() );
String indexName = date + "-" + indexType;
CreateIndexRequest request = new CreateIndexRequest( indexName );
request.aliases( buildIndexAliases( tenantList, indexType ) );
request.settings( buildIndexSettings() );
request.mapping( "_doc", buildIndexMapping() ); //Test passes when commented out
return request;
}
这就是我创建索引的方式。
public CreateIndexResponse createIndex( CreateIndexRequest request ){
CreateIndexResponse response = null;
try{
L.info( "Requesting creation of the index" );
response = client.indices().create( request, RequestOptions.DEFAULT );
if( response.isAcknowledged() ){
L.info( "Index created" );
}
else{
L.warn( "Index not created: request not acknowledged" );
}
}
catch( IOException e ){
L.error( "Could not create Index" );
}
return response;
}
这是我的单元测试。
@Test
public void createIndexTest() {
try{
CreateIndexRequest request = client.buildIndexRequest( "census", this.tenantList );
CreateIndexResponse response = client.createIndex( request );
if (!response.isAcknowledged()) {
fail();
}
}
catch( IOException e ){
fail();
}
}
这是索引请求的主体,当通过Postman使用
PUT /index
时,该请求成功使用映射创建了索引。{
"aliases": {
"census-tenant-a": {
"filter": {
"term": {
"_routing": "tenant-a"
}
},
"index_routing": "tenant-a",
"search_routing": "tenant-a"
},
"census-tenant-b": {
"filter": {
"term": {
"_routing": "tenant-b"
}
},
"index_routing": "tenant-b",
"search_routing": "tenant-b"
},
"census-tenant-c": {
"filter": {
"term": {
"_routing": "tenant-c"
}
},
"index_routing": "tenant-c",
"search_routing": "tenant-c"
}
},
"mappings": {
"_doc": {
"_routing": {
"required": true
},
"properties": {
"launch_code": {
"type": "text"
},
"tenant_id": {
"type": "keyword"
},
"environment_id": {
"type": "keyword"
},
"app_id": {
"type": "keyword"
},
"launch_id": {
"type": "keyword"
},
"timestamp": {
"type": "date"
},
"data": {
"properties": {
"changed": {
"type": "boolean"
},
"census_groups": {
"type": "object"
},
"local_member_id": {
"type": "keyword"
},
"last_service_counter": {
"type": "integer"
},
"last_election_counter": {
"type": "integer"
},
"last_election_update_counter": {
"type": "integer"
},
"last_membership_counter": {
"type": "integer"
},
"last_service_config_counter": {
"type": "integer"
},
"last_service_file_counter": {
"type": "integer"
}
}
}
}
}
},
"settings": {
"index": {
"number_of_shards": "3",
"number_of_replicas": "1"
}
}
}
我真的不明白发生了什么。我知道
XContentBuilder
在使用后应该关闭以避免内存泄漏。但是,我想先创建索引,然后再处理资源关闭。
我使用相同的逻辑来创建别名和设置,但仅不适用于映射。
此外,如上所述,当我将Index API与
XContentBuilder
一起使用时,PUT /index
的JSON表示成功。谢谢!
最佳答案
您可能要结束以“app_id”开头的对象:
startObject(“app_id”)