Add wildcard support to field resolving in the Get Field Mapping API
Closes #4367
This commit is contained in:
parent
a9e259d438
commit
99b421925f
|
@ -38,7 +38,7 @@ For which the response is (assuming `text` is a default string field):
|
||||||
The get field mapping API can be used to get the mapping of multiple fields from more than one index or type
|
The get field mapping API can be used to get the mapping of multiple fields from more than one index or type
|
||||||
with a single call. General usage of the API follows the
|
with a single call. General usage of the API follows the
|
||||||
following syntax: `host:port/{index}/{type}/_mapping/field/{field}` where
|
following syntax: `host:port/{index}/{type}/_mapping/field/{field}` where
|
||||||
`{index}`, `{type}` and `{field}` can stand for comma-separated list of names. To
|
`{index}`, `{type}` and `{field}` can stand for comma-separated list of names or wild cards. To
|
||||||
get mappings for all indices you can use `_all` for `{index}`. The
|
get mappings for all indices you can use `_all` for `{index}`. The
|
||||||
following are some examples:
|
following are some examples:
|
||||||
|
|
||||||
|
@ -47,12 +47,15 @@ following are some examples:
|
||||||
curl -XGET 'http://localhost:9200/twitter,kimchy/_mapping/field/message'
|
curl -XGET 'http://localhost:9200/twitter,kimchy/_mapping/field/message'
|
||||||
|
|
||||||
curl -XGET 'http://localhost:9200/_all/tweet,book/_mapping/field/message,user.id'
|
curl -XGET 'http://localhost:9200/_all/tweet,book/_mapping/field/message,user.id'
|
||||||
|
|
||||||
|
curl -XGET 'http://localhost:9200/_all/tw*/_mapping/field/*.id'
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
|
||||||
[float]
|
[float]
|
||||||
=== Specifying fields
|
=== Specifying fields
|
||||||
|
|
||||||
The get mapping api allows you to specify fields using any of the following:
|
The get mapping api allows you to specify one or more fields separated with by a comma.
|
||||||
|
You can also use wildcards. The field names can be any of the following:
|
||||||
|
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Full names:: the full path, including any parent object name the field is
|
Full names:: the full path, including any parent object name the field is
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.action.admin.indices.mapping.get;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import org.elasticsearch.ElasticSearchException;
|
import org.elasticsearch.ElasticSearchException;
|
||||||
|
@ -168,22 +169,69 @@ public class TransportGetFieldMappingsAction extends TransportClusterInfoAction<
|
||||||
private ImmutableMap<String, FieldMappingMetaData> findFieldMappingsByType(DocumentMapper documentMapper, String[] fields,
|
private ImmutableMap<String, FieldMappingMetaData> findFieldMappingsByType(DocumentMapper documentMapper, String[] fields,
|
||||||
boolean includeDefaults) throws ElasticSearchException {
|
boolean includeDefaults) throws ElasticSearchException {
|
||||||
MapBuilder<String, FieldMappingMetaData> fieldMappings = new MapBuilder<String, FieldMappingMetaData>();
|
MapBuilder<String, FieldMappingMetaData> fieldMappings = new MapBuilder<String, FieldMappingMetaData>();
|
||||||
|
ImmutableList<FieldMapper> allFieldMappers = documentMapper.mappers().mappers();
|
||||||
for (String field : fields) {
|
for (String field : fields) {
|
||||||
FieldMapper fieldMapper = documentMapper.mappers().smartNameFieldMapper(field);
|
if (Regex.isMatchAllPattern(field)) {
|
||||||
if (fieldMapper != null) {
|
for (FieldMapper fieldMapper : allFieldMappers) {
|
||||||
try {
|
addFieldMapper(fieldMapper.names().fullName(), fieldMapper, fieldMappings, includeDefaults);
|
||||||
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
|
}
|
||||||
builder.startObject();
|
} else if (Regex.isSimpleMatchPattern(field)) {
|
||||||
fieldMapper.toXContent(builder, includeDefaults ? includeDefaultsParams : ToXContent.EMPTY_PARAMS);
|
// go through the field mappers 3 times, to make sure we give preference to the resolve order: full name, index name, name.
|
||||||
builder.endObject();
|
// also make sure we only store each mapper once.
|
||||||
fieldMappings.put(field, new FieldMappingMetaData(fieldMapper.names().fullName(), builder.bytes()));
|
boolean[] resolved = new boolean[allFieldMappers.size()];
|
||||||
} catch (IOException e) {
|
for (int i = 0; i < allFieldMappers.size(); i++) {
|
||||||
throw new ElasticSearchException("failed to serialize XContent of field [" + field + "]", e);
|
FieldMapper fieldMapper = allFieldMappers.get(i);
|
||||||
|
if (Regex.simpleMatch(field, fieldMapper.names().fullName())) {
|
||||||
|
addFieldMapper(fieldMapper.names().fullName(), fieldMapper, fieldMappings, includeDefaults);
|
||||||
|
resolved[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < allFieldMappers.size(); i++) {
|
||||||
|
if (resolved[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
FieldMapper fieldMapper = allFieldMappers.get(i);
|
||||||
|
if (Regex.simpleMatch(field, fieldMapper.names().indexName())) {
|
||||||
|
addFieldMapper(fieldMapper.names().indexName(), fieldMapper, fieldMappings, includeDefaults);
|
||||||
|
resolved[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < allFieldMappers.size(); i++) {
|
||||||
|
if (resolved[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
FieldMapper fieldMapper = allFieldMappers.get(i);
|
||||||
|
if (Regex.simpleMatch(field, fieldMapper.names().name())) {
|
||||||
|
addFieldMapper(fieldMapper.names().name(), fieldMapper, fieldMappings, includeDefaults);
|
||||||
|
resolved[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// not a pattern
|
||||||
|
FieldMapper fieldMapper = documentMapper.mappers().smartNameFieldMapper(field);
|
||||||
|
if (fieldMapper != null) {
|
||||||
|
addFieldMapper(field, fieldMapper, fieldMappings, includeDefaults);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fieldMappings.immutableMap();
|
return fieldMappings.immutableMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addFieldMapper(String field, FieldMapper fieldMapper, MapBuilder<String, FieldMappingMetaData> fieldMappings, boolean includeDefaults) {
|
||||||
|
if (fieldMappings.containsKey(field)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
|
||||||
|
builder.startObject();
|
||||||
|
fieldMapper.toXContent(builder, includeDefaults ? includeDefaultsParams : ToXContent.EMPTY_PARAMS);
|
||||||
|
builder.endObject();
|
||||||
|
fieldMappings.put(field, new FieldMappingMetaData(fieldMapper.names().fullName(), builder.bytes()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ElasticSearchException("failed to serialize XContent of field [" + field + "]", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue