Consistent APIs: Get field mapping API includes 'mappings'
The get field mapping API now includes a mappings element after the index in its JSON Added more consistent endpoint /{index}/_mapping/{type}/field/{fields} and added endpoint /_mapping/{type}/field/{fields} which are also used in tests Added rest spec tests for wildcards and _all Relates #4071 NOTE: This is not yet complete for 1.0. We need to return an empty JSON document instead of a 404 if the field of an existing index and type is not found. However this is not possible with the current data structure being returned. Needs to be finished for 1.0.
This commit is contained in:
parent
349a8be4fd
commit
a3abcdc93a
|
@ -4,7 +4,7 @@
|
||||||
"methods": ["GET"],
|
"methods": ["GET"],
|
||||||
"url": {
|
"url": {
|
||||||
"path": "/_mapping/field/{field}",
|
"path": "/_mapping/field/{field}",
|
||||||
"paths": ["/_mapping/field/{field}", "/{index}/_mapping/field/{field}", "/{index}/{type}/_mapping/field/{field}"],
|
"paths": ["/_mapping/field/{field}", "/{index}/_mapping/field/{field}", "/_mapping/{type}/field/{field}", "/{index}/_mapping/{type}/field/{field}"],
|
||||||
"parts": {
|
"parts": {
|
||||||
"index": {
|
"index": {
|
||||||
"type" : "list",
|
"type" : "list",
|
||||||
|
|
|
@ -17,7 +17,7 @@ setup:
|
||||||
indices.get_field_mapping:
|
indices.get_field_mapping:
|
||||||
field: text
|
field: text
|
||||||
|
|
||||||
- match: {test_index.test_type.text.mapping.text.type: string}
|
- match: {test_index.mappings.test_type.text.mapping.text.type: string}
|
||||||
|
|
||||||
---
|
---
|
||||||
"Get field mapping by index only":
|
"Get field mapping by index only":
|
||||||
|
@ -26,7 +26,7 @@ setup:
|
||||||
index: test_index
|
index: test_index
|
||||||
field: text
|
field: text
|
||||||
|
|
||||||
- match: {test_index.test_type.text.mapping.text.type: string}
|
- match: {test_index.mappings.test_type.text.mapping.text.type: string}
|
||||||
|
|
||||||
---
|
---
|
||||||
"Get field mapping by type & field":
|
"Get field mapping by type & field":
|
||||||
|
@ -37,7 +37,7 @@ setup:
|
||||||
type: test_type
|
type: test_type
|
||||||
field: text
|
field: text
|
||||||
|
|
||||||
- match: {test_index.test_type.text.mapping.text.type: string}
|
- match: {test_index.mappings.test_type.text.mapping.text.type: string}
|
||||||
|
|
||||||
---
|
---
|
||||||
"Get field mapping by type & field, with another field that doesn't exist":
|
"Get field mapping by type & field, with another field that doesn't exist":
|
||||||
|
@ -48,8 +48,8 @@ setup:
|
||||||
type: test_type
|
type: test_type
|
||||||
field: [ text , text1 ]
|
field: [ text , text1 ]
|
||||||
|
|
||||||
- match: {test_index.test_type.text.mapping.text.type: string}
|
- match: {test_index.mappings.test_type.text.mapping.text.type: string}
|
||||||
- is_false: test_index.test_type.text1
|
- is_false: test_index.mappings.test_type.text1
|
||||||
|
|
||||||
---
|
---
|
||||||
"Get field mapping with include_defaults":
|
"Get field mapping with include_defaults":
|
||||||
|
@ -61,5 +61,16 @@ setup:
|
||||||
field: text
|
field: text
|
||||||
include_defaults: true
|
include_defaults: true
|
||||||
|
|
||||||
- match: {test_index.test_type.text.mapping.text.type: string}
|
- match: {test_index.mappings.test_type.text.mapping.text.type: string}
|
||||||
- match: {test_index.test_type.text.mapping.text.analyzer: default}
|
- match: {test_index.mappings.test_type.text.mapping.text.analyzer: default}
|
||||||
|
|
||||||
|
---
|
||||||
|
"Get field mapping should work without index specifying type and field":
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.get_field_mapping:
|
||||||
|
type: test_type
|
||||||
|
field: text
|
||||||
|
|
||||||
|
- match: {test_index.mappings.test_type.text.mapping.text.type: string}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,29 @@ setup:
|
||||||
type: string
|
type: string
|
||||||
index_name: t3
|
index_name: t3
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.create:
|
||||||
|
index: test_index_2
|
||||||
|
body:
|
||||||
|
mappings:
|
||||||
|
test_type_2:
|
||||||
|
properties:
|
||||||
|
t1:
|
||||||
|
type: string
|
||||||
|
t2:
|
||||||
|
type: string
|
||||||
|
obj:
|
||||||
|
path: just_name
|
||||||
|
properties:
|
||||||
|
t1:
|
||||||
|
type: string
|
||||||
|
i_t1:
|
||||||
|
type: string
|
||||||
|
index_name: t1
|
||||||
|
i_t3:
|
||||||
|
type: string
|
||||||
|
index_name: t3
|
||||||
|
|
||||||
---
|
---
|
||||||
"Get field mapping with * for fields":
|
"Get field mapping with * for fields":
|
||||||
|
|
||||||
|
@ -30,43 +53,92 @@ setup:
|
||||||
indices.get_field_mapping:
|
indices.get_field_mapping:
|
||||||
field: "*"
|
field: "*"
|
||||||
|
|
||||||
- match: {test_index.test_type.t1.full_name: t1 }
|
- match: {test_index.mappings.test_type.t1.full_name: t1 }
|
||||||
- match: {test_index.test_type.t2.full_name: t2 }
|
- match: {test_index.mappings.test_type.t2.full_name: t2 }
|
||||||
- match: {test_index.test_type.obj\.t1.full_name: obj.t1 }
|
- match: {test_index.mappings.test_type.obj\.t1.full_name: obj.t1 }
|
||||||
- match: {test_index.test_type.obj\.i_t1.full_name: obj.i_t1 }
|
- match: {test_index.mappings.test_type.obj\.i_t1.full_name: obj.i_t1 }
|
||||||
- match: {test_index.test_type.obj\.i_t3.full_name: obj.i_t3 }
|
- match: {test_index.mappings.test_type.obj\.i_t3.full_name: obj.i_t3 }
|
||||||
|
|
||||||
---
|
---
|
||||||
"Get field mapping with t* for fields":
|
"Get field mapping with t* for fields":
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
indices.get_field_mapping:
|
indices.get_field_mapping:
|
||||||
|
index: test_index
|
||||||
field: "t*"
|
field: "t*"
|
||||||
|
|
||||||
# i_t1 matches the pattern using it's index name, but t1 already means a full name
|
# i_t1 matches the pattern using it's index name, but t1 already means a full name
|
||||||
# of a field and thus takes precedence.
|
# of a field and thus takes precedence.
|
||||||
- match: {test_index.test_type.t1.full_name: t1 }
|
- match: {test_index.mappings.test_type.t1.full_name: t1 }
|
||||||
- match: {test_index.test_type.t2.full_name: t2 }
|
- match: {test_index.mappings.test_type.t2.full_name: t2 }
|
||||||
- match: {test_index.test_type.t3.full_name: obj.i_t3 }
|
- match: {test_index.mappings.test_type.t3.full_name: obj.i_t3 }
|
||||||
- length: {test_index.test_type: 3}
|
- length: {test_index.mappings.test_type: 3}
|
||||||
|
|
||||||
---
|
---
|
||||||
"Get field mapping with *t1 for fields":
|
"Get field mapping with *t1 for fields":
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
indices.get_field_mapping:
|
indices.get_field_mapping:
|
||||||
|
index: test_index
|
||||||
field: "*t1"
|
field: "*t1"
|
||||||
- match: {test_index.test_type.t1.full_name: t1 }
|
- match: {test_index.mappings.test_type.t1.full_name: t1 }
|
||||||
- match: {test_index.test_type.obj\.t1.full_name: obj.t1 }
|
- match: {test_index.mappings.test_type.obj\.t1.full_name: obj.t1 }
|
||||||
- match: {test_index.test_type.obj\.i_t1.full_name: obj.i_t1 }
|
- match: {test_index.mappings.test_type.obj\.i_t1.full_name: obj.i_t1 }
|
||||||
- length: {test_index.test_type: 3}
|
- length: {test_index.mappings.test_type: 3}
|
||||||
|
|
||||||
---
|
---
|
||||||
"Get field mapping with wildcarded relative names":
|
"Get field mapping with wildcarded relative names":
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
indices.get_field_mapping:
|
indices.get_field_mapping:
|
||||||
|
index: test_index
|
||||||
field: "i_*"
|
field: "i_*"
|
||||||
- match: {test_index.test_type.i_t1.full_name: obj.i_t1 }
|
- match: {test_index.mappings.test_type.i_t1.full_name: obj.i_t1 }
|
||||||
- match: {test_index.test_type.i_t3.full_name: obj.i_t3 }
|
- match: {test_index.mappings.test_type.i_t3.full_name: obj.i_t3 }
|
||||||
- length: {test_index.test_type: 2}
|
- length: {test_index.mappings.test_type: 2}
|
||||||
|
|
||||||
|
---
|
||||||
|
"Get field mapping should work using '_all' for indices and types":
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.get_field_mapping:
|
||||||
|
index: _all
|
||||||
|
type: _all
|
||||||
|
field: "i_*"
|
||||||
|
- match: {test_index.mappings.test_type.i_t1.full_name: obj.i_t1 }
|
||||||
|
- match: {test_index.mappings.test_type.i_t3.full_name: obj.i_t3 }
|
||||||
|
- length: {test_index.mappings.test_type: 2}
|
||||||
|
- match: {test_index_2.mappings.test_type_2.i_t1.full_name: obj.i_t1 }
|
||||||
|
- match: {test_index_2.mappings.test_type_2.i_t3.full_name: obj.i_t3 }
|
||||||
|
- length: {test_index_2.mappings.test_type_2: 2}
|
||||||
|
|
||||||
|
---
|
||||||
|
"Get field mapping should work using '*' for indices and types":
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.get_field_mapping:
|
||||||
|
index: '*'
|
||||||
|
type: '*'
|
||||||
|
field: "i_*"
|
||||||
|
- match: {test_index.mappings.test_type.i_t1.full_name: obj.i_t1 }
|
||||||
|
- match: {test_index.mappings.test_type.i_t3.full_name: obj.i_t3 }
|
||||||
|
- length: {test_index.mappings.test_type: 2}
|
||||||
|
- match: {test_index_2.mappings.test_type_2.i_t1.full_name: obj.i_t1 }
|
||||||
|
- match: {test_index_2.mappings.test_type_2.i_t3.full_name: obj.i_t3 }
|
||||||
|
- length: {test_index_2.mappings.test_type_2: 2}
|
||||||
|
|
||||||
|
---
|
||||||
|
"Get field mapping should work using comma_separated values for indices and types":
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.get_field_mapping:
|
||||||
|
index: 'test_index,test_index_2'
|
||||||
|
type: 'test_type,test_type_2'
|
||||||
|
field: "i_*"
|
||||||
|
- match: {test_index.mappings.test_type.i_t1.full_name: obj.i_t1 }
|
||||||
|
- match: {test_index.mappings.test_type.i_t3.full_name: obj.i_t3 }
|
||||||
|
- length: {test_index.mappings.test_type: 2}
|
||||||
|
- match: {test_index_2.mappings.test_type_2.i_t1.full_name: obj.i_t1 }
|
||||||
|
- match: {test_index_2.mappings.test_type_2.i_t3.full_name: obj.i_t3 }
|
||||||
|
- length: {test_index_2.mappings.test_type_2: 2}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,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, ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>>> indexEntry : mappings.entrySet()) {
|
for (Map.Entry<String, ImmutableMap<String, ImmutableMap<String, FieldMappingMetaData>>> indexEntry : mappings.entrySet()) {
|
||||||
builder.startObject(indexEntry.getKey(), XContentBuilder.FieldCaseConversion.NONE);
|
builder.startObject(indexEntry.getKey(), XContentBuilder.FieldCaseConversion.NONE);
|
||||||
|
builder.startObject("mappings");
|
||||||
for (Map.Entry<String, ImmutableMap<String, FieldMappingMetaData>> typeEntry : indexEntry.getValue().entrySet()) {
|
for (Map.Entry<String, ImmutableMap<String, FieldMappingMetaData>> typeEntry : indexEntry.getValue().entrySet()) {
|
||||||
builder.startObject(typeEntry.getKey(), XContentBuilder.FieldCaseConversion.NONE);
|
builder.startObject(typeEntry.getKey(), XContentBuilder.FieldCaseConversion.NONE);
|
||||||
for (Map.Entry<String, FieldMappingMetaData> fieldEntry : typeEntry.getValue().entrySet()) {
|
for (Map.Entry<String, FieldMappingMetaData> fieldEntry : typeEntry.getValue().entrySet()) {
|
||||||
|
@ -81,6 +82,7 @@ public class GetFieldMappingsResponse extends ActionResponse implements ToXConte
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
|
builder.endObject();
|
||||||
}
|
}
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,17 +49,18 @@ public class RestGetFieldMappingAction extends BaseRestHandler {
|
||||||
public RestGetFieldMappingAction(Settings settings, Client client, RestController controller) {
|
public RestGetFieldMappingAction(Settings settings, Client client, RestController controller) {
|
||||||
super(settings, client);
|
super(settings, client);
|
||||||
controller.registerHandler(GET, "/_mapping/field/{fields}", this);
|
controller.registerHandler(GET, "/_mapping/field/{fields}", this);
|
||||||
|
controller.registerHandler(GET, "/_mapping/{type}/field/{fields}", this);
|
||||||
controller.registerHandler(GET, "/{index}/_mapping/field/{fields}", this);
|
controller.registerHandler(GET, "/{index}/_mapping/field/{fields}", this);
|
||||||
controller.registerHandler(GET, "/{index}/{type}/_mapping/field/{fields}", this);
|
controller.registerHandler(GET, "/{index}/{type}/_mapping/field/{fields}", this);
|
||||||
|
controller.registerHandler(GET, "/{index}/_mapping/{type}/field/{fields}", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRequest(final RestRequest request, final RestChannel channel) {
|
public void handleRequest(final RestRequest request, final RestChannel channel) {
|
||||||
final String[] indices = Strings.splitStringByCommaToArray(request.param("index"));
|
final String[] indices = Strings.splitStringByCommaToArray(request.param("index"));
|
||||||
final String[] types = Strings.splitStringByCommaToArray(request.param("type"));
|
final String[] types = request.paramAsStringArrayOrEmptyIfAll("type");
|
||||||
boolean local = request.paramAsBooleanOptional("local", false);
|
boolean local = request.paramAsBooleanOptional("local", false);
|
||||||
final String[] fields = Strings.splitStringByCommaToArray(request.param("fields"));
|
final String[] fields = Strings.splitStringByCommaToArray(request.param("fields"));
|
||||||
|
|
||||||
GetFieldMappingsRequest getMappingsRequest = new GetFieldMappingsRequest();
|
GetFieldMappingsRequest getMappingsRequest = new GetFieldMappingsRequest();
|
||||||
getMappingsRequest.indices(indices).types(types).local(local).fields(fields).includeDefaults(request.paramAsBoolean("include_defaults", false));
|
getMappingsRequest.indices(indices).types(types).local(local).fields(fields).includeDefaults(request.paramAsBoolean("include_defaults", false));
|
||||||
getMappingsRequest.indicesOptions(IndicesOptions.fromRequest(request, getMappingsRequest.indicesOptions()));
|
getMappingsRequest.indicesOptions(IndicesOptions.fromRequest(request, getMappingsRequest.indicesOptions()));
|
||||||
|
|
Loading…
Reference in New Issue