Add get field mappings to High Level REST API Client (#31423)
Add get field mappings to High Level REST API Client Relates to #27205
This commit is contained in:
parent
b6cc6fc2bc
commit
b7ef75fed6
|
@ -37,6 +37,8 @@ import org.elasticsearch.action.admin.indices.flush.SyncedFlushRequest;
|
||||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
||||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse;
|
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse;
|
||||||
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
||||||
|
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest;
|
||||||
|
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
|
||||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
||||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
||||||
|
@ -188,6 +190,35 @@ public final class IndicesClient {
|
||||||
GetMappingsResponse::fromXContent, listener, emptySet());
|
GetMappingsResponse::fromXContent, listener, emptySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the field mappings on an index or indices using the Get Field Mapping API.
|
||||||
|
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-get-field-mapping.html">
|
||||||
|
* Get Field Mapping API on elastic.co</a>
|
||||||
|
* @param getFieldMappingsRequest the request
|
||||||
|
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
|
||||||
|
* @return the response
|
||||||
|
* @throws IOException in case there is a problem sending the request or parsing back the response
|
||||||
|
*/
|
||||||
|
public GetFieldMappingsResponse getFieldMapping(GetFieldMappingsRequest getFieldMappingsRequest,
|
||||||
|
RequestOptions options) throws IOException {
|
||||||
|
return restHighLevelClient.performRequestAndParseEntity(getFieldMappingsRequest, RequestConverters::getFieldMapping, options,
|
||||||
|
GetFieldMappingsResponse::fromXContent, emptySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronously retrieves the field mappings on an index on indices using the Get Field Mapping API.
|
||||||
|
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-get-field-mapping.html">
|
||||||
|
* Get Field Mapping API on elastic.co</a>
|
||||||
|
* @param getFieldMappingsRequest the request
|
||||||
|
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
|
||||||
|
* @param listener the listener to be notified upon request completion
|
||||||
|
*/
|
||||||
|
public void getFieldMappingAsync(GetFieldMappingsRequest getFieldMappingsRequest, RequestOptions options,
|
||||||
|
ActionListener<GetFieldMappingsResponse> listener) {
|
||||||
|
restHighLevelClient.performRequestAsyncAndParseEntity(getFieldMappingsRequest, RequestConverters::getFieldMapping, options,
|
||||||
|
GetFieldMappingsResponse::fromXContent, listener, emptySet());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates aliases using the Index Aliases API.
|
* Updates aliases using the Index Aliases API.
|
||||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html">
|
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html">
|
||||||
|
|
|
@ -50,6 +50,7 @@ import org.elasticsearch.action.admin.indices.flush.FlushRequest;
|
||||||
import org.elasticsearch.action.admin.indices.flush.SyncedFlushRequest;
|
import org.elasticsearch.action.admin.indices.flush.SyncedFlushRequest;
|
||||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
||||||
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
||||||
|
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest;
|
||||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
||||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
||||||
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
|
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
|
||||||
|
@ -230,6 +231,25 @@ final class RequestConverters {
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Request getFieldMapping(GetFieldMappingsRequest getFieldMappingsRequest) throws IOException {
|
||||||
|
String[] indices = getFieldMappingsRequest.indices() == null ? Strings.EMPTY_ARRAY : getFieldMappingsRequest.indices();
|
||||||
|
String[] types = getFieldMappingsRequest.types() == null ? Strings.EMPTY_ARRAY : getFieldMappingsRequest.types();
|
||||||
|
String[] fields = getFieldMappingsRequest.fields() == null ? Strings.EMPTY_ARRAY : getFieldMappingsRequest.fields();
|
||||||
|
|
||||||
|
String endpoint = new EndpointBuilder().addCommaSeparatedPathParts(indices)
|
||||||
|
.addPathPartAsIs("_mapping").addCommaSeparatedPathParts(types)
|
||||||
|
.addPathPartAsIs("field").addCommaSeparatedPathParts(fields)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Request request = new Request(HttpGet.METHOD_NAME, endpoint);
|
||||||
|
|
||||||
|
Params parameters = new Params(request);
|
||||||
|
parameters.withIndicesOptions(getFieldMappingsRequest.indicesOptions());
|
||||||
|
parameters.withIncludeDefaults(getFieldMappingsRequest.includeDefaults());
|
||||||
|
parameters.withLocal(getFieldMappingsRequest.local());
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
static Request refresh(RefreshRequest refreshRequest) {
|
static Request refresh(RefreshRequest refreshRequest) {
|
||||||
String[] indices = refreshRequest.indices() == null ? Strings.EMPTY_ARRAY : refreshRequest.indices();
|
String[] indices = refreshRequest.indices() == null ? Strings.EMPTY_ARRAY : refreshRequest.indices();
|
||||||
Request request = new Request(HttpPost.METHOD_NAME, endpoint(indices, "_refresh"));
|
Request request = new Request(HttpPost.METHOD_NAME, endpoint(indices, "_refresh"));
|
||||||
|
|
|
@ -43,6 +43,8 @@ import org.elasticsearch.action.admin.indices.flush.SyncedFlushRequest;
|
||||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
||||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse;
|
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse;
|
||||||
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
||||||
|
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest;
|
||||||
|
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
|
||||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
||||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
||||||
|
@ -74,6 +76,7 @@ import org.elasticsearch.cluster.metadata.AliasMetaData;
|
||||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||||
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
|
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
|
||||||
import org.elasticsearch.common.ValidationException;
|
import org.elasticsearch.common.ValidationException;
|
||||||
|
import org.elasticsearch.common.bytes.BytesArray;
|
||||||
import org.elasticsearch.common.settings.Setting;
|
import org.elasticsearch.common.settings.Setting;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.unit.ByteSizeUnit;
|
import org.elasticsearch.common.unit.ByteSizeUnit;
|
||||||
|
@ -378,6 +381,41 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
|
||||||
assertThat(mappings, equalTo(expected));
|
assertThat(mappings, equalTo(expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testGetFieldMapping() throws IOException {
|
||||||
|
String indexName = "test";
|
||||||
|
createIndex(indexName, Settings.EMPTY);
|
||||||
|
|
||||||
|
PutMappingRequest putMappingRequest = new PutMappingRequest(indexName);
|
||||||
|
putMappingRequest.type("_doc");
|
||||||
|
XContentBuilder mappingBuilder = JsonXContent.contentBuilder();
|
||||||
|
mappingBuilder.startObject().startObject("properties").startObject("field");
|
||||||
|
mappingBuilder.field("type", "text");
|
||||||
|
mappingBuilder.endObject().endObject().endObject();
|
||||||
|
putMappingRequest.source(mappingBuilder);
|
||||||
|
|
||||||
|
PutMappingResponse putMappingResponse =
|
||||||
|
execute(putMappingRequest, highLevelClient().indices()::putMapping, highLevelClient().indices()::putMappingAsync);
|
||||||
|
assertTrue(putMappingResponse.isAcknowledged());
|
||||||
|
|
||||||
|
GetFieldMappingsRequest getFieldMappingsRequest = new GetFieldMappingsRequest()
|
||||||
|
.indices(indexName)
|
||||||
|
.types("_doc")
|
||||||
|
.fields("field");
|
||||||
|
|
||||||
|
GetFieldMappingsResponse getFieldMappingsResponse =
|
||||||
|
execute(getFieldMappingsRequest,
|
||||||
|
highLevelClient().indices()::getFieldMapping,
|
||||||
|
highLevelClient().indices()::getFieldMappingAsync);
|
||||||
|
|
||||||
|
final Map<String, GetFieldMappingsResponse.FieldMappingMetaData> fieldMappingMap =
|
||||||
|
getFieldMappingsResponse.mappings().get(indexName).get("_doc");
|
||||||
|
|
||||||
|
final GetFieldMappingsResponse.FieldMappingMetaData metaData =
|
||||||
|
new GetFieldMappingsResponse.FieldMappingMetaData("field",
|
||||||
|
new BytesArray("{\"field\":{\"type\":\"text\"}}"));
|
||||||
|
assertThat(fieldMappingMap, equalTo(Collections.singletonMap("field", metaData)));
|
||||||
|
}
|
||||||
|
|
||||||
public void testDeleteIndex() throws IOException {
|
public void testDeleteIndex() throws IOException {
|
||||||
{
|
{
|
||||||
// Delete index if exists
|
// Delete index if exists
|
||||||
|
|
|
@ -52,6 +52,7 @@ import org.elasticsearch.action.admin.indices.flush.FlushRequest;
|
||||||
import org.elasticsearch.action.admin.indices.flush.SyncedFlushRequest;
|
import org.elasticsearch.action.admin.indices.flush.SyncedFlushRequest;
|
||||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
||||||
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
||||||
|
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest;
|
||||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
||||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
||||||
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
|
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
|
||||||
|
@ -457,6 +458,61 @@ public class RequestConvertersTests extends ESTestCase {
|
||||||
assertThat(HttpGet.METHOD_NAME, equalTo(request.getMethod()));
|
assertThat(HttpGet.METHOD_NAME, equalTo(request.getMethod()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testGetFieldMapping() throws IOException {
|
||||||
|
GetFieldMappingsRequest getFieldMappingsRequest = new GetFieldMappingsRequest();
|
||||||
|
|
||||||
|
String[] indices = Strings.EMPTY_ARRAY;
|
||||||
|
if (randomBoolean()) {
|
||||||
|
indices = randomIndicesNames(0, 5);
|
||||||
|
getFieldMappingsRequest.indices(indices);
|
||||||
|
} else if (randomBoolean()) {
|
||||||
|
getFieldMappingsRequest.indices((String[]) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
String type = null;
|
||||||
|
if (randomBoolean()) {
|
||||||
|
type = randomAlphaOfLengthBetween(3, 10);
|
||||||
|
getFieldMappingsRequest.types(type);
|
||||||
|
} else if (randomBoolean()) {
|
||||||
|
getFieldMappingsRequest.types((String[]) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] fields = null;
|
||||||
|
if (randomBoolean()) {
|
||||||
|
fields = new String[randomIntBetween(1, 5)];
|
||||||
|
for (int i = 0; i < fields.length; i++) {
|
||||||
|
fields[i] = randomAlphaOfLengthBetween(3, 10);
|
||||||
|
}
|
||||||
|
getFieldMappingsRequest.fields(fields);
|
||||||
|
} else if (randomBoolean()) {
|
||||||
|
getFieldMappingsRequest.fields((String[]) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> expectedParams = new HashMap<>();
|
||||||
|
|
||||||
|
setRandomIndicesOptions(getFieldMappingsRequest::indicesOptions, getFieldMappingsRequest::indicesOptions, expectedParams);
|
||||||
|
setRandomLocal(getFieldMappingsRequest::local, expectedParams);
|
||||||
|
|
||||||
|
Request request = RequestConverters.getFieldMapping(getFieldMappingsRequest);
|
||||||
|
StringJoiner endpoint = new StringJoiner("/", "/", "");
|
||||||
|
String index = String.join(",", indices);
|
||||||
|
if (Strings.hasLength(index)) {
|
||||||
|
endpoint.add(index);
|
||||||
|
}
|
||||||
|
endpoint.add("_mapping");
|
||||||
|
if (type != null) {
|
||||||
|
endpoint.add(type);
|
||||||
|
}
|
||||||
|
endpoint.add("field");
|
||||||
|
if (fields != null) {
|
||||||
|
endpoint.add(String.join(",", fields));
|
||||||
|
}
|
||||||
|
assertThat(endpoint.toString(), equalTo(request.getEndpoint()));
|
||||||
|
|
||||||
|
assertThat(expectedParams, equalTo(request.getParameters()));
|
||||||
|
assertThat(HttpGet.METHOD_NAME, equalTo(request.getMethod()));
|
||||||
|
}
|
||||||
|
|
||||||
public void testDeleteIndex() {
|
public void testDeleteIndex() {
|
||||||
String[] indices = randomIndicesNames(0, 5);
|
String[] indices = randomIndicesNames(0, 5);
|
||||||
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indices);
|
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indices);
|
||||||
|
@ -2268,16 +2324,20 @@ public class RequestConvertersTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setRandomLocal(MasterNodeReadRequest<?> request, Map<String, String> expectedParams) {
|
private static void setRandomLocal(Consumer<Boolean> setter, Map<String, String> expectedParams) {
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
boolean local = randomBoolean();
|
boolean local = randomBoolean();
|
||||||
request.local(local);
|
setter.accept(local);
|
||||||
if (local) {
|
if (local) {
|
||||||
expectedParams.put("local", String.valueOf(local));
|
expectedParams.put("local", String.valueOf(local));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void setRandomLocal(MasterNodeReadRequest<?> request, Map<String, String> expectedParams) {
|
||||||
|
setRandomLocal(request::local, expectedParams);
|
||||||
|
}
|
||||||
|
|
||||||
private static void setRandomTimeout(Consumer<String> setter, TimeValue defaultTimeout, Map<String, String> expectedParams) {
|
private static void setRandomTimeout(Consumer<String> setter, TimeValue defaultTimeout, Map<String, String> expectedParams) {
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
String timeout = randomTimeValue();
|
String timeout = randomTimeValue();
|
||||||
|
|
|
@ -41,6 +41,8 @@ import org.elasticsearch.action.admin.indices.flush.SyncedFlushRequest;
|
||||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
||||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse;
|
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse;
|
||||||
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
||||||
|
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest;
|
||||||
|
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
|
||||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
||||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
|
||||||
|
@ -703,6 +705,110 @@ public class IndicesClientDocumentationIT extends ESRestHighLevelClientTestCase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testGetFieldMapping() throws IOException, InterruptedException {
|
||||||
|
RestHighLevelClient client = highLevelClient();
|
||||||
|
|
||||||
|
{
|
||||||
|
CreateIndexResponse createIndexResponse = client.indices().create(new CreateIndexRequest("twitter"), RequestOptions.DEFAULT);
|
||||||
|
assertTrue(createIndexResponse.isAcknowledged());
|
||||||
|
PutMappingRequest request = new PutMappingRequest("twitter");
|
||||||
|
request.type("tweet");
|
||||||
|
request.source(
|
||||||
|
"{\n" +
|
||||||
|
" \"properties\": {\n" +
|
||||||
|
" \"message\": {\n" +
|
||||||
|
" \"type\": \"text\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"timestamp\": {\n" +
|
||||||
|
" \"type\": \"date\"\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}", // <1>
|
||||||
|
XContentType.JSON);
|
||||||
|
PutMappingResponse putMappingResponse = client.indices().putMapping(request, RequestOptions.DEFAULT);
|
||||||
|
assertTrue(putMappingResponse.isAcknowledged());
|
||||||
|
}
|
||||||
|
|
||||||
|
// tag::get-field-mapping-request
|
||||||
|
GetFieldMappingsRequest request = new GetFieldMappingsRequest(); // <1>
|
||||||
|
request.indices("twitter"); // <2>
|
||||||
|
request.types("tweet"); // <3>
|
||||||
|
request.fields("message", "timestamp"); // <4>
|
||||||
|
// end::get-field-mapping-request
|
||||||
|
|
||||||
|
// tag::get-field-mapping-request-indicesOptions
|
||||||
|
request.indicesOptions(IndicesOptions.lenientExpandOpen()); // <1>
|
||||||
|
// end::get-field-mapping-request-indicesOptions
|
||||||
|
|
||||||
|
// tag::get-field-mapping-request-local
|
||||||
|
request.local(true); // <1>
|
||||||
|
// end::get-field-mapping-request-local
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
// tag::get-field-mapping-execute
|
||||||
|
GetFieldMappingsResponse response =
|
||||||
|
client.indices().getFieldMapping(request, RequestOptions.DEFAULT);
|
||||||
|
// end::get-field-mapping-execute
|
||||||
|
|
||||||
|
// tag::get-field-mapping-response
|
||||||
|
final Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetaData>>> mappings =
|
||||||
|
response.mappings();// <1>
|
||||||
|
final Map<String, GetFieldMappingsResponse.FieldMappingMetaData> typeMappings =
|
||||||
|
mappings.get("twitter").get("tweet"); // <2>
|
||||||
|
final GetFieldMappingsResponse.FieldMappingMetaData metaData =
|
||||||
|
typeMappings.get("message");// <3>
|
||||||
|
|
||||||
|
final String fullName = metaData.fullName();// <4>
|
||||||
|
final Map<String, Object> source = metaData.sourceAsMap(); // <5>
|
||||||
|
// end::get-field-mapping-response
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// tag::get-field-mapping-execute-listener
|
||||||
|
ActionListener<GetFieldMappingsResponse> listener =
|
||||||
|
new ActionListener<GetFieldMappingsResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(GetFieldMappingsResponse putMappingResponse) {
|
||||||
|
// <1>
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Exception e) {
|
||||||
|
// <2>
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// end::get-field-mapping-execute-listener
|
||||||
|
|
||||||
|
// Replace the empty listener by a blocking listener in test
|
||||||
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
final ActionListener<GetFieldMappingsResponse> latchListener = new LatchedActionListener<>(listener, latch);
|
||||||
|
listener = ActionListener.wrap(r -> {
|
||||||
|
final Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetaData>>> mappings =
|
||||||
|
r.mappings();
|
||||||
|
final Map<String, GetFieldMappingsResponse.FieldMappingMetaData> typeMappings =
|
||||||
|
mappings.get("twitter").get("tweet");
|
||||||
|
final GetFieldMappingsResponse.FieldMappingMetaData metaData1 = typeMappings.get("message");
|
||||||
|
|
||||||
|
final String fullName = metaData1.fullName();
|
||||||
|
final Map<String, Object> source = metaData1.sourceAsMap();
|
||||||
|
latchListener.onResponse(r);
|
||||||
|
}, e -> {
|
||||||
|
latchListener.onFailure(e);
|
||||||
|
fail("should not fail");
|
||||||
|
});
|
||||||
|
|
||||||
|
// tag::get-field-mapping-execute-async
|
||||||
|
client.indices().getFieldMappingAsync(request, RequestOptions.DEFAULT, listener); // <1>
|
||||||
|
// end::get-field-mapping-execute-async
|
||||||
|
|
||||||
|
assertTrue(latch.await(30L, TimeUnit.SECONDS));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testOpenIndex() throws Exception {
|
public void testOpenIndex() throws Exception {
|
||||||
RestHighLevelClient client = highLevelClient();
|
RestHighLevelClient client = highLevelClient();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
[[java-rest-high-get-field-mappings]]
|
||||||
|
=== Get Field Mappings API
|
||||||
|
|
||||||
|
[[java-rest-high-get-field-mappings-request]]
|
||||||
|
==== Get Field Mappings Request
|
||||||
|
|
||||||
|
A `GetFieldMappingsRequest` can have an optional list of indices, optional list of types and the list of fields:
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-field-mapping-request]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> An empty request
|
||||||
|
<2> Setting the indices to fetch mapping for
|
||||||
|
<3> The types to be returned
|
||||||
|
<4> The fields to be returned
|
||||||
|
|
||||||
|
==== Optional arguments
|
||||||
|
The following arguments can also optionally be provided:
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-field-mapping-request-indicesOptions]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> Setting `IndicesOptions` controls how unavailable indices are resolved and
|
||||||
|
how wildcard expressions are expanded
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-field-mapping-request-local]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> The `local` flag (defaults to `false`) controls whether the aliases need
|
||||||
|
to be looked up in the local cluster state or in the cluster state held by
|
||||||
|
the elected master node
|
||||||
|
|
||||||
|
[[java-rest-high-get-field-mappings-sync]]
|
||||||
|
==== Synchronous Execution
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-field-mapping-execute]
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
[[java-rest-high-get-field-mapping-async]]
|
||||||
|
==== Asynchronous Execution
|
||||||
|
|
||||||
|
The asynchronous execution of a get mappings request requires both the
|
||||||
|
`GetFieldMappingsRequest` instance and an `ActionListener` instance to be passed to
|
||||||
|
the asynchronous method:
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-field-mapping-execute-async]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> The `GetFieldMappingsRequest` to execute and the `ActionListener` to use when the execution completes
|
||||||
|
|
||||||
|
The asynchronous method does not block and returns immediately. Once it is
|
||||||
|
completed the `ActionListener` is called back using the `onResponse` method if
|
||||||
|
the execution successfully completed or using the `onFailure` method if it
|
||||||
|
failed.
|
||||||
|
|
||||||
|
A typical listener for `GetMappingsResponse` looks like:
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-field-mapping-execute-listener]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> Called when the execution is successfully completed. The response is provided as an argument
|
||||||
|
<2> Called in case of failure. The raised exception is provided as an argument
|
||||||
|
|
||||||
|
[[java-rest-high-get-field-mapping-response]]
|
||||||
|
==== Get Field Mappings Response
|
||||||
|
|
||||||
|
The returned `GetFieldMappingsResponse` allows to retrieve information about the
|
||||||
|
executed operation as follows:
|
||||||
|
|
||||||
|
["source","java",subs="attributes,callouts,macros"]
|
||||||
|
--------------------------------------------------
|
||||||
|
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-field-mapping-response]
|
||||||
|
--------------------------------------------------
|
||||||
|
<1> Returning all requested indices fields' mappings
|
||||||
|
<2> Retrieving the mappings for a particular index and type
|
||||||
|
<3> Getting the mappings metadata for the `message` field
|
||||||
|
<4> Getting the full name of the field
|
||||||
|
<5> Getting the mapping source of the field
|
||||||
|
|
|
@ -77,6 +77,7 @@ Index Management::
|
||||||
|
|
||||||
Mapping Management::
|
Mapping Management::
|
||||||
* <<java-rest-high-put-mapping>>
|
* <<java-rest-high-put-mapping>>
|
||||||
|
* <<java-rest-high-get-field-mappings>>
|
||||||
|
|
||||||
Alias Management::
|
Alias Management::
|
||||||
* <<java-rest-high-update-aliases>>
|
* <<java-rest-high-update-aliases>>
|
||||||
|
@ -98,6 +99,7 @@ include::indices/force_merge.asciidoc[]
|
||||||
include::indices/rollover.asciidoc[]
|
include::indices/rollover.asciidoc[]
|
||||||
include::indices/put_mapping.asciidoc[]
|
include::indices/put_mapping.asciidoc[]
|
||||||
include::indices/get_mappings.asciidoc[]
|
include::indices/get_mappings.asciidoc[]
|
||||||
|
include::indices/get_field_mappings.asciidoc[]
|
||||||
include::indices/update_aliases.asciidoc[]
|
include::indices/update_aliases.asciidoc[]
|
||||||
include::indices/exists_alias.asciidoc[]
|
include::indices/exists_alias.asciidoc[]
|
||||||
include::indices/get_alias.asciidoc[]
|
include::indices/get_alias.asciidoc[]
|
||||||
|
|
|
@ -20,13 +20,17 @@
|
||||||
package org.elasticsearch.action.admin.indices.mapping.get;
|
package org.elasticsearch.action.admin.indices.mapping.get;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionResponse;
|
import org.elasticsearch.action.ActionResponse;
|
||||||
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.bytes.BytesArray;
|
import org.elasticsearch.common.bytes.BytesArray;
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||||
|
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||||
import org.elasticsearch.common.xcontent.ToXContentFragment;
|
import org.elasticsearch.common.xcontent.ToXContentFragment;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.common.xcontent.XContentType;
|
import org.elasticsearch.common.xcontent.XContentType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
|
|
||||||
|
@ -34,13 +38,45 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import static java.util.Collections.emptyMap;
|
import static java.util.Collections.emptyMap;
|
||||||
import static java.util.Collections.unmodifiableMap;
|
import static java.util.Collections.unmodifiableMap;
|
||||||
|
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg;
|
||||||
|
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||||
|
import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken;
|
||||||
|
|
||||||
/** Response object for {@link GetFieldMappingsRequest} API */
|
/** Response object for {@link GetFieldMappingsRequest} API */
|
||||||
public class GetFieldMappingsResponse extends ActionResponse implements ToXContentFragment {
|
public class GetFieldMappingsResponse extends ActionResponse implements ToXContentFragment {
|
||||||
|
|
||||||
|
private static final ParseField MAPPINGS = new ParseField("mappings");
|
||||||
|
|
||||||
|
private static final ObjectParser<Map<String, Map<String, FieldMappingMetaData>>, String> PARSER =
|
||||||
|
new ObjectParser<>(MAPPINGS.getPreferredName(), true, HashMap::new);
|
||||||
|
|
||||||
|
static {
|
||||||
|
PARSER.declareField((p, typeMappings, index) -> {
|
||||||
|
p.nextToken();
|
||||||
|
while (p.currentToken() == XContentParser.Token.FIELD_NAME) {
|
||||||
|
final String typeName = p.currentName();
|
||||||
|
|
||||||
|
if (p.nextToken() == XContentParser.Token.START_OBJECT) {
|
||||||
|
final Map<String, FieldMappingMetaData> typeMapping = new HashMap<>();
|
||||||
|
typeMappings.put(typeName, typeMapping);
|
||||||
|
|
||||||
|
while (p.nextToken() == XContentParser.Token.FIELD_NAME) {
|
||||||
|
final String fieldName = p.currentName();
|
||||||
|
final FieldMappingMetaData fieldMappingMetaData = FieldMappingMetaData.fromXContent(p);
|
||||||
|
typeMapping.put(fieldName, fieldMappingMetaData);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p.skipChildren();
|
||||||
|
}
|
||||||
|
p.nextToken();
|
||||||
|
}
|
||||||
|
}, MAPPINGS, ObjectParser.ValueType.OBJECT);
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, Map<String, Map<String, FieldMappingMetaData>>> mappings = emptyMap();
|
private Map<String, Map<String, Map<String, FieldMappingMetaData>>> mappings = emptyMap();
|
||||||
|
|
||||||
GetFieldMappingsResponse(Map<String, Map<String, Map<String, FieldMappingMetaData>>> mappings) {
|
GetFieldMappingsResponse(Map<String, Map<String, Map<String, FieldMappingMetaData>>> mappings) {
|
||||||
|
@ -77,7 +113,7 @@ public class GetFieldMappingsResponse extends ActionResponse implements ToXConte
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
for (Map.Entry<String, Map<String, Map<String, FieldMappingMetaData>>> indexEntry : mappings.entrySet()) {
|
for (Map.Entry<String, Map<String, Map<String, FieldMappingMetaData>>> indexEntry : mappings.entrySet()) {
|
||||||
builder.startObject(indexEntry.getKey());
|
builder.startObject(indexEntry.getKey());
|
||||||
builder.startObject("mappings");
|
builder.startObject(MAPPINGS.getPreferredName());
|
||||||
for (Map.Entry<String, Map<String, FieldMappingMetaData>> typeEntry : indexEntry.getValue().entrySet()) {
|
for (Map.Entry<String, Map<String, FieldMappingMetaData>> typeEntry : indexEntry.getValue().entrySet()) {
|
||||||
builder.startObject(typeEntry.getKey());
|
builder.startObject(typeEntry.getKey());
|
||||||
for (Map.Entry<String, FieldMappingMetaData> fieldEntry : typeEntry.getValue().entrySet()) {
|
for (Map.Entry<String, FieldMappingMetaData> fieldEntry : typeEntry.getValue().entrySet()) {
|
||||||
|
@ -93,9 +129,46 @@ public class GetFieldMappingsResponse extends ActionResponse implements ToXConte
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static GetFieldMappingsResponse fromXContent(XContentParser parser) throws IOException {
|
||||||
|
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);
|
||||||
|
|
||||||
|
final Map<String, Map<String, Map<String, FieldMappingMetaData>>> mappings = new HashMap<>();
|
||||||
|
if (parser.nextToken() == XContentParser.Token.FIELD_NAME) {
|
||||||
|
while (parser.currentToken() == XContentParser.Token.FIELD_NAME) {
|
||||||
|
final String index = parser.currentName();
|
||||||
|
|
||||||
|
final Map<String, Map<String, FieldMappingMetaData>> typeMappings = PARSER.parse(parser, index);
|
||||||
|
mappings.put(index, typeMappings);
|
||||||
|
|
||||||
|
parser.nextToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new GetFieldMappingsResponse(mappings);
|
||||||
|
}
|
||||||
|
|
||||||
public static class FieldMappingMetaData implements ToXContentFragment {
|
public static class FieldMappingMetaData implements ToXContentFragment {
|
||||||
public static final FieldMappingMetaData NULL = new FieldMappingMetaData("", BytesArray.EMPTY);
|
public static final FieldMappingMetaData NULL = new FieldMappingMetaData("", BytesArray.EMPTY);
|
||||||
|
|
||||||
|
private static final ParseField FULL_NAME = new ParseField("full_name");
|
||||||
|
private static final ParseField MAPPING = new ParseField("mapping");
|
||||||
|
|
||||||
|
private static final ConstructingObjectParser<FieldMappingMetaData, String> PARSER =
|
||||||
|
new ConstructingObjectParser<>("field_mapping_meta_data", true,
|
||||||
|
a -> new FieldMappingMetaData((String)a[0], (BytesReference)a[1])
|
||||||
|
);
|
||||||
|
|
||||||
|
static {
|
||||||
|
PARSER.declareField(optionalConstructorArg(),
|
||||||
|
(p, c) -> p.text(), FULL_NAME, ObjectParser.ValueType.STRING);
|
||||||
|
PARSER.declareField(optionalConstructorArg(),
|
||||||
|
(p, c) -> {
|
||||||
|
final XContentBuilder jsonBuilder = jsonBuilder().copyCurrentStructure(p);
|
||||||
|
final BytesReference bytes = BytesReference.bytes(jsonBuilder);
|
||||||
|
return bytes;
|
||||||
|
}, MAPPING, ObjectParser.ValueType.OBJECT);
|
||||||
|
}
|
||||||
|
|
||||||
private String fullName;
|
private String fullName;
|
||||||
private BytesReference source;
|
private BytesReference source;
|
||||||
|
|
||||||
|
@ -122,18 +195,41 @@ public class GetFieldMappingsResponse extends ActionResponse implements ToXConte
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static FieldMappingMetaData fromXContent(XContentParser parser) throws IOException {
|
||||||
|
return PARSER.parse(parser, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.field("full_name", fullName);
|
builder.field(FULL_NAME.getPreferredName(), fullName);
|
||||||
if (params.paramAsBoolean("pretty", false)) {
|
if (params.paramAsBoolean("pretty", false)) {
|
||||||
builder.field("mapping", sourceAsMap());
|
builder.field("mapping", sourceAsMap());
|
||||||
} else {
|
} else {
|
||||||
try (InputStream stream = source.streamInput()) {
|
try (InputStream stream = source.streamInput()) {
|
||||||
builder.rawField("mapping", stream, XContentType.JSON);
|
builder.rawField(MAPPING.getPreferredName(), stream, XContentType.JSON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "FieldMappingMetaData{fullName='" + fullName + '\'' + ", source=" + source + '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof FieldMappingMetaData)) return false;
|
||||||
|
FieldMappingMetaData that = (FieldMappingMetaData) o;
|
||||||
|
return Objects.equals(fullName, that.fullName) &&
|
||||||
|
Objects.equals(source, that.source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(fullName, source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -178,4 +274,25 @@ public class GetFieldMappingsResponse extends ActionResponse implements ToXConte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GetFieldMappingsResponse{" +
|
||||||
|
"mappings=" + mappings +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof GetFieldMappingsResponse)) return false;
|
||||||
|
GetFieldMappingsResponse that = (GetFieldMappingsResponse) o;
|
||||||
|
return Objects.equals(mappings, that.mappings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(mappings);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,16 +23,22 @@ import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRespon
|
||||||
import org.elasticsearch.common.bytes.BytesArray;
|
import org.elasticsearch.common.bytes.BytesArray;
|
||||||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentType;
|
||||||
|
import org.elasticsearch.test.AbstractStreamableXContentTestCase;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class GetFieldMappingsResponseTests extends ESTestCase {
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
|
||||||
public void testSerialization() throws IOException {
|
public class GetFieldMappingsResponseTests extends AbstractStreamableXContentTestCase<GetFieldMappingsResponse> {
|
||||||
|
|
||||||
|
public void testManualSerialization() throws IOException {
|
||||||
Map<String, Map<String, Map<String, FieldMappingMetaData>>> mappings = new HashMap<>();
|
Map<String, Map<String, Map<String, FieldMappingMetaData>>> mappings = new HashMap<>();
|
||||||
FieldMappingMetaData fieldMappingMetaData = new FieldMappingMetaData("my field", new BytesArray("{}"));
|
FieldMappingMetaData fieldMappingMetaData = new FieldMappingMetaData("my field", new BytesArray("{}"));
|
||||||
mappings.put("index", Collections.singletonMap("type", Collections.singletonMap("field", fieldMappingMetaData)));
|
mappings.put("index", Collections.singletonMap("type", Collections.singletonMap("field", fieldMappingMetaData)));
|
||||||
|
@ -49,4 +55,92 @@ public class GetFieldMappingsResponseTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testManualJunkedJson() throws Exception {
|
||||||
|
// in fact random fields could be evaluated as proper mapping, while proper junk in this case is arrays and values
|
||||||
|
final String json =
|
||||||
|
"{\"index1\":{\"mappings\":"
|
||||||
|
+ "{\"doctype0\":{\"field1\":{\"full_name\":\"my field\",\"mapping\":{\"type\":\"keyword\"}},"
|
||||||
|
+ "\"field0\":{\"full_name\":\"my field\",\"mapping\":{\"type\":\"keyword\"}}},"
|
||||||
|
// junk here
|
||||||
|
+ "\"junk1\": [\"field1\", {\"field2\":{}}],"
|
||||||
|
+ "\"junk2\": [{\"field3\":{}}],"
|
||||||
|
+ "\"junk3\": 42,"
|
||||||
|
+ "\"junk4\": \"Q\","
|
||||||
|
+ "\"doctype1\":{\"field1\":{\"full_name\":\"my field\",\"mapping\":{\"type\":\"keyword\"}},"
|
||||||
|
+ "\"field0\":{\"full_name\":\"my field\",\"mapping\":{\"type\":\"keyword\"}}}}},"
|
||||||
|
+ "\"index0\":{\"mappings\":"
|
||||||
|
+ "{\"doctype0\":{\"field1\":{\"full_name\":\"my field\",\"mapping\":{\"type\":\"keyword\"}},"
|
||||||
|
+ "\"field0\":{\"full_name\":\"my field\",\"mapping\":{\"type\":\"keyword\"}}},"
|
||||||
|
+ "\"doctype1\":{\"field1\":{\"full_name\":\"my field\",\"mapping\":{\"type\":\"keyword\"}},"
|
||||||
|
+ "\"field0\":{\"full_name\":\"my field\",\"mapping\":{\"type\":\"keyword\"}}}}}}";
|
||||||
|
|
||||||
|
final XContentParser parser = XContentType.JSON.xContent().createParser(xContentRegistry(),
|
||||||
|
LoggingDeprecationHandler.INSTANCE, json.getBytes("UTF-8"));
|
||||||
|
|
||||||
|
final GetFieldMappingsResponse response = GetFieldMappingsResponse.fromXContent(parser);
|
||||||
|
|
||||||
|
FieldMappingMetaData fieldMappingMetaData =
|
||||||
|
new FieldMappingMetaData("my field", new BytesArray("{\"type\":\"keyword\"}"));
|
||||||
|
Map<String, FieldMappingMetaData> fieldMapping = new HashMap<>();
|
||||||
|
fieldMapping.put("field0", fieldMappingMetaData);
|
||||||
|
fieldMapping.put("field1", fieldMappingMetaData);
|
||||||
|
|
||||||
|
Map<String, Map<String, FieldMappingMetaData>> typeMapping = new HashMap<>();
|
||||||
|
typeMapping.put("doctype0", fieldMapping);
|
||||||
|
typeMapping.put("doctype1", fieldMapping);
|
||||||
|
|
||||||
|
Map<String, Map<String, Map<String, FieldMappingMetaData>>> mappings = new HashMap<>();
|
||||||
|
mappings.put("index0", typeMapping);
|
||||||
|
mappings.put("index1", typeMapping);
|
||||||
|
|
||||||
|
final Map<String, Map<String, Map<String, FieldMappingMetaData>>> responseMappings = response.mappings();
|
||||||
|
assertThat(responseMappings, equalTo(mappings));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected GetFieldMappingsResponse doParseInstance(XContentParser parser) throws IOException {
|
||||||
|
return GetFieldMappingsResponse.fromXContent(parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected GetFieldMappingsResponse createBlankInstance() {
|
||||||
|
return new GetFieldMappingsResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected GetFieldMappingsResponse createTestInstance() {
|
||||||
|
return new GetFieldMappingsResponse(randomMapping());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Predicate<String> getRandomFieldsExcludeFilter() {
|
||||||
|
// allow random fields at the level of `index` and `index.mappings.doctype.field`
|
||||||
|
// otherwise random field could be evaluated as index name or type name
|
||||||
|
return s -> false == (s.matches("(?<index>[^.]+)")
|
||||||
|
|| s.matches("(?<index>[^.]+)\\.mappings\\.(?<doctype>[^.]+)\\.(?<field>[^.]+)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Map<String, Map<String, FieldMappingMetaData>>> randomMapping() {
|
||||||
|
Map<String, Map<String, Map<String, FieldMappingMetaData>>> mappings = new HashMap<>();
|
||||||
|
|
||||||
|
int indices = randomInt(10);
|
||||||
|
for(int i = 0; i < indices; i++) {
|
||||||
|
final Map<String, Map<String, FieldMappingMetaData>> doctypesMappings = new HashMap<>();
|
||||||
|
int doctypes = randomInt(10);
|
||||||
|
for(int j = 0; j < doctypes; j++) {
|
||||||
|
Map<String, FieldMappingMetaData> fieldMappings = new HashMap<>();
|
||||||
|
int fields = randomInt(10);
|
||||||
|
for(int k = 0; k < fields; k++) {
|
||||||
|
final String mapping = randomBoolean() ? "{\"type\":\"string\"}" : "{\"type\":\"keyword\"}";
|
||||||
|
FieldMappingMetaData metaData =
|
||||||
|
new FieldMappingMetaData("my field", new BytesArray(mapping));
|
||||||
|
fieldMappings.put("field" + k, metaData);
|
||||||
|
}
|
||||||
|
doctypesMappings.put("doctype" + j, fieldMappings);
|
||||||
|
}
|
||||||
|
mappings.put("index" + i, doctypesMappings);
|
||||||
|
}
|
||||||
|
return mappings;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue