REST API: Consistent get field mapping response
If a get field mapping request is issued, and all but the field can be found, the response should return an empty JSON object instead of a 404. Closes #4738
This commit is contained in:
parent
d9699e02f4
commit
5e58f4066e
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
"Raise 404 when field doesn't exist":
|
||||
"Return empty object if field doesn't exist, but type and index do":
|
||||
|
||||
- do:
|
||||
indices.create:
|
||||
|
@ -13,9 +13,9 @@
|
|||
analyzer: whitespace
|
||||
|
||||
- do:
|
||||
catch: missing
|
||||
indices.get_field_mapping:
|
||||
index: test_index
|
||||
type: test_type
|
||||
field: not_text
|
||||
field: not_existent
|
||||
|
||||
- match: { '': {}}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.action.admin.indices.mapping.get;
|
|||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
|
@ -88,6 +89,8 @@ public class GetFieldMappingsResponse extends ActionResponse implements ToXConte
|
|||
}
|
||||
|
||||
public static class FieldMappingMetaData implements ToXContent {
|
||||
public static final FieldMappingMetaData NULL = new FieldMappingMetaData("", BytesArray.EMPTY);
|
||||
|
||||
private String fullName;
|
||||
private BytesReference source;
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ public class TransportGetFieldMappingsAction extends TransportClusterInfoAction<
|
|||
return ImmutableMap.of();
|
||||
}
|
||||
|
||||
boolean isProbablySingleFieldRequest = concreteIndices.length == 1 && types.length == 1 && fields.length == 1;
|
||||
ImmutableMap.Builder<String, ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>>> indexMapBuilder = ImmutableMap.builder();
|
||||
Sets.SetView<String> intersection = Sets.intersection(Sets.newHashSet(concreteIndices), indicesService.indices());
|
||||
for (String index : intersection) {
|
||||
|
@ -114,7 +115,7 @@ public class TransportGetFieldMappingsAction extends TransportClusterInfoAction<
|
|||
MapBuilder<String, ImmutableMap<String, FieldMappingMetaData>> typeMappings = new MapBuilder<String, ImmutableMap<String, FieldMappingMetaData>>();
|
||||
for (String type : typeIntersection) {
|
||||
DocumentMapper documentMapper = indexService.mapperService().documentMapper(type);
|
||||
ImmutableMap<String, FieldMappingMetaData> fieldMapping = findFieldMappingsByType(documentMapper, fields, includeDefaults);
|
||||
ImmutableMap<String, FieldMappingMetaData> fieldMapping = findFieldMappingsByType(documentMapper, fields, includeDefaults, isProbablySingleFieldRequest);
|
||||
if (!fieldMapping.isEmpty()) {
|
||||
typeMappings.put(type, fieldMapping);
|
||||
}
|
||||
|
@ -170,7 +171,7 @@ public class TransportGetFieldMappingsAction extends TransportClusterInfoAction<
|
|||
};
|
||||
|
||||
private ImmutableMap<String, FieldMappingMetaData> findFieldMappingsByType(DocumentMapper documentMapper, String[] fields,
|
||||
boolean includeDefaults) throws ElasticsearchException {
|
||||
boolean includeDefaults, boolean isProbablySingleFieldRequest) throws ElasticsearchException {
|
||||
MapBuilder<String, FieldMappingMetaData> fieldMappings = new MapBuilder<String, FieldMappingMetaData>();
|
||||
ImmutableList<FieldMapper> allFieldMappers = documentMapper.mappers().mappers();
|
||||
for (String field : fields) {
|
||||
|
@ -215,6 +216,8 @@ public class TransportGetFieldMappingsAction extends TransportClusterInfoAction<
|
|||
FieldMapper fieldMapper = documentMapper.mappers().smartNameFieldMapper(field);
|
||||
if (fieldMapper != null) {
|
||||
addFieldMapper(field, fieldMapper, fieldMappings, includeDefaults);
|
||||
} else if (isProbablySingleFieldRequest) {
|
||||
fieldMappings.put(field, FieldMappingMetaData.NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,10 +35,12 @@ import org.elasticsearch.rest.*;
|
|||
import org.elasticsearch.rest.action.support.RestXContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||
import static org.elasticsearch.rest.RestStatus.NOT_FOUND;
|
||||
import static org.elasticsearch.rest.RestStatus.OK;
|
||||
import static org.elasticsearch.rest.action.support.RestXContentBuilder.emptyBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -70,14 +72,21 @@ public class RestGetFieldMappingAction extends BaseRestHandler {
|
|||
@Override
|
||||
public void onResponse(GetFieldMappingsResponse response) {
|
||||
try {
|
||||
XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
|
||||
builder.startObject();
|
||||
|
||||
ImmutableMap<String, ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>>> mappingsByIndex = response.mappings();
|
||||
|
||||
boolean isPossibleSingleFieldRequest = indices.length == 1 && types.length == 1 && fields.length == 1;
|
||||
if (isPossibleSingleFieldRequest && isFieldMappingMissingField(mappingsByIndex)) {
|
||||
channel.sendResponse(new XContentRestResponse(request, OK, emptyBuilder(request)));
|
||||
return;
|
||||
}
|
||||
|
||||
RestStatus status = OK;
|
||||
if (mappingsByIndex.isEmpty() && fields.length > 0) {
|
||||
status = NOT_FOUND;
|
||||
}
|
||||
|
||||
XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
|
||||
builder.startObject();
|
||||
response.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||
builder.endObject();
|
||||
channel.sendResponse(new XContentRestResponse(request, status, builder));
|
||||
|
@ -97,4 +106,25 @@ public class RestGetFieldMappingAction extends BaseRestHandler {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Helper method to find out if the only included fieldmapping metadata is typed NULL, which means
|
||||
* that type and index exist, but the field did not
|
||||
*/
|
||||
private boolean isFieldMappingMissingField(ImmutableMap<String, ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>>> mappingsByIndex) throws IOException {
|
||||
if (mappingsByIndex.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>> value : mappingsByIndex.values()) {
|
||||
for (ImmutableMap<String, FieldMappingMetaData> fieldValue : value.values()) {
|
||||
for (Map.Entry<String, FieldMappingMetaData> fieldMappingMetaDataEntry : fieldValue.entrySet()) {
|
||||
if (fieldMappingMetaDataEntry.getValue() == FieldMappingMetaData.NULL) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue