我一直在用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”)

07-28 07:39