mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-22 12:56:53 +00:00
Deprecate types in get field mapping API (#37667)
- Add deprecation warning to RestGetFieldMappingAction - Add two new java HRLC classes GetFieldMappingsRequest and GetFieldMappingsResponse. These classes use new typeless forms of a request and response, and differ in that from the server versions. Relates to #35190
This commit is contained in:
parent
f45b5fedb5
commit
c8565fe692
@ -37,8 +37,8 @@ import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse;
|
||||
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
||||
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
|
||||
import org.elasticsearch.client.indices.GetFieldMappingsRequest;
|
||||
import org.elasticsearch.client.indices.GetFieldMappingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
|
||||
@ -241,11 +241,16 @@ public final class IndicesClient {
|
||||
* @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
|
||||
*
|
||||
* @deprecated This method uses an old request object which still refers to types, a deprecated feature. The method
|
||||
* {@link #getFieldMapping(GetFieldMappingsRequest, RequestOptions)} should be used instead, which accepts a new request object.
|
||||
*/
|
||||
public GetFieldMappingsResponse getFieldMapping(GetFieldMappingsRequest getFieldMappingsRequest,
|
||||
RequestOptions options) throws IOException {
|
||||
return restHighLevelClient.performRequestAndParseEntity(getFieldMappingsRequest, IndicesRequestConverters::getFieldMapping, options,
|
||||
GetFieldMappingsResponse::fromXContent, emptySet());
|
||||
@Deprecated
|
||||
public org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse getFieldMapping(
|
||||
org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest getFieldMappingsRequest,
|
||||
RequestOptions options) throws IOException {
|
||||
return restHighLevelClient.performRequestAndParseEntity(getFieldMappingsRequest, IndicesRequestConverters::getFieldMapping,
|
||||
options, org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse::fromXContent, emptySet());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -255,9 +260,45 @@ public final class IndicesClient {
|
||||
* @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
|
||||
*
|
||||
* @deprecated This method uses an old request object which still refers to types, a deprecated feature. The
|
||||
* method {@link #getFieldMappingAsync(GetFieldMappingsRequest, RequestOptions, ActionListener)} should be used instead,
|
||||
* which accepts a new request object.
|
||||
*/
|
||||
public void getFieldMappingAsync(GetFieldMappingsRequest getFieldMappingsRequest, RequestOptions options,
|
||||
ActionListener<GetFieldMappingsResponse> listener) {
|
||||
@Deprecated
|
||||
public void getFieldMappingAsync(org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest getFieldMappingsRequest,
|
||||
RequestOptions options,
|
||||
ActionListener<org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse> listener) {
|
||||
restHighLevelClient.performRequestAsyncAndParseEntity(getFieldMappingsRequest, IndicesRequestConverters::getFieldMapping, options,
|
||||
org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse::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, IndicesRequestConverters::getFieldMapping,
|
||||
options, GetFieldMappingsResponse::fromXContent, emptySet()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously 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
|
||||
* @param listener the listener to be notified upon request completion
|
||||
*/
|
||||
public void getFieldMappingAsync(GetFieldMappingsRequest getFieldMappingsRequest,
|
||||
RequestOptions options, ActionListener<GetFieldMappingsResponse> listener) {
|
||||
restHighLevelClient.performRequestAsyncAndParseEntity(getFieldMappingsRequest, IndicesRequestConverters::getFieldMapping, options,
|
||||
GetFieldMappingsResponse::fromXContent, listener, emptySet());
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ import org.elasticsearch.action.admin.indices.flush.FlushRequest;
|
||||
import org.elasticsearch.action.admin.indices.flush.SyncedFlushRequest;
|
||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
||||
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest;
|
||||
import org.elasticsearch.client.indices.GetFieldMappingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
|
||||
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
|
||||
@ -165,7 +165,28 @@ final class IndicesRequestConverters {
|
||||
return request;
|
||||
}
|
||||
|
||||
static Request getFieldMapping(GetFieldMappingsRequest getFieldMappingsRequest) throws IOException {
|
||||
static Request getFieldMapping(GetFieldMappingsRequest getFieldMappingsRequest) {
|
||||
String[] indices = getFieldMappingsRequest.indices() == null ? Strings.EMPTY_ARRAY : getFieldMappingsRequest.indices();
|
||||
String[] fields = getFieldMappingsRequest.fields() == null ? Strings.EMPTY_ARRAY : getFieldMappingsRequest.fields();
|
||||
|
||||
String endpoint = new RequestConverters.EndpointBuilder()
|
||||
.addCommaSeparatedPathParts(indices)
|
||||
.addPathPartAsIs("_mapping")
|
||||
.addPathPartAsIs("field")
|
||||
.addCommaSeparatedPathParts(fields)
|
||||
.build();
|
||||
|
||||
Request request = new Request(HttpGet.METHOD_NAME, endpoint);
|
||||
|
||||
RequestConverters.Params parameters = new RequestConverters.Params(request);
|
||||
parameters.withIndicesOptions(getFieldMappingsRequest.indicesOptions());
|
||||
parameters.withIncludeDefaults(getFieldMappingsRequest.includeDefaults());
|
||||
parameters.withLocal(getFieldMappingsRequest.local());
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
static Request getFieldMapping(org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest getFieldMappingsRequest) {
|
||||
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();
|
||||
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.client.indices;
|
||||
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.client.Validatable;
|
||||
import org.elasticsearch.common.Strings;
|
||||
|
||||
/** Request the mappings of specific fields */
|
||||
public class GetFieldMappingsRequest implements Validatable {
|
||||
|
||||
private boolean local = false;
|
||||
|
||||
private String[] fields = Strings.EMPTY_ARRAY;
|
||||
|
||||
private boolean includeDefaults = false;
|
||||
|
||||
private String[] indices = Strings.EMPTY_ARRAY;
|
||||
|
||||
private IndicesOptions indicesOptions = IndicesOptions.strictExpandOpen();
|
||||
|
||||
/**
|
||||
* Indicate whether the receiving node should operate based on local index information or forward requests,
|
||||
* where needed, to other nodes. If running locally, request will not raise errors if running locally & missing indices.
|
||||
*/
|
||||
public GetFieldMappingsRequest local(boolean local) {
|
||||
this.local = local;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean local() {
|
||||
return local;
|
||||
}
|
||||
|
||||
public GetFieldMappingsRequest indices(String... indices) {
|
||||
this.indices = indices;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GetFieldMappingsRequest indicesOptions(IndicesOptions indicesOptions) {
|
||||
this.indicesOptions = indicesOptions;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String[] indices() {
|
||||
return indices;
|
||||
}
|
||||
|
||||
public IndicesOptions indicesOptions() {
|
||||
return indicesOptions;
|
||||
}
|
||||
|
||||
/** @param fields a list of fields to retrieve the mapping for */
|
||||
public GetFieldMappingsRequest fields(String... fields) {
|
||||
this.fields = fields;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String[] fields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public boolean includeDefaults() {
|
||||
return includeDefaults;
|
||||
}
|
||||
|
||||
/** Indicates whether default mapping settings should be returned */
|
||||
public GetFieldMappingsRequest includeDefaults(boolean includeDefaults) {
|
||||
this.includeDefaults = includeDefaults;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.client.indices;
|
||||
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.index.mapper.Mapper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
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 */
|
||||
public class GetFieldMappingsResponse {
|
||||
|
||||
private static final ParseField MAPPINGS = new ParseField("mappings");
|
||||
|
||||
private static final ObjectParser<Map<String, FieldMappingMetaData>, String> PARSER =
|
||||
new ObjectParser<>(MAPPINGS.getPreferredName(), true, HashMap::new);
|
||||
|
||||
static {
|
||||
PARSER.declareField((p, fieldMappings, index) -> {
|
||||
p.nextToken();
|
||||
while (p.currentToken() == XContentParser.Token.FIELD_NAME) {
|
||||
final String fieldName = p.currentName();
|
||||
final FieldMappingMetaData fieldMappingMetaData = FieldMappingMetaData.fromXContent(p);
|
||||
fieldMappings.put(fieldName, fieldMappingMetaData);
|
||||
p.nextToken();
|
||||
}
|
||||
}, MAPPINGS, ObjectParser.ValueType.OBJECT);
|
||||
}
|
||||
|
||||
private Map<String, Map<String, FieldMappingMetaData>> mappings;
|
||||
|
||||
GetFieldMappingsResponse(Map<String, Map<String, FieldMappingMetaData>> mappings) {
|
||||
this.mappings = mappings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the fields mapping. The return map keys are indexes and fields (as specified in the request).
|
||||
*/
|
||||
public Map<String, Map<String, FieldMappingMetaData>> mappings() {
|
||||
return mappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mappings of a specific index and field.
|
||||
*
|
||||
* @param field field name as specified in the {@link GetFieldMappingsRequest}
|
||||
* @return FieldMappingMetaData for the requested field or null if not found.
|
||||
*/
|
||||
public FieldMappingMetaData fieldMappings(String index, String field) {
|
||||
Map<String, FieldMappingMetaData> indexMapping = mappings.get(index);
|
||||
if (indexMapping == null) {
|
||||
return null;
|
||||
}
|
||||
return indexMapping.get(field);
|
||||
}
|
||||
|
||||
|
||||
public static GetFieldMappingsResponse fromXContent(XContentParser parser) throws IOException {
|
||||
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);
|
||||
final 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, FieldMappingMetaData> fieldMappings = PARSER.parse(parser, index);
|
||||
mappings.put(index, fieldMappings);
|
||||
parser.nextToken();
|
||||
}
|
||||
}
|
||||
return new GetFieldMappingsResponse(mappings);
|
||||
}
|
||||
|
||||
public static class FieldMappingMetaData {
|
||||
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 BytesReference source;
|
||||
|
||||
public FieldMappingMetaData(String fullName, BytesReference source) {
|
||||
this.fullName = fullName;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public String fullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mappings as a map. Note that the returned map has a single key which is always the field's {@link Mapper#name}.
|
||||
*/
|
||||
public Map<String, Object> sourceAsMap() {
|
||||
return XContentHelper.convertToMap(source, true, XContentType.JSON).v2();
|
||||
}
|
||||
|
||||
//pkg-private for testing
|
||||
BytesReference getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public static FieldMappingMetaData fromXContent(XContentParser parser) throws IOException {
|
||||
return PARSER.parse(parser, null);
|
||||
}
|
||||
|
||||
@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
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@ -43,8 +43,8 @@ import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse;
|
||||
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
||||
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
|
||||
import org.elasticsearch.client.indices.GetFieldMappingsRequest;
|
||||
import org.elasticsearch.client.indices.GetFieldMappingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
|
||||
@ -93,6 +93,7 @@ import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.query.QueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestGetFieldMappingAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestPutMappingAction;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -500,7 +501,6 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
|
||||
|
||||
GetFieldMappingsRequest getFieldMappingsRequest = new GetFieldMappingsRequest()
|
||||
.indices(indexName)
|
||||
.types("_doc")
|
||||
.fields("field");
|
||||
|
||||
GetFieldMappingsResponse getFieldMappingsResponse =
|
||||
@ -509,7 +509,7 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
|
||||
highLevelClient().indices()::getFieldMappingAsync);
|
||||
|
||||
final Map<String, GetFieldMappingsResponse.FieldMappingMetaData> fieldMappingMap =
|
||||
getFieldMappingsResponse.mappings().get(indexName).get("_doc");
|
||||
getFieldMappingsResponse.mappings().get(indexName);
|
||||
|
||||
final GetFieldMappingsResponse.FieldMappingMetaData metaData =
|
||||
new GetFieldMappingsResponse.FieldMappingMetaData("field",
|
||||
@ -517,6 +517,42 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
|
||||
assertThat(fieldMappingMap, equalTo(Collections.singletonMap("field", metaData)));
|
||||
}
|
||||
|
||||
public void testGetFieldMappingWithTypes() throws IOException {
|
||||
String indexName = "test";
|
||||
createIndex(indexName, Settings.EMPTY);
|
||||
|
||||
PutMappingRequest putMappingRequest = new PutMappingRequest(indexName);
|
||||
XContentBuilder mappingBuilder = JsonXContent.contentBuilder();
|
||||
mappingBuilder.startObject().startObject("properties").startObject("field");
|
||||
mappingBuilder.field("type", "text");
|
||||
mappingBuilder.endObject().endObject().endObject();
|
||||
putMappingRequest.source(mappingBuilder);
|
||||
|
||||
AcknowledgedResponse putMappingResponse =
|
||||
execute(putMappingRequest, highLevelClient().indices()::putMapping, highLevelClient().indices()::putMappingAsync);
|
||||
assertTrue(putMappingResponse.isAcknowledged());
|
||||
|
||||
org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest getFieldMappingsRequest =
|
||||
new org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest()
|
||||
.indices(indexName)
|
||||
.types("_doc")
|
||||
.fields("field");
|
||||
|
||||
org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse getFieldMappingsResponse =
|
||||
execute(getFieldMappingsRequest,
|
||||
highLevelClient().indices()::getFieldMapping,
|
||||
highLevelClient().indices()::getFieldMappingAsync,
|
||||
expectWarnings(RestGetFieldMappingAction.TYPES_DEPRECATION_MESSAGE));
|
||||
|
||||
final Map<String, org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse.FieldMappingMetaData>
|
||||
fieldMappingMap = getFieldMappingsResponse.mappings().get(indexName).get("_doc");
|
||||
|
||||
final org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse.FieldMappingMetaData metaData =
|
||||
new org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse.FieldMappingMetaData("field",
|
||||
new BytesArray("{\"field\":{\"type\":\"text\"}}"));
|
||||
assertThat(fieldMappingMap, equalTo(Collections.singletonMap("field", metaData)));
|
||||
}
|
||||
|
||||
public void testDeleteIndex() throws IOException {
|
||||
{
|
||||
// Delete index if exists
|
||||
|
@ -38,7 +38,6 @@ import org.elasticsearch.action.admin.indices.flush.FlushRequest;
|
||||
import org.elasticsearch.action.admin.indices.flush.SyncedFlushRequest;
|
||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
||||
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.open.OpenIndexRequest;
|
||||
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
|
||||
@ -54,6 +53,7 @@ import org.elasticsearch.action.support.master.AcknowledgedRequest;
|
||||
import org.elasticsearch.client.indices.GetIndexTemplatesRequest;
|
||||
import org.elasticsearch.client.indices.IndexTemplatesExistRequest;
|
||||
import org.elasticsearch.client.indices.PutMappingRequest;
|
||||
import org.elasticsearch.client.indices.GetFieldMappingsRequest;
|
||||
import org.elasticsearch.common.CheckedFunction;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
@ -258,7 +258,7 @@ public class IndicesRequestConvertersTests extends ESTestCase {
|
||||
Assert.assertThat(HttpGet.METHOD_NAME, equalTo(request.getMethod()));
|
||||
}
|
||||
|
||||
public void testGetFieldMapping() throws IOException {
|
||||
public void testGetFieldMapping() {
|
||||
GetFieldMappingsRequest getFieldMappingsRequest = new GetFieldMappingsRequest();
|
||||
|
||||
String[] indices = Strings.EMPTY_ARRAY;
|
||||
@ -269,6 +269,50 @@ public class IndicesRequestConvertersTests extends ESTestCase {
|
||||
getFieldMappingsRequest.indices((String[]) null);
|
||||
}
|
||||
|
||||
String[] fields = null;
|
||||
if (ESTestCase.randomBoolean()) {
|
||||
fields = new String[ESTestCase.randomIntBetween(1, 5)];
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
fields[i] = ESTestCase.randomAlphaOfLengthBetween(3, 10);
|
||||
}
|
||||
getFieldMappingsRequest.fields(fields);
|
||||
} else if (ESTestCase.randomBoolean()) {
|
||||
getFieldMappingsRequest.fields((String[]) null);
|
||||
}
|
||||
|
||||
Map<String, String> expectedParams = new HashMap<>();
|
||||
RequestConvertersTests.setRandomIndicesOptions(getFieldMappingsRequest::indicesOptions, getFieldMappingsRequest::indicesOptions,
|
||||
expectedParams);
|
||||
RequestConvertersTests.setRandomLocal(getFieldMappingsRequest::local, expectedParams);
|
||||
|
||||
Request request = IndicesRequestConverters.getFieldMapping(getFieldMappingsRequest);
|
||||
StringJoiner endpoint = new StringJoiner("/", "/", "");
|
||||
String index = String.join(",", indices);
|
||||
if (Strings.hasLength(index)) {
|
||||
endpoint.add(index);
|
||||
}
|
||||
endpoint.add("_mapping");
|
||||
endpoint.add("field");
|
||||
if (fields != null) {
|
||||
endpoint.add(String.join(",", fields));
|
||||
}
|
||||
Assert.assertThat(endpoint.toString(), equalTo(request.getEndpoint()));
|
||||
Assert.assertThat(expectedParams, equalTo(request.getParameters()));
|
||||
Assert.assertThat(HttpGet.METHOD_NAME, equalTo(request.getMethod()));
|
||||
}
|
||||
|
||||
public void testGetFieldMappingWithTypes() {
|
||||
org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest getFieldMappingsRequest =
|
||||
new org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest();
|
||||
|
||||
String[] indices = Strings.EMPTY_ARRAY;
|
||||
if (ESTestCase.randomBoolean()) {
|
||||
indices = RequestConvertersTests.randomIndicesNames(0, 5);
|
||||
getFieldMappingsRequest.indices(indices);
|
||||
} else if (ESTestCase.randomBoolean()) {
|
||||
getFieldMappingsRequest.indices((String[]) null);
|
||||
}
|
||||
|
||||
String type = null;
|
||||
if (ESTestCase.randomBoolean()) {
|
||||
type = ESTestCase.randomAlphaOfLengthBetween(3, 10);
|
||||
|
@ -42,8 +42,8 @@ import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse;
|
||||
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
||||
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsResponse;
|
||||
import org.elasticsearch.client.indices.GetFieldMappingsRequest;
|
||||
import org.elasticsearch.client.indices.GetFieldMappingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
|
||||
@ -725,8 +725,7 @@ public class IndicesClientDocumentationIT extends ESRestHighLevelClientTestCase
|
||||
// tag::get-field-mappings-request
|
||||
GetFieldMappingsRequest request = new GetFieldMappingsRequest(); // <1>
|
||||
request.indices("twitter"); // <2>
|
||||
request.types("_doc"); // <3>
|
||||
request.fields("message", "timestamp"); // <4>
|
||||
request.fields("message", "timestamp"); // <3>
|
||||
// end::get-field-mappings-request
|
||||
|
||||
// tag::get-field-mappings-request-indicesOptions
|
||||
@ -745,12 +744,12 @@ public class IndicesClientDocumentationIT extends ESRestHighLevelClientTestCase
|
||||
// end::get-field-mappings-execute
|
||||
|
||||
// tag::get-field-mappings-response
|
||||
final Map<String, Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetaData>>> mappings =
|
||||
final Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetaData>> mappings =
|
||||
response.mappings();// <1>
|
||||
final Map<String, GetFieldMappingsResponse.FieldMappingMetaData> typeMappings =
|
||||
mappings.get("twitter").get("_doc"); // <2>
|
||||
final Map<String, GetFieldMappingsResponse.FieldMappingMetaData> fieldMappings =
|
||||
mappings.get("twitter"); // <2>
|
||||
final GetFieldMappingsResponse.FieldMappingMetaData metaData =
|
||||
typeMappings.get("message");// <3>
|
||||
fieldMappings.get("message");// <3>
|
||||
|
||||
final String fullName = metaData.fullName();// <4>
|
||||
final Map<String, Object> source = metaData.sourceAsMap(); // <5>
|
||||
@ -777,11 +776,11 @@ public class IndicesClientDocumentationIT extends ESRestHighLevelClientTestCase
|
||||
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 =
|
||||
final Map<String, Map<String, GetFieldMappingsResponse.FieldMappingMetaData>> mappings =
|
||||
r.mappings();
|
||||
final Map<String, GetFieldMappingsResponse.FieldMappingMetaData> typeMappings =
|
||||
mappings.get("twitter").get("_doc");
|
||||
final GetFieldMappingsResponse.FieldMappingMetaData metaData1 = typeMappings.get("message");
|
||||
final Map<String, GetFieldMappingsResponse.FieldMappingMetaData> fieldMappings =
|
||||
mappings.get("twitter");
|
||||
final GetFieldMappingsResponse.FieldMappingMetaData metaData1 = fieldMappings.get("message");
|
||||
|
||||
final String fullName = metaData1.fullName();
|
||||
final Map<String, Object> source = metaData1.sourceAsMap();
|
||||
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.client.indices;
|
||||
|
||||
import org.elasticsearch.client.indices.GetFieldMappingsResponse.FieldMappingMetaData;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static org.elasticsearch.test.AbstractXContentTestCase.xContentTester;
|
||||
|
||||
public class GetFieldMappingsResponseTests extends ESTestCase {
|
||||
|
||||
public void testFromXContent() throws IOException {
|
||||
xContentTester(
|
||||
this::createParser,
|
||||
GetFieldMappingsResponseTests::createTestInstance,
|
||||
GetFieldMappingsResponseTests::toXContent,
|
||||
GetFieldMappingsResponse::fromXContent)
|
||||
.supportsUnknownFields(true)
|
||||
.randomFieldsExcludeFilter(getRandomFieldsExcludeFilter())
|
||||
.test();
|
||||
}
|
||||
|
||||
Predicate<String> getRandomFieldsExcludeFilter() {
|
||||
// allow random fields at the level of `index` and `index.mappings.field`
|
||||
// otherwise random field could be evaluated as index name or type name
|
||||
return s -> false == (s.matches("(?<index>[^.]+)")
|
||||
|| s.matches("(?<index>[^.]+)\\.mappings\\.(?<field>[^.]+)"));
|
||||
}
|
||||
|
||||
static GetFieldMappingsResponse createTestInstance() {
|
||||
Map<String, Map<String, FieldMappingMetaData>> mappings = new HashMap<>();
|
||||
// if mappings is empty, means that fields are not found
|
||||
if (randomBoolean()) {
|
||||
int indices = randomInt(10);
|
||||
for (int i = 0; i < indices; i++) {
|
||||
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\"}";
|
||||
final String fieldName = randomAlphaOfLength(8);
|
||||
FieldMappingMetaData metaData = new FieldMappingMetaData(fieldName, new BytesArray(mapping));
|
||||
fieldMappings.put(fieldName, metaData);
|
||||
}
|
||||
mappings.put(randomAlphaOfLength(8), fieldMappings);
|
||||
}
|
||||
}
|
||||
return new GetFieldMappingsResponse(mappings);
|
||||
}
|
||||
|
||||
// As the client class GetFieldMappingsResponse doesn't have toXContent method, adding this method here only for the test
|
||||
static void toXContent(GetFieldMappingsResponse response, XContentBuilder builder) throws IOException {
|
||||
builder.startObject();
|
||||
for (Map.Entry<String, Map<String, FieldMappingMetaData>> indexEntry : response.mappings().entrySet()) {
|
||||
builder.startObject(indexEntry.getKey());
|
||||
builder.startObject("mappings");
|
||||
Map<String, FieldMappingMetaData> mappings = null;
|
||||
for (Map.Entry<String, FieldMappingMetaData> fieldEntry : indexEntry.getValue().entrySet()) {
|
||||
builder.startObject(fieldEntry.getKey());
|
||||
builder.field("full_name", fieldEntry.getValue().fullName());
|
||||
builder.field("mapping", fieldEntry.getValue().sourceAsMap());
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
}
|
@ -18,8 +18,7 @@ include-tagged::{doc-tests-file}[{api}-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
|
||||
<3> The fields to be returned
|
||||
|
||||
==== Optional arguments
|
||||
The following arguments can also optionally be provided:
|
||||
@ -53,7 +52,7 @@ executed operation as follows:
|
||||
include-tagged::{doc-tests-file}[{api}-response]
|
||||
--------------------------------------------------
|
||||
<1> Returning all requested indices fields' mappings
|
||||
<2> Retrieving the mappings for a particular index and type
|
||||
<2> Retrieving the mappings for a particular index
|
||||
<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
|
||||
|
@ -29,7 +29,12 @@ import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/** Request the mappings of specific fields */
|
||||
/**
|
||||
* Request the mappings of specific fields
|
||||
*
|
||||
* Note: there is a new class with the same name for the Java HLRC that uses a typeless format.
|
||||
* Any changes done to this class should go to that client class as well.
|
||||
*/
|
||||
public class GetFieldMappingsRequest extends ActionRequest implements IndicesRequest.Replaceable {
|
||||
|
||||
protected boolean local = false;
|
||||
|
@ -50,7 +50,12 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken;
|
||||
import static org.elasticsearch.rest.BaseRestHandler.DEFAULT_INCLUDE_TYPE_NAME_POLICY;
|
||||
|
||||
/** Response object for {@link GetFieldMappingsRequest} API */
|
||||
/**
|
||||
* Response object for {@link GetFieldMappingsRequest} API
|
||||
*
|
||||
* Note: there is a new class with the same name for the Java HLRC that uses a typeless format.
|
||||
* Any changes done to this class should go to that client class as well.
|
||||
*/
|
||||
public class GetFieldMappingsResponse extends ActionResponse implements ToXContentObject {
|
||||
|
||||
private static final ParseField MAPPINGS = new ParseField("mappings");
|
||||
|
@ -19,12 +19,14 @@
|
||||
|
||||
package org.elasticsearch.rest.action.admin.indices;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
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.GetFieldMappingsResponse.FieldMappingMetaData;
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.client.node.NodeClient;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.logging.DeprecationLogger;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.rest.BaseRestHandler;
|
||||
@ -43,6 +45,12 @@ import static org.elasticsearch.rest.RestStatus.NOT_FOUND;
|
||||
import static org.elasticsearch.rest.RestStatus.OK;
|
||||
|
||||
public class RestGetFieldMappingAction extends BaseRestHandler {
|
||||
|
||||
private static final DeprecationLogger deprecationLogger = new DeprecationLogger(
|
||||
LogManager.getLogger(RestPutMappingAction.class));
|
||||
public static final String TYPES_DEPRECATION_MESSAGE = "[types removal] Using include_type_name in get " +
|
||||
"field mapping requests is deprecated. The parameter will be removed in the next major version.";
|
||||
|
||||
public RestGetFieldMappingAction(Settings settings, RestController controller) {
|
||||
super(settings);
|
||||
controller.registerHandler(GET, "/_mapping/field/{fields}", this);
|
||||
@ -68,6 +76,9 @@ public class RestGetFieldMappingAction extends BaseRestHandler {
|
||||
throw new IllegalArgumentException("Types cannot be specified unless include_type_name" +
|
||||
" is set to true.");
|
||||
}
|
||||
if (request.hasParam(INCLUDE_TYPE_NAME_PARAMETER)) {
|
||||
deprecationLogger.deprecatedAndMaybeLog("get_field_mapping_with_types", TYPES_DEPRECATION_MESSAGE);
|
||||
}
|
||||
|
||||
GetFieldMappingsRequest getMappingsRequest = new GetFieldMappingsRequest();
|
||||
getMappingsRequest.indices(indices).types(types).fields(fields).includeDefaults(request.paramAsBoolean("include_defaults", false));
|
||||
|
@ -40,6 +40,31 @@ public class RestGetFieldMappingActionTests extends RestActionTestCase {
|
||||
new RestGetFieldMappingAction(Settings.EMPTY, controller());
|
||||
}
|
||||
|
||||
public void testIncludeTypeName() {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
String path;
|
||||
if (randomBoolean()) {
|
||||
params.put(INCLUDE_TYPE_NAME_PARAMETER, "true");
|
||||
path = "some_index/some_type/_mapping/field/some_field";
|
||||
} else {
|
||||
params.put(INCLUDE_TYPE_NAME_PARAMETER, "false");
|
||||
path = "some_index/_mapping/field/some_field";
|
||||
}
|
||||
RestRequest deprecatedRequest = new FakeRestRequest.Builder(xContentRegistry())
|
||||
.withMethod(RestRequest.Method.GET)
|
||||
.withPath(path)
|
||||
.withParams(params)
|
||||
.build();
|
||||
dispatchRequest(deprecatedRequest);
|
||||
assertWarnings(RestGetFieldMappingAction.TYPES_DEPRECATION_MESSAGE);
|
||||
|
||||
RestRequest validRequest = new FakeRestRequest.Builder(xContentRegistry())
|
||||
.withMethod(RestRequest.Method.GET)
|
||||
.withPath("some_index/_mapping/field/some_field")
|
||||
.build();
|
||||
dispatchRequest(validRequest);
|
||||
}
|
||||
|
||||
public void testTypeInPath() {
|
||||
// Test that specifying a type while setting include_type_name to false
|
||||
// results in an illegal argument exception.
|
||||
|
Loading…
x
Reference in New Issue
Block a user