Merge remote-tracking branch 'upstream/master' into feature/seq_no

This commit is contained in:
Boaz Leskes 2015-12-16 11:52:03 +01:00
commit 31afc8a9a5
25 changed files with 356 additions and 246 deletions

View File

@ -29,7 +29,6 @@ import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.routing.ShardRouting; import org.elasticsearch.cluster.routing.ShardRouting;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
@ -48,7 +47,13 @@ import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.query.ParsedQuery; import org.elasticsearch.index.query.ParsedQuery;
import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.shard.*; import org.elasticsearch.index.shard.IndexEventListener;
import org.elasticsearch.index.shard.IndexSearcherWrapper;
import org.elasticsearch.index.shard.IndexShard;
import org.elasticsearch.index.shard.ShadowIndexShard;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.shard.ShardNotFoundException;
import org.elasticsearch.index.shard.ShardPath;
import org.elasticsearch.index.similarity.SimilarityService; import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.index.store.IndexStore; import org.elasticsearch.index.store.IndexStore;
import org.elasticsearch.index.store.Store; import org.elasticsearch.index.store.Store;
@ -73,7 +78,7 @@ import static org.elasticsearch.common.collect.MapBuilder.newMapBuilder;
/** /**
* *
*/ */
public final class IndexService extends AbstractIndexComponent implements IndexComponent, Iterable<IndexShard>{ public final class IndexService extends AbstractIndexComponent implements IndexComponent, Iterable<IndexShard> {
private final IndexEventListener eventListener; private final IndexEventListener eventListener;
private final AnalysisService analysisService; private final AnalysisService analysisService;
@ -93,7 +98,6 @@ public final class IndexService extends AbstractIndexComponent implements IndexC
private final AtomicBoolean deleted = new AtomicBoolean(false); private final AtomicBoolean deleted = new AtomicBoolean(false);
private final IndexSettings indexSettings; private final IndexSettings indexSettings;
@Inject
public IndexService(IndexSettings indexSettings, NodeEnvironment nodeEnv, public IndexService(IndexSettings indexSettings, NodeEnvironment nodeEnv,
SimilarityService similarityService, SimilarityService similarityService,
ShardStoreDeleter shardStoreDeleter, ShardStoreDeleter shardStoreDeleter,
@ -146,7 +150,7 @@ public final class IndexService extends AbstractIndexComponent implements IndexC
*/ */
@Nullable @Nullable
public IndexShard getShardOrNull(int shardId) { public IndexShard getShardOrNull(int shardId) {
return shards.get(shardId); return shards.get(shardId);
} }
/** /**
@ -160,13 +164,17 @@ public final class IndexService extends AbstractIndexComponent implements IndexC
return indexShard; return indexShard;
} }
public Set<Integer> shardIds() { return shards.keySet(); } public Set<Integer> shardIds() {
return shards.keySet();
}
public IndexCache cache() { public IndexCache cache() {
return indexCache; return indexCache;
} }
public IndexFieldDataService fieldData() { return indexFieldData; } public IndexFieldDataService fieldData() {
return indexFieldData;
}
public AnalysisService analysisService() { public AnalysisService analysisService() {
return this.analysisService; return this.analysisService;
@ -207,7 +215,7 @@ public final class IndexService extends AbstractIndexComponent implements IndexC
private long getAvgShardSizeInBytes() throws IOException { private long getAvgShardSizeInBytes() throws IOException {
long sum = 0; long sum = 0;
int count = 0; int count = 0;
for(IndexShard indexShard : this) { for (IndexShard indexShard : this) {
sum += indexShard.store().stats().sizeInBytes(); sum += indexShard.store().stats().sizeInBytes();
count++; count++;
} }
@ -254,17 +262,17 @@ public final class IndexService extends AbstractIndexComponent implements IndexC
// TODO: we should, instead, hold a "bytes reserved" of how large we anticipate this shard will be, e.g. for a shard // TODO: we should, instead, hold a "bytes reserved" of how large we anticipate this shard will be, e.g. for a shard
// that's being relocated/replicated we know how large it will become once it's done copying: // that's being relocated/replicated we know how large it will become once it's done copying:
// Count up how many shards are currently on each data path: // Count up how many shards are currently on each data path:
Map<Path,Integer> dataPathToShardCount = new HashMap<>(); Map<Path, Integer> dataPathToShardCount = new HashMap<>();
for(IndexShard shard : this) { for (IndexShard shard : this) {
Path dataPath = shard.shardPath().getRootStatePath(); Path dataPath = shard.shardPath().getRootStatePath();
Integer curCount = dataPathToShardCount.get(dataPath); Integer curCount = dataPathToShardCount.get(dataPath);
if (curCount == null) { if (curCount == null) {
curCount = 0; curCount = 0;
} }
dataPathToShardCount.put(dataPath, curCount+1); dataPathToShardCount.put(dataPath, curCount + 1);
} }
path = ShardPath.selectNewPathForShard(nodeEnv, shardId, this.indexSettings, routing.getExpectedShardSize() == ShardRouting.UNAVAILABLE_EXPECTED_SHARD_SIZE ? getAvgShardSizeInBytes() : routing.getExpectedShardSize(), path = ShardPath.selectNewPathForShard(nodeEnv, shardId, this.indexSettings, routing.getExpectedShardSize() == ShardRouting.UNAVAILABLE_EXPECTED_SHARD_SIZE ? getAvgShardSizeInBytes() : routing.getExpectedShardSize(),
dataPathToShardCount); dataPathToShardCount);
logger.debug("{} creating using a new path [{}]", shardId, path); logger.debug("{} creating using a new path [{}]", shardId, path);
} else { } else {
logger.debug("{} creating using an existing path [{}]", shardId, path); logger.debug("{} creating using an existing path [{}]", shardId, path);
@ -277,7 +285,7 @@ public final class IndexService extends AbstractIndexComponent implements IndexC
logger.debug("creating shard_id {}", shardId); logger.debug("creating shard_id {}", shardId);
// if we are on a shared FS we only own the shard (ie. we can safely delete it) if we are the primary. // if we are on a shared FS we only own the shard (ie. we can safely delete it) if we are the primary.
final boolean canDeleteShardContent = IndexMetaData.isOnSharedFilesystem(indexSettings) == false || final boolean canDeleteShardContent = IndexMetaData.isOnSharedFilesystem(indexSettings) == false ||
(primary && IndexMetaData.isOnSharedFilesystem(indexSettings)); (primary && IndexMetaData.isOnSharedFilesystem(indexSettings));
store = new Store(shardId, this.indexSettings, indexStore.newDirectoryService(path), lock, new StoreCloseListener(shardId, canDeleteShardContent, () -> nodeServicesProvider.getIndicesQueryCache().onClose(shardId))); store = new Store(shardId, this.indexSettings, indexStore.newDirectoryService(path), lock, new StoreCloseListener(shardId, canDeleteShardContent, () -> nodeServicesProvider.getIndicesQueryCache().onClose(shardId)));
if (useShadowEngine(primary, indexSettings)) { if (useShadowEngine(primary, indexSettings)) {
indexShard = new ShadowIndexShard(shardId, this.indexSettings, path, store, indexCache, mapperService, similarityService, indexFieldData, engineFactory, eventListener, searcherWrapper, nodeServicesProvider); indexShard = new ShadowIndexShard(shardId, this.indexSettings, path, store, indexCache, mapperService, similarityService, indexFieldData, engineFactory, eventListener, searcherWrapper, nodeServicesProvider);
@ -462,6 +470,7 @@ public final class IndexService extends AbstractIndexComponent implements IndexC
} }
} }
} }
/** /**
* Returns the filter associated with listed filtering aliases. * Returns the filter associated with listed filtering aliases.
* <p> * <p>

View File

@ -19,16 +19,9 @@
package org.elasticsearch.index.mapper; package org.elasticsearch.index.mapper;
public class ContentPath { public final class ContentPath {
public enum Type { private static final char DELIMITER = '.';
JUST_NAME,
FULL,
}
private Type pathType;
private final char delimiter;
private final StringBuilder sb; private final StringBuilder sb;
@ -47,7 +40,6 @@ public class ContentPath {
* number of path elements to not be included in {@link #pathAsText(String)}. * number of path elements to not be included in {@link #pathAsText(String)}.
*/ */
public ContentPath(int offset) { public ContentPath(int offset) {
this.delimiter = '.';
this.sb = new StringBuilder(); this.sb = new StringBuilder();
this.offset = offset; this.offset = offset;
reset(); reset();
@ -71,26 +63,11 @@ public class ContentPath {
} }
public String pathAsText(String name) { public String pathAsText(String name) {
if (pathType == Type.JUST_NAME) {
return name;
}
return fullPathAsText(name);
}
public String fullPathAsText(String name) {
sb.setLength(0); sb.setLength(0);
for (int i = offset; i < index; i++) { for (int i = offset; i < index; i++) {
sb.append(path[i]).append(delimiter); sb.append(path[i]).append(DELIMITER);
} }
sb.append(name); sb.append(name);
return sb.toString(); return sb.toString();
} }
public Type pathType() {
return pathType;
}
public void pathType(Type type) {
this.pathType = type;
}
} }

View File

@ -234,9 +234,6 @@ class DocumentParser implements Closeable {
nestedDoc.add(new Field(TypeFieldMapper.NAME, mapper.nestedTypePathAsString(), TypeFieldMapper.Defaults.FIELD_TYPE)); nestedDoc.add(new Field(TypeFieldMapper.NAME, mapper.nestedTypePathAsString(), TypeFieldMapper.Defaults.FIELD_TYPE));
} }
ContentPath.Type origPathType = context.path().pathType();
context.path().pathType(mapper.pathType());
// if we are at the end of the previous object, advance // if we are at the end of the previous object, advance
if (token == XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.END_OBJECT) {
token = parser.nextToken(); token = parser.nextToken();
@ -272,7 +269,6 @@ class DocumentParser implements Closeable {
} }
} }
// restore the enable path flag // restore the enable path flag
context.path().pathType(origPathType);
if (nested.isNested()) { if (nested.isNested()) {
ParseContext.Document nestedDoc = context.doc(); ParseContext.Document nestedDoc = context.doc();
ParseContext.Document parentDoc = nestedDoc.getParent(); ParseContext.Document parentDoc = nestedDoc.getParent();
@ -341,7 +337,7 @@ class DocumentParser implements Closeable {
context.path().remove(); context.path().remove();
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "object"); Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "object");
if (builder == null) { if (builder == null) {
builder = MapperBuilders.object(currentFieldName).enabled(true).pathType(mapper.pathType()); builder = MapperBuilders.object(currentFieldName).enabled(true);
// if this is a non root object, then explicitly set the dynamic behavior if set // if this is a non root object, then explicitly set the dynamic behavior if set
if (!(mapper instanceof RootObjectMapper) && mapper.dynamic() != ObjectMapper.Defaults.DYNAMIC) { if (!(mapper instanceof RootObjectMapper) && mapper.dynamic() != ObjectMapper.Defaults.DYNAMIC) {
((ObjectMapper.Builder) builder).dynamic(mapper.dynamic()); ((ObjectMapper.Builder) builder).dynamic(mapper.dynamic());
@ -610,7 +606,7 @@ class DocumentParser implements Closeable {
return null; return null;
} }
final Mapper.BuilderContext builderContext = new Mapper.BuilderContext(context.indexSettings(), context.path()); final Mapper.BuilderContext builderContext = new Mapper.BuilderContext(context.indexSettings(), context.path());
final MappedFieldType existingFieldType = context.mapperService().fullName(context.path().fullPathAsText(currentFieldName)); final MappedFieldType existingFieldType = context.mapperService().fullName(context.path().pathAsText(currentFieldName));
Mapper.Builder builder = null; Mapper.Builder builder = null;
if (existingFieldType != null) { if (existingFieldType != null) {
// create a builder of the same type // create a builder of the same type
@ -695,7 +691,7 @@ class DocumentParser implements Closeable {
if (paths.length > 1) { if (paths.length > 1) {
ObjectMapper parent = context.root(); ObjectMapper parent = context.root();
for (int i = 0; i < paths.length-1; i++) { for (int i = 0; i < paths.length-1; i++) {
mapper = context.docMapper().objectMappers().get(context.path().fullPathAsText(paths[i])); mapper = context.docMapper().objectMappers().get(context.path().pathAsText(paths[i]));
if (mapper == null) { if (mapper == null) {
// One mapping is missing, check if we are allowed to create a dynamic one. // One mapping is missing, check if we are allowed to create a dynamic one.
ObjectMapper.Dynamic dynamic = parent.dynamic(); ObjectMapper.Dynamic dynamic = parent.dynamic();
@ -713,12 +709,12 @@ class DocumentParser implements Closeable {
if (!(parent instanceof RootObjectMapper) && parent.dynamic() != ObjectMapper.Defaults.DYNAMIC) { if (!(parent instanceof RootObjectMapper) && parent.dynamic() != ObjectMapper.Defaults.DYNAMIC) {
((ObjectMapper.Builder) builder).dynamic(parent.dynamic()); ((ObjectMapper.Builder) builder).dynamic(parent.dynamic());
} }
builder = MapperBuilders.object(paths[i]).enabled(true).pathType(parent.pathType()); builder = MapperBuilders.object(paths[i]).enabled(true);
} }
Mapper.BuilderContext builderContext = new Mapper.BuilderContext(context.indexSettings(), context.path()); Mapper.BuilderContext builderContext = new Mapper.BuilderContext(context.indexSettings(), context.path());
mapper = (ObjectMapper) builder.build(builderContext); mapper = (ObjectMapper) builder.build(builderContext);
if (mapper.nested() != ObjectMapper.Nested.NO) { if (mapper.nested() != ObjectMapper.Nested.NO) {
throw new MapperParsingException("It is forbidden to create dynamic nested objects ([" + context.path().fullPathAsText(paths[i]) + "]) through `copy_to`"); throw new MapperParsingException("It is forbidden to create dynamic nested objects ([" + context.path().pathAsText(paths[i]) + "]) through `copy_to`");
} }
break; break;
case FALSE: case FALSE:

View File

@ -207,11 +207,6 @@ public abstract class FieldMapper extends Mapper implements Cloneable {
return this; return this;
} }
public T multiFieldPathType(ContentPath.Type pathType) {
multiFieldsBuilder.pathType(pathType);
return builder;
}
public T addMultiField(Mapper.Builder mapperBuilder) { public T addMultiField(Mapper.Builder mapperBuilder) {
multiFieldsBuilder.add(mapperBuilder); multiFieldsBuilder.add(mapperBuilder);
return builder; return builder;
@ -242,7 +237,7 @@ public abstract class FieldMapper extends Mapper implements Cloneable {
} }
protected String buildFullName(BuilderContext context) { protected String buildFullName(BuilderContext context) {
return context.path().fullPathAsText(name); return context.path().pathAsText(name);
} }
protected void setupFieldType(BuilderContext context) { protected void setupFieldType(BuilderContext context) {
@ -540,18 +535,12 @@ public abstract class FieldMapper extends Mapper implements Cloneable {
public static class MultiFields { public static class MultiFields {
public static MultiFields empty() { public static MultiFields empty() {
return new MultiFields(ContentPath.Type.FULL, ImmutableOpenMap.<String, FieldMapper>of()); return new MultiFields(ImmutableOpenMap.<String, FieldMapper>of());
} }
public static class Builder { public static class Builder {
private final ImmutableOpenMap.Builder<String, Mapper.Builder> mapperBuilders = ImmutableOpenMap.builder(); private final ImmutableOpenMap.Builder<String, Mapper.Builder> mapperBuilders = ImmutableOpenMap.builder();
private ContentPath.Type pathType = ContentPath.Type.FULL;
public Builder pathType(ContentPath.Type pathType) {
this.pathType = pathType;
return this;
}
public Builder add(Mapper.Builder builder) { public Builder add(Mapper.Builder builder) {
mapperBuilders.put(builder.name(), builder); mapperBuilders.put(builder.name(), builder);
@ -560,13 +549,9 @@ public abstract class FieldMapper extends Mapper implements Cloneable {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public MultiFields build(FieldMapper.Builder mainFieldBuilder, BuilderContext context) { public MultiFields build(FieldMapper.Builder mainFieldBuilder, BuilderContext context) {
if (pathType == ContentPath.Type.FULL && mapperBuilders.isEmpty()) { if (mapperBuilders.isEmpty()) {
return empty(); return empty();
} else if (mapperBuilders.isEmpty()) {
return new MultiFields(pathType, ImmutableOpenMap.<String, FieldMapper>of());
} else { } else {
ContentPath.Type origPathType = context.path().pathType();
context.path().pathType(pathType);
context.path().add(mainFieldBuilder.name()); context.path().add(mainFieldBuilder.name());
ImmutableOpenMap.Builder mapperBuilders = this.mapperBuilders; ImmutableOpenMap.Builder mapperBuilders = this.mapperBuilders;
for (ObjectObjectCursor<String, Mapper.Builder> cursor : this.mapperBuilders) { for (ObjectObjectCursor<String, Mapper.Builder> cursor : this.mapperBuilders) {
@ -577,18 +562,15 @@ public abstract class FieldMapper extends Mapper implements Cloneable {
mapperBuilders.put(key, mapper); mapperBuilders.put(key, mapper);
} }
context.path().remove(); context.path().remove();
context.path().pathType(origPathType);
ImmutableOpenMap.Builder<String, FieldMapper> mappers = mapperBuilders.cast(); ImmutableOpenMap.Builder<String, FieldMapper> mappers = mapperBuilders.cast();
return new MultiFields(pathType, mappers.build()); return new MultiFields(mappers.build());
} }
} }
} }
private final ContentPath.Type pathType;
private final ImmutableOpenMap<String, FieldMapper> mappers; private final ImmutableOpenMap<String, FieldMapper> mappers;
private MultiFields(ContentPath.Type pathType, ImmutableOpenMap<String, FieldMapper> mappers) { private MultiFields(ImmutableOpenMap<String, FieldMapper> mappers) {
this.pathType = pathType;
ImmutableOpenMap.Builder<String, FieldMapper> builder = new ImmutableOpenMap.Builder<>(); ImmutableOpenMap.Builder<String, FieldMapper> builder = new ImmutableOpenMap.Builder<>();
// we disable the all in multi-field mappers // we disable the all in multi-field mappers
for (ObjectObjectCursor<String, FieldMapper> cursor : mappers) { for (ObjectObjectCursor<String, FieldMapper> cursor : mappers) {
@ -609,21 +591,14 @@ public abstract class FieldMapper extends Mapper implements Cloneable {
context = context.createMultiFieldContext(); context = context.createMultiFieldContext();
ContentPath.Type origPathType = context.path().pathType();
context.path().pathType(pathType);
context.path().add(mainField.simpleName()); context.path().add(mainField.simpleName());
for (ObjectCursor<FieldMapper> cursor : mappers.values()) { for (ObjectCursor<FieldMapper> cursor : mappers.values()) {
cursor.value.parse(context); cursor.value.parse(context);
} }
context.path().remove(); context.path().remove();
context.path().pathType(origPathType);
} }
public MultiFields merge(MultiFields mergeWith) { public MultiFields merge(MultiFields mergeWith) {
if (pathType != mergeWith.pathType) {
throw new IllegalArgumentException("Can't change path type from [" + pathType + "] to [" + mergeWith.pathType + "]");
}
ImmutableOpenMap.Builder<String, FieldMapper> newMappersBuilder = ImmutableOpenMap.builder(mappers); ImmutableOpenMap.Builder<String, FieldMapper> newMappersBuilder = ImmutableOpenMap.builder(mappers);
for (ObjectCursor<FieldMapper> cursor : mergeWith.mappers.values()) { for (ObjectCursor<FieldMapper> cursor : mergeWith.mappers.values()) {
@ -642,7 +617,7 @@ public abstract class FieldMapper extends Mapper implements Cloneable {
} }
ImmutableOpenMap<String, FieldMapper> mappers = newMappersBuilder.build(); ImmutableOpenMap<String, FieldMapper> mappers = newMappersBuilder.build();
return new MultiFields(pathType, mappers); return new MultiFields(mappers);
} }
public Iterator<Mapper> iterator() { public Iterator<Mapper> iterator() {
@ -650,9 +625,6 @@ public abstract class FieldMapper extends Mapper implements Cloneable {
} }
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
if (pathType != ContentPath.Type.FULL) {
builder.field("path", pathType.name().toLowerCase(Locale.ROOT));
}
if (!mappers.isEmpty()) { if (!mappers.isEmpty()) {
// sort the mappers so we get consistent serialization format // sort the mappers so we get consistent serialization format
Mapper[] sortedMappers = mappers.values().toArray(Mapper.class); Mapper[] sortedMappers = mappers.values().toArray(Mapper.class);

View File

@ -338,7 +338,7 @@ public class MapperService extends AbstractIndexComponent implements Closeable {
for (FieldMapper fieldMapper : fieldMappers) { for (FieldMapper fieldMapper : fieldMappers) {
if (fullPathObjectMappers.containsKey(fieldMapper.name())) { if (fullPathObjectMappers.containsKey(fieldMapper.name())) {
throw new IllegalArgumentException("Field [{}] is defined as a field in mapping [" + fieldMapper.name() + "] but this name is already used for an object in other types"); throw new IllegalArgumentException("Field [" + fieldMapper.name() + "] is defined as a field in mapping [" + type + "] but this name is already used for an object in other types");
} }
} }

View File

@ -61,7 +61,6 @@ public class TypeParsers {
@Override @Override
public Mapper.Builder<?, ?> parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException { public Mapper.Builder<?, ?> parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
ContentPath.Type pathType = null;
FieldMapper.Builder mainFieldBuilder = null; FieldMapper.Builder mainFieldBuilder = null;
List<FieldMapper.Builder> fields = null; List<FieldMapper.Builder> fields = null;
String firstType = null; String firstType = null;
@ -70,10 +69,7 @@ public class TypeParsers {
Map.Entry<String, Object> entry = iterator.next(); Map.Entry<String, Object> entry = iterator.next();
String fieldName = Strings.toUnderscoreCase(entry.getKey()); String fieldName = Strings.toUnderscoreCase(entry.getKey());
Object fieldNode = entry.getValue(); Object fieldNode = entry.getValue();
if (fieldName.equals("path") && parserContext.indexVersionCreated().before(Version.V_2_0_0_beta1)) { if (fieldName.equals("fields")) {
pathType = parsePathType(name, fieldNode.toString());
iterator.remove();
} else if (fieldName.equals("fields")) {
Map<String, Object> fieldsNode = (Map<String, Object>) fieldNode; Map<String, Object> fieldsNode = (Map<String, Object>) fieldNode;
for (Iterator<Map.Entry<String, Object>> fieldsIterator = fieldsNode.entrySet().iterator(); fieldsIterator.hasNext();) { for (Iterator<Map.Entry<String, Object>> fieldsIterator = fieldsNode.entrySet().iterator(); fieldsIterator.hasNext();) {
Map.Entry<String, Object> entry1 = fieldsIterator.next(); Map.Entry<String, Object> entry1 = fieldsIterator.next();
@ -132,17 +128,10 @@ public class TypeParsers {
} }
} }
if (fields != null && pathType != null) { if (fields != null) {
for (Mapper.Builder field : fields) { for (Mapper.Builder field : fields) {
mainFieldBuilder.addMultiField(field); mainFieldBuilder.addMultiField(field);
} }
mainFieldBuilder.multiFieldPathType(pathType);
} else if (fields != null) {
for (Mapper.Builder field : fields) {
mainFieldBuilder.addMultiField(field);
}
} else if (pathType != null) {
mainFieldBuilder.multiFieldPathType(pathType);
} }
return mainFieldBuilder; return mainFieldBuilder;
} }
@ -337,10 +326,7 @@ public class TypeParsers {
public static boolean parseMultiField(FieldMapper.Builder builder, String name, Mapper.TypeParser.ParserContext parserContext, String propName, Object propNode) { public static boolean parseMultiField(FieldMapper.Builder builder, String name, Mapper.TypeParser.ParserContext parserContext, String propName, Object propNode) {
parserContext = parserContext.createMultiFieldContext(parserContext); parserContext = parserContext.createMultiFieldContext(parserContext);
if (propName.equals("path") && parserContext.indexVersionCreated().before(Version.V_2_0_0_beta1)) { if (propName.equals("fields")) {
builder.multiFieldPathType(parsePathType(name, propNode.toString()));
return true;
} else if (propName.equals("fields")) {
final Map<String, Object> multiFieldsPropNodes; final Map<String, Object> multiFieldsPropNodes;
@ -457,17 +443,6 @@ public class TypeParsers {
} }
} }
public static ContentPath.Type parsePathType(String name, String path) throws MapperParsingException {
path = Strings.toUnderscoreCase(path);
if ("just_name".equals(path)) {
return ContentPath.Type.JUST_NAME;
} else if ("full".equals(path)) {
return ContentPath.Type.FULL;
} else {
throw new MapperParsingException("wrong value for pathType [" + path + "] for object [" + name + "]");
}
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static void parseCopyFields(Object propNode, FieldMapper.Builder builder) { public static void parseCopyFields(Object propNode, FieldMapper.Builder builder) {
FieldMapper.CopyTo.Builder copyToBuilder = new FieldMapper.CopyTo.Builder(); FieldMapper.CopyTo.Builder copyToBuilder = new FieldMapper.CopyTo.Builder();

View File

@ -33,7 +33,6 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.index.mapper.ContentPath;
import org.elasticsearch.index.mapper.FieldMapper; import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.index.mapper.Mapper;
@ -73,7 +72,6 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr
} }
public static class Defaults { public static class Defaults {
public static final ContentPath.Type PATH_TYPE = ContentPath.Type.FULL;
public static final boolean ENABLE_LATLON = false; public static final boolean ENABLE_LATLON = false;
public static final boolean ENABLE_GEOHASH = false; public static final boolean ENABLE_GEOHASH = false;
public static final boolean ENABLE_GEOHASH_PREFIX = false; public static final boolean ENABLE_GEOHASH_PREFIX = false;
@ -82,7 +80,6 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr
} }
public abstract static class Builder<T extends Builder, Y extends BaseGeoPointFieldMapper> extends FieldMapper.Builder<T, Y> { public abstract static class Builder<T extends Builder, Y extends BaseGeoPointFieldMapper> extends FieldMapper.Builder<T, Y> {
protected ContentPath.Type pathType = Defaults.PATH_TYPE;
protected boolean enableLatLon = Defaults.ENABLE_LATLON; protected boolean enableLatLon = Defaults.ENABLE_LATLON;
@ -105,12 +102,6 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr
return (GeoPointFieldType)fieldType; return (GeoPointFieldType)fieldType;
} }
@Override
public T multiFieldPathType(ContentPath.Type pathType) {
this.pathType = pathType;
return builder;
}
@Override @Override
public T fieldDataSettings(Settings settings) { public T fieldDataSettings(Settings settings) {
this.fieldDataSettings = settings; this.fieldDataSettings = settings;
@ -158,13 +149,10 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr
} }
public abstract Y build(BuilderContext context, String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType, public abstract Y build(BuilderContext context, String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType,
Settings indexSettings, ContentPath.Type pathType, DoubleFieldMapper latMapper, DoubleFieldMapper lonMapper, Settings indexSettings, DoubleFieldMapper latMapper, DoubleFieldMapper lonMapper,
StringFieldMapper geoHashMapper, MultiFields multiFields, Explicit<Boolean> ignoreMalformed, CopyTo copyTo); StringFieldMapper geoHashMapper, MultiFields multiFields, Explicit<Boolean> ignoreMalformed, CopyTo copyTo);
public Y build(Mapper.BuilderContext context) { public Y build(Mapper.BuilderContext context) {
ContentPath.Type origPathType = context.path().pathType();
context.path().pathType(pathType);
GeoPointFieldType geoPointFieldType = (GeoPointFieldType)fieldType; GeoPointFieldType geoPointFieldType = (GeoPointFieldType)fieldType;
DoubleFieldMapper latMapper = null; DoubleFieldMapper latMapper = null;
@ -190,9 +178,8 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr
geoPointFieldType.setGeoHashEnabled(geoHashMapper.fieldType(), geoHashPrecision, enableGeoHashPrefix); geoPointFieldType.setGeoHashEnabled(geoHashMapper.fieldType(), geoHashPrecision, enableGeoHashPrefix);
} }
context.path().remove(); context.path().remove();
context.path().pathType(origPathType);
return build(context, name, fieldType, defaultFieldType, context.indexSettings(), origPathType, return build(context, name, fieldType, defaultFieldType, context.indexSettings(),
latMapper, lonMapper, geoHashMapper, multiFieldsBuilder.build(this, context), ignoreMalformed(context), copyTo); latMapper, lonMapper, geoHashMapper, multiFieldsBuilder.build(this, context), ignoreMalformed(context), copyTo);
} }
} }
@ -364,17 +351,14 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr
protected final DoubleFieldMapper lonMapper; protected final DoubleFieldMapper lonMapper;
protected final ContentPath.Type pathType;
protected final StringFieldMapper geoHashMapper; protected final StringFieldMapper geoHashMapper;
protected Explicit<Boolean> ignoreMalformed; protected Explicit<Boolean> ignoreMalformed;
protected BaseGeoPointFieldMapper(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType, Settings indexSettings, protected BaseGeoPointFieldMapper(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType, Settings indexSettings,
ContentPath.Type pathType, DoubleFieldMapper latMapper, DoubleFieldMapper lonMapper, StringFieldMapper geoHashMapper, DoubleFieldMapper latMapper, DoubleFieldMapper lonMapper, StringFieldMapper geoHashMapper,
MultiFields multiFields, Explicit<Boolean> ignoreMalformed, CopyTo copyTo) { MultiFields multiFields, Explicit<Boolean> ignoreMalformed, CopyTo copyTo) {
super(simpleName, fieldType, defaultFieldType, indexSettings, multiFields, copyTo); super(simpleName, fieldType, defaultFieldType, indexSettings, multiFields, copyTo);
this.pathType = pathType;
this.latMapper = latMapper; this.latMapper = latMapper;
this.lonMapper = lonMapper; this.lonMapper = lonMapper;
this.geoHashMapper = geoHashMapper; this.geoHashMapper = geoHashMapper;
@ -434,8 +418,6 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr
@Override @Override
public Mapper parse(ParseContext context) throws IOException { public Mapper parse(ParseContext context) throws IOException {
ContentPath.Type origPathType = context.path().pathType();
context.path().pathType(pathType);
context.path().add(simpleName()); context.path().add(simpleName());
GeoPoint sparse = context.parseExternalValue(GeoPoint.class); GeoPoint sparse = context.parseExternalValue(GeoPoint.class);
@ -480,7 +462,6 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr
} }
context.path().remove(); context.path().remove();
context.path().pathType(origPathType);
return null; return null;
} }
@ -505,9 +486,6 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr
@Override @Override
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException { protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
super.doXContentBody(builder, includeDefaults, params); super.doXContentBody(builder, includeDefaults, params);
if (includeDefaults || pathType != Defaults.PATH_TYPE) {
builder.field("path", pathType.name().toLowerCase(Locale.ROOT));
}
if (includeDefaults || fieldType().isLatLonEnabled() != GeoPointFieldMapper.Defaults.ENABLE_LATLON) { if (includeDefaults || fieldType().isLatLonEnabled() != GeoPointFieldMapper.Defaults.ENABLE_LATLON) {
builder.field("lat_lon", fieldType().isLatLonEnabled()); builder.field("lat_lon", fieldType().isLatLonEnabled());
} }

View File

@ -27,7 +27,6 @@ import org.elasticsearch.common.Explicit;
import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils; import org.elasticsearch.common.geo.GeoUtils;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.mapper.ContentPath;
import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.MapperParsingException;
@ -81,12 +80,12 @@ public class GeoPointFieldMapper extends BaseGeoPointFieldMapper {
@Override @Override
public GeoPointFieldMapper build(BuilderContext context, String simpleName, MappedFieldType fieldType, public GeoPointFieldMapper build(BuilderContext context, String simpleName, MappedFieldType fieldType,
MappedFieldType defaultFieldType, Settings indexSettings, ContentPath.Type pathType, DoubleFieldMapper latMapper, MappedFieldType defaultFieldType, Settings indexSettings, DoubleFieldMapper latMapper,
DoubleFieldMapper lonMapper, StringFieldMapper geoHashMapper, MultiFields multiFields, Explicit<Boolean> ignoreMalformed, DoubleFieldMapper lonMapper, StringFieldMapper geoHashMapper, MultiFields multiFields, Explicit<Boolean> ignoreMalformed,
CopyTo copyTo) { CopyTo copyTo) {
fieldType.setTokenized(false); fieldType.setTokenized(false);
setupFieldType(context); setupFieldType(context);
return new GeoPointFieldMapper(simpleName, fieldType, defaultFieldType, indexSettings, pathType, latMapper, lonMapper, return new GeoPointFieldMapper(simpleName, fieldType, defaultFieldType, indexSettings, latMapper, lonMapper,
geoHashMapper, multiFields, ignoreMalformed, copyTo); geoHashMapper, multiFields, ignoreMalformed, copyTo);
} }
@ -104,9 +103,9 @@ public class GeoPointFieldMapper extends BaseGeoPointFieldMapper {
} }
public GeoPointFieldMapper(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType, Settings indexSettings, public GeoPointFieldMapper(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType, Settings indexSettings,
ContentPath.Type pathType, DoubleFieldMapper latMapper, DoubleFieldMapper lonMapper, DoubleFieldMapper latMapper, DoubleFieldMapper lonMapper,
StringFieldMapper geoHashMapper, MultiFields multiFields, Explicit<Boolean> ignoreMalformed, CopyTo copyTo) { StringFieldMapper geoHashMapper, MultiFields multiFields, Explicit<Boolean> ignoreMalformed, CopyTo copyTo) {
super(simpleName, fieldType, defaultFieldType, indexSettings, pathType, latMapper, lonMapper, geoHashMapper, multiFields, super(simpleName, fieldType, defaultFieldType, indexSettings, latMapper, lonMapper, geoHashMapper, multiFields,
ignoreMalformed, copyTo); ignoreMalformed, copyTo);
} }

View File

@ -35,7 +35,6 @@ import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.common.util.ByteUtils; import org.elasticsearch.common.util.ByteUtils;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.index.mapper.ContentPath;
import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.MapperParsingException;
@ -110,14 +109,14 @@ public class GeoPointFieldMapperLegacy extends BaseGeoPointFieldMapper implement
@Override @Override
public GeoPointFieldMapperLegacy build(BuilderContext context, String simpleName, MappedFieldType fieldType, public GeoPointFieldMapperLegacy build(BuilderContext context, String simpleName, MappedFieldType fieldType,
MappedFieldType defaultFieldType, Settings indexSettings, ContentPath.Type pathType, DoubleFieldMapper latMapper, MappedFieldType defaultFieldType, Settings indexSettings, DoubleFieldMapper latMapper,
DoubleFieldMapper lonMapper, StringFieldMapper geoHashMapper, MultiFields multiFields, Explicit<Boolean> ignoreMalformed, DoubleFieldMapper lonMapper, StringFieldMapper geoHashMapper, MultiFields multiFields, Explicit<Boolean> ignoreMalformed,
CopyTo copyTo) { CopyTo copyTo) {
fieldType.setTokenized(false); fieldType.setTokenized(false);
setupFieldType(context); setupFieldType(context);
fieldType.setHasDocValues(false); fieldType.setHasDocValues(false);
defaultFieldType.setHasDocValues(false); defaultFieldType.setHasDocValues(false);
return new GeoPointFieldMapperLegacy(simpleName, fieldType, defaultFieldType, indexSettings, pathType, latMapper, lonMapper, return new GeoPointFieldMapperLegacy(simpleName, fieldType, defaultFieldType, indexSettings, latMapper, lonMapper,
geoHashMapper, multiFields, ignoreMalformed, coerce(context), copyTo); geoHashMapper, multiFields, ignoreMalformed, coerce(context), copyTo);
} }
@ -287,10 +286,10 @@ public class GeoPointFieldMapperLegacy extends BaseGeoPointFieldMapper implement
protected Explicit<Boolean> coerce; protected Explicit<Boolean> coerce;
public GeoPointFieldMapperLegacy(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType, Settings indexSettings, public GeoPointFieldMapperLegacy(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType, Settings indexSettings,
ContentPath.Type pathType, DoubleFieldMapper latMapper, DoubleFieldMapper lonMapper, DoubleFieldMapper latMapper, DoubleFieldMapper lonMapper,
StringFieldMapper geoHashMapper, MultiFields multiFields, Explicit<Boolean> ignoreMalformed, StringFieldMapper geoHashMapper, MultiFields multiFields, Explicit<Boolean> ignoreMalformed,
Explicit<Boolean> coerce, CopyTo copyTo) { Explicit<Boolean> coerce, CopyTo copyTo) {
super(simpleName, fieldType, defaultFieldType, indexSettings, pathType, latMapper, lonMapper, geoHashMapper, multiFields, super(simpleName, fieldType, defaultFieldType, indexSettings, latMapper, lonMapper, geoHashMapper, multiFields,
ignoreMalformed, copyTo); ignoreMalformed, copyTo);
this.coerce = coerce; this.coerce = coerce;
} }

View File

@ -125,13 +125,13 @@ public class DynamicTemplate {
} }
public boolean match(ContentPath path, String name, String dynamicType) { public boolean match(ContentPath path, String name, String dynamicType) {
if (pathMatch != null && !patternMatch(pathMatch, path.fullPathAsText(name))) { if (pathMatch != null && !patternMatch(pathMatch, path.pathAsText(name))) {
return false; return false;
} }
if (match != null && !patternMatch(match, name)) { if (match != null && !patternMatch(match, name)) {
return false; return false;
} }
if (pathUnmatch != null && patternMatch(pathUnmatch, path.fullPathAsText(name))) { if (pathUnmatch != null && patternMatch(pathUnmatch, path.pathAsText(name))) {
return false; return false;
} }
if (unmatch != null && patternMatch(unmatch, name)) { if (unmatch != null && patternMatch(unmatch, name)) {

View File

@ -24,7 +24,6 @@ import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TermQuery;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.Version;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.CopyOnWriteHashMap; import org.elasticsearch.common.collect.CopyOnWriteHashMap;
@ -40,7 +39,6 @@ import java.util.*;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue; import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue;
import static org.elasticsearch.index.mapper.MapperBuilders.object; import static org.elasticsearch.index.mapper.MapperBuilders.object;
import static org.elasticsearch.index.mapper.core.TypeParsers.parsePathType;
/** /**
* *
@ -54,7 +52,6 @@ public class ObjectMapper extends Mapper implements AllFieldMapper.IncludeInAll,
public static final boolean ENABLED = true; public static final boolean ENABLED = true;
public static final Nested NESTED = Nested.NO; public static final Nested NESTED = Nested.NO;
public static final Dynamic DYNAMIC = null; // not set, inherited from root public static final Dynamic DYNAMIC = null; // not set, inherited from root
public static final ContentPath.Type PATH_TYPE = ContentPath.Type.FULL;
} }
public static enum Dynamic { public static enum Dynamic {
@ -104,8 +101,6 @@ public class ObjectMapper extends Mapper implements AllFieldMapper.IncludeInAll,
protected Dynamic dynamic = Defaults.DYNAMIC; protected Dynamic dynamic = Defaults.DYNAMIC;
protected ContentPath.Type pathType = Defaults.PATH_TYPE;
protected Boolean includeInAll; protected Boolean includeInAll;
protected final List<Mapper.Builder> mappersBuilders = new ArrayList<>(); protected final List<Mapper.Builder> mappersBuilders = new ArrayList<>();
@ -130,11 +125,6 @@ public class ObjectMapper extends Mapper implements AllFieldMapper.IncludeInAll,
return builder; return builder;
} }
public T pathType(ContentPath.Type pathType) {
this.pathType = pathType;
return builder;
}
public T includeInAll(boolean includeInAll) { public T includeInAll(boolean includeInAll) {
this.includeInAll = includeInAll; this.includeInAll = includeInAll;
return builder; return builder;
@ -147,8 +137,6 @@ public class ObjectMapper extends Mapper implements AllFieldMapper.IncludeInAll,
@Override @Override
public Y build(BuilderContext context) { public Y build(BuilderContext context) {
ContentPath.Type origPathType = context.path().pathType();
context.path().pathType(pathType);
context.path().add(name); context.path().add(name);
Map<String, Mapper> mappers = new HashMap<>(); Map<String, Mapper> mappers = new HashMap<>();
@ -156,17 +144,16 @@ public class ObjectMapper extends Mapper implements AllFieldMapper.IncludeInAll,
Mapper mapper = builder.build(context); Mapper mapper = builder.build(context);
mappers.put(mapper.simpleName(), mapper); mappers.put(mapper.simpleName(), mapper);
} }
context.path().pathType(origPathType);
context.path().remove(); context.path().remove();
ObjectMapper objectMapper = createMapper(name, context.path().fullPathAsText(name), enabled, nested, dynamic, pathType, mappers, context.indexSettings()); ObjectMapper objectMapper = createMapper(name, context.path().pathAsText(name), enabled, nested, dynamic, mappers, context.indexSettings());
objectMapper = objectMapper.includeInAllIfNotSet(includeInAll); objectMapper = objectMapper.includeInAllIfNotSet(includeInAll);
return (Y) objectMapper; return (Y) objectMapper;
} }
protected ObjectMapper createMapper(String name, String fullPath, boolean enabled, Nested nested, Dynamic dynamic, ContentPath.Type pathType, Map<String, Mapper> mappers, @Nullable Settings settings) { protected ObjectMapper createMapper(String name, String fullPath, boolean enabled, Nested nested, Dynamic dynamic, Map<String, Mapper> mappers, @Nullable Settings settings) {
return new ObjectMapper(name, fullPath, enabled, nested, dynamic, pathType, mappers); return new ObjectMapper(name, fullPath, enabled, nested, dynamic, mappers);
} }
} }
@ -179,7 +166,7 @@ public class ObjectMapper extends Mapper implements AllFieldMapper.IncludeInAll,
Map.Entry<String, Object> entry = iterator.next(); Map.Entry<String, Object> entry = iterator.next();
String fieldName = Strings.toUnderscoreCase(entry.getKey()); String fieldName = Strings.toUnderscoreCase(entry.getKey());
Object fieldNode = entry.getValue(); Object fieldNode = entry.getValue();
if (parseObjectOrDocumentTypeProperties(fieldName, fieldNode, parserContext, builder) || parseObjectProperties(name, fieldName, fieldNode, parserContext, builder)) { if (parseObjectOrDocumentTypeProperties(fieldName, fieldNode, parserContext, builder)) {
iterator.remove(); iterator.remove();
} }
} }
@ -214,14 +201,6 @@ public class ObjectMapper extends Mapper implements AllFieldMapper.IncludeInAll,
return false; return false;
} }
protected static boolean parseObjectProperties(String name, String fieldName, Object fieldNode, ParserContext parserContext, ObjectMapper.Builder builder) {
if (fieldName.equals("path") && parserContext.indexVersionCreated().before(Version.V_2_0_0_beta1)) {
builder.pathType(parsePathType(name, fieldNode.toString()));
return true;
}
return false;
}
protected static void parseNested(String name, Map<String, Object> node, ObjectMapper.Builder builder) { protected static void parseNested(String name, Map<String, Object> node, ObjectMapper.Builder builder) {
boolean nested = false; boolean nested = false;
boolean nestedIncludeInParent = false; boolean nestedIncludeInParent = false;
@ -326,19 +305,16 @@ public class ObjectMapper extends Mapper implements AllFieldMapper.IncludeInAll,
private volatile Dynamic dynamic; private volatile Dynamic dynamic;
private final ContentPath.Type pathType;
private Boolean includeInAll; private Boolean includeInAll;
private volatile CopyOnWriteHashMap<String, Mapper> mappers; private volatile CopyOnWriteHashMap<String, Mapper> mappers;
ObjectMapper(String name, String fullPath, boolean enabled, Nested nested, Dynamic dynamic, ContentPath.Type pathType, Map<String, Mapper> mappers) { ObjectMapper(String name, String fullPath, boolean enabled, Nested nested, Dynamic dynamic, Map<String, Mapper> mappers) {
super(name); super(name);
this.fullPath = fullPath; this.fullPath = fullPath;
this.enabled = enabled; this.enabled = enabled;
this.nested = nested; this.nested = nested;
this.dynamic = dynamic; this.dynamic = dynamic;
this.pathType = pathType;
if (mappers == null) { if (mappers == null) {
this.mappers = new CopyOnWriteHashMap<>(); this.mappers = new CopyOnWriteHashMap<>();
} else { } else {
@ -380,10 +356,6 @@ public class ObjectMapper extends Mapper implements AllFieldMapper.IncludeInAll,
return this.enabled; return this.enabled;
} }
public ContentPath.Type pathType() {
return pathType;
}
public Mapper getMapper(String field) { public Mapper getMapper(String field) {
return mappers.get(field); return mappers.get(field);
} }
@ -535,9 +507,6 @@ public class ObjectMapper extends Mapper implements AllFieldMapper.IncludeInAll,
if (enabled != Defaults.ENABLED) { if (enabled != Defaults.ENABLED) {
builder.field("enabled", enabled); builder.field("enabled", enabled);
} }
if (pathType != Defaults.PATH_TYPE) {
builder.field("path", pathType.name().toLowerCase(Locale.ROOT));
}
if (includeInAll != null) { if (includeInAll != null) {
builder.field("include_in_all", includeInAll); builder.field("include_in_all", includeInAll);
} }

View File

@ -95,7 +95,7 @@ public class RootObjectMapper extends ObjectMapper {
@Override @Override
protected ObjectMapper createMapper(String name, String fullPath, boolean enabled, Nested nested, Dynamic dynamic, ContentPath.Type pathType, Map<String, Mapper> mappers, @Nullable Settings settings) { protected ObjectMapper createMapper(String name, String fullPath, boolean enabled, Nested nested, Dynamic dynamic, Map<String, Mapper> mappers, @Nullable Settings settings) {
assert !nested.isNested(); assert !nested.isNested();
FormatDateTimeFormatter[] dates = null; FormatDateTimeFormatter[] dates = null;
if (dynamicDateTimeFormatters == null) { if (dynamicDateTimeFormatters == null) {
@ -106,7 +106,7 @@ public class RootObjectMapper extends ObjectMapper {
} else { } else {
dates = dynamicDateTimeFormatters.toArray(new FormatDateTimeFormatter[dynamicDateTimeFormatters.size()]); dates = dynamicDateTimeFormatters.toArray(new FormatDateTimeFormatter[dynamicDateTimeFormatters.size()]);
} }
return new RootObjectMapper(name, enabled, dynamic, pathType, mappers, return new RootObjectMapper(name, enabled, dynamic, mappers,
dates, dates,
dynamicTemplates.toArray(new DynamicTemplate[dynamicTemplates.size()]), dynamicTemplates.toArray(new DynamicTemplate[dynamicTemplates.size()]),
dateDetection, numericDetection); dateDetection, numericDetection);
@ -196,9 +196,9 @@ public class RootObjectMapper extends ObjectMapper {
private volatile DynamicTemplate dynamicTemplates[]; private volatile DynamicTemplate dynamicTemplates[];
RootObjectMapper(String name, boolean enabled, Dynamic dynamic, ContentPath.Type pathType, Map<String, Mapper> mappers, RootObjectMapper(String name, boolean enabled, Dynamic dynamic, Map<String, Mapper> mappers,
FormatDateTimeFormatter[] dynamicDateTimeFormatters, DynamicTemplate dynamicTemplates[], boolean dateDetection, boolean numericDetection) { FormatDateTimeFormatter[] dynamicDateTimeFormatters, DynamicTemplate dynamicTemplates[], boolean dateDetection, boolean numericDetection) {
super(name, name, enabled, Nested.NO, dynamic, pathType, mappers); super(name, name, enabled, Nested.NO, dynamic, mappers);
this.dynamicTemplates = dynamicTemplates; this.dynamicTemplates = dynamicTemplates;
this.dynamicDateTimeFormatters = dynamicDateTimeFormatters; this.dynamicDateTimeFormatters = dynamicDateTimeFormatters;
this.dateDetection = dateDetection; this.dateDetection = dateDetection;

View File

@ -22,7 +22,6 @@ import org.apache.lucene.store.StoreRateLimiting;
import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.node.settings.NodeSettingsService; import org.elasticsearch.node.settings.NodeSettingsService;

View File

@ -0,0 +1,34 @@
/*
* 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.monitor.os;
public class DummyOsInfo extends OsInfo {
DummyOsInfo() {
refreshInterval = 0;
availableProcessors = 0;
allocatedProcessors = 0;
name = "dummy_name";
arch = "dummy_arch";
version = "dummy_version";
}
public static final DummyOsInfo INSTANCE = new DummyOsInfo();
}

View File

@ -108,6 +108,9 @@ public class OsInfo implements Streamable, ToXContent {
refreshInterval = in.readLong(); refreshInterval = in.readLong();
availableProcessors = in.readInt(); availableProcessors = in.readInt();
allocatedProcessors = in.readInt(); allocatedProcessors = in.readInt();
name = in.readOptionalString();
arch = in.readOptionalString();
version = in.readOptionalString();
} }
@Override @Override
@ -115,5 +118,8 @@ public class OsInfo implements Streamable, ToXContent {
out.writeLong(refreshInterval); out.writeLong(refreshInterval);
out.writeInt(availableProcessors); out.writeInt(availableProcessors);
out.writeInt(allocatedProcessors); out.writeInt(allocatedProcessors);
out.writeOptionalString(name);
out.writeOptionalString(arch);
out.writeOptionalString(version);
} }
} }

View File

@ -0,0 +1,28 @@
/*
* 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.plugins;
public class DummyPluginInfo extends PluginInfo {
private DummyPluginInfo(String name, String description, boolean site, String version, boolean jvm, String classname, boolean isolated) {
super(name, description, site, version, jvm, classname, isolated);
}
public static final DummyPluginInfo INSTANCE = new DummyPluginInfo("dummy_plugin_name", "dummy plugin description", true, "dummy_plugin_version", true, "DummyPluginName", true);
}

View File

@ -18,6 +18,7 @@
*/ */
package org.elasticsearch.search.aggregations.bucket.children; package org.elasticsearch.search.aggregations.bucket.children;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.SortedDocValues; import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.search.*; import org.apache.lucene.search.*;
@ -64,9 +65,6 @@ public class ParentToChildrenAggregator extends SingleBucketAggregator {
private final LongObjectPagedHashMap<long[]> parentOrdToOtherBuckets; private final LongObjectPagedHashMap<long[]> parentOrdToOtherBuckets;
private boolean multipleBucketsPerParentOrd = false; private boolean multipleBucketsPerParentOrd = false;
// This needs to be a Set to avoid duplicate reader context entries via (#setNextReader(...), it can get invoked multiple times with the same reader context)
private Set<LeafReaderContext> replay = new LinkedHashSet<>();
public ParentToChildrenAggregator(String name, AggregatorFactories factories, AggregationContext aggregationContext, public ParentToChildrenAggregator(String name, AggregatorFactories factories, AggregationContext aggregationContext,
Aggregator parent, String parentType, Query childFilter, Query parentFilter, Aggregator parent, String parentType, Query childFilter, Query parentFilter,
ValuesSource.Bytes.WithOrdinals.ParentChild valuesSource, ValuesSource.Bytes.WithOrdinals.ParentChild valuesSource,
@ -99,17 +97,11 @@ public class ParentToChildrenAggregator extends SingleBucketAggregator {
if (valuesSource == null) { if (valuesSource == null) {
return LeafBucketCollector.NO_OP_COLLECTOR; return LeafBucketCollector.NO_OP_COLLECTOR;
} }
if (replay == null) {
throw new IllegalStateException();
}
final SortedDocValues globalOrdinals = valuesSource.globalOrdinalsValues(parentType, ctx); final SortedDocValues globalOrdinals = valuesSource.globalOrdinalsValues(parentType, ctx);
assert globalOrdinals != null; assert globalOrdinals != null;
Scorer parentScorer = parentFilter.scorer(ctx); Scorer parentScorer = parentFilter.scorer(ctx);
final Bits parentDocs = Lucene.asSequentialAccessBits(ctx.reader().maxDoc(), parentScorer); final Bits parentDocs = Lucene.asSequentialAccessBits(ctx.reader().maxDoc(), parentScorer);
if (childFilter.scorer(ctx) != null) {
replay.add(ctx);
}
return new LeafBucketCollector() { return new LeafBucketCollector() {
@Override @Override
@ -138,10 +130,8 @@ public class ParentToChildrenAggregator extends SingleBucketAggregator {
@Override @Override
protected void doPostCollection() throws IOException { protected void doPostCollection() throws IOException {
final Set<LeafReaderContext> replay = this.replay; IndexReader indexReader = context().searchContext().searcher().getIndexReader();
this.replay = null; for (LeafReaderContext ctx : indexReader.leaves()) {
for (LeafReaderContext ctx : replay) {
DocIdSetIterator childDocsIter = childFilter.scorer(ctx); DocIdSetIterator childDocsIter = childFilter.scorer(ctx);
if (childDocsIter == null) { if (childDocsIter == null) {
continue; continue;

View File

@ -95,9 +95,6 @@ public class ExternalMapper extends FieldMapper {
@Override @Override
public ExternalMapper build(BuilderContext context) { public ExternalMapper build(BuilderContext context) {
ContentPath.Type origPathType = context.path().pathType();
context.path().pathType(ContentPath.Type.FULL);
context.path().add(name); context.path().add(name);
BinaryFieldMapper binMapper = binBuilder.build(context); BinaryFieldMapper binMapper = binBuilder.build(context);
BooleanFieldMapper boolMapper = boolBuilder.build(context); BooleanFieldMapper boolMapper = boolBuilder.build(context);
@ -107,7 +104,6 @@ public class ExternalMapper extends FieldMapper {
FieldMapper stringMapper = (FieldMapper)stringBuilder.build(context); FieldMapper stringMapper = (FieldMapper)stringBuilder.build(context);
context.path().remove(); context.path().remove();
context.path().pathType(origPathType);
setupFieldType(context); setupFieldType(context);
return new ExternalMapper(name, fieldType, generatedValue, mapperName, binMapper, boolMapper, pointMapper, shapeMapper, stringMapper, return new ExternalMapper(name, fieldType, generatedValue, mapperName, binMapper, boolMapper, pointMapper, shapeMapper, stringMapper,

View File

@ -0,0 +1,140 @@
/*
* 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.nodesinfo;
import org.elasticsearch.Build;
import org.elasticsearch.Version;
import org.elasticsearch.action.admin.cluster.node.info.NodeInfo;
import org.elasticsearch.action.admin.cluster.node.info.PluginsAndModules;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.BoundTransportAddress;
import org.elasticsearch.common.transport.DummyTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.http.HttpInfo;
import org.elasticsearch.monitor.jvm.JvmInfo;
import org.elasticsearch.monitor.os.DummyOsInfo;
import org.elasticsearch.monitor.os.OsInfo;
import org.elasticsearch.monitor.process.ProcessInfo;
import org.elasticsearch.plugins.DummyPluginInfo;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.VersionUtils;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.threadpool.ThreadPoolInfo;
import org.elasticsearch.transport.TransportInfo;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.hamcrest.core.IsEqual.equalTo;
/**
*
*/
public class NodeInfoStreamingTests extends ESTestCase {
public void testNodeInfoStreaming() throws IOException {
NodeInfo nodeInfo = createNodeInfo();
Version version = Version.CURRENT;
BytesStreamOutput out = new BytesStreamOutput();
out.setVersion(version);
nodeInfo.writeTo(out);
out.close();
StreamInput in = StreamInput.wrap(out.bytes());
in.setVersion(version);
NodeInfo readNodeInfo = NodeInfo.readNodeInfo(in);
assertExpectedUnchanged(nodeInfo, readNodeInfo);
}
// checks all properties that are expected to be unchanged. Once we start changing them between versions this method has to be changed as well
private void assertExpectedUnchanged(NodeInfo nodeInfo, NodeInfo readNodeInfo) throws IOException {
assertThat(nodeInfo.getBuild().toString(), equalTo(readNodeInfo.getBuild().toString()));
assertThat(nodeInfo.getHostname(), equalTo(readNodeInfo.getHostname()));
assertThat(nodeInfo.getVersion(), equalTo(readNodeInfo.getVersion()));
assertThat(nodeInfo.getServiceAttributes().size(), equalTo(readNodeInfo.getServiceAttributes().size()));
for (Map.Entry<String, String> entry : nodeInfo.getServiceAttributes().entrySet()) {
assertNotNull(readNodeInfo.getServiceAttributes().get(entry.getKey()));
assertThat(readNodeInfo.getServiceAttributes().get(entry.getKey()), equalTo(entry.getValue()));
}
compareJsonOutput(nodeInfo.getHttp(), readNodeInfo.getHttp());
compareJsonOutput(nodeInfo.getJvm(), readNodeInfo.getJvm());
compareJsonOutput(nodeInfo.getProcess(), readNodeInfo.getProcess());
compareJsonOutput(nodeInfo.getSettings(), readNodeInfo.getSettings());
compareJsonOutput(nodeInfo.getThreadPool(), readNodeInfo.getThreadPool());
compareJsonOutput(nodeInfo.getTransport(), readNodeInfo.getTransport());
compareJsonOutput(nodeInfo.getNode(), readNodeInfo.getNode());
compareJsonOutput(nodeInfo.getOs(), readNodeInfo.getOs());
comparePluginsAndModules(nodeInfo, readNodeInfo);
}
private void comparePluginsAndModules(NodeInfo nodeInfo, NodeInfo readNodeInfo) throws IOException {
ToXContent.Params params = ToXContent.EMPTY_PARAMS;
XContentBuilder pluginsAndModules = jsonBuilder();
pluginsAndModules.startObject();
nodeInfo.getPlugins().toXContent(pluginsAndModules, params);
pluginsAndModules.endObject();
XContentBuilder readPluginsAndModules = jsonBuilder();
readPluginsAndModules.startObject();
readNodeInfo.getPlugins().toXContent(readPluginsAndModules, params);
readPluginsAndModules.endObject();
assertThat(pluginsAndModules.string(), equalTo(readPluginsAndModules.string()));
}
private void compareJsonOutput(ToXContent param1, ToXContent param2) throws IOException {
ToXContent.Params params = ToXContent.EMPTY_PARAMS;
XContentBuilder param1Builder = jsonBuilder();
XContentBuilder param2Builder = jsonBuilder();
param1.toXContent(param1Builder, params);
param2.toXContent(param2Builder, params);
assertThat(param1Builder.string(), equalTo(param2Builder.string()));
}
private NodeInfo createNodeInfo() {
Build build = Build.CURRENT;
DiscoveryNode node = new DiscoveryNode("test_node", DummyTransportAddress.INSTANCE, VersionUtils.randomVersion(random()));
Map<String, String> serviceAttributes = new HashMap<>();
serviceAttributes.put("test", "attribute");
Settings settings = Settings.builder().put("test", "setting").build();
OsInfo osInfo = DummyOsInfo.INSTANCE;
ProcessInfo process = new ProcessInfo(randomInt(), randomBoolean());
JvmInfo jvm = JvmInfo.jvmInfo();
List<ThreadPool.Info> threadPoolInfos = new ArrayList<>();
threadPoolInfos.add(new ThreadPool.Info("test_threadpool", ThreadPool.ThreadPoolType.FIXED, 5));
ThreadPoolInfo threadPoolInfo = new ThreadPoolInfo(threadPoolInfos);
Map<String, BoundTransportAddress> profileAddresses = new HashMap<>();
BoundTransportAddress dummyBoundTransportAddress = new BoundTransportAddress(new TransportAddress[]{DummyTransportAddress.INSTANCE}, DummyTransportAddress.INSTANCE);
profileAddresses.put("test_address", dummyBoundTransportAddress);
TransportInfo transport = new TransportInfo(dummyBoundTransportAddress, profileAddresses);
HttpInfo htttpInfo = new HttpInfo(dummyBoundTransportAddress, randomLong());
PluginsAndModules plugins = new PluginsAndModules();
plugins.addModule(DummyPluginInfo.INSTANCE);
plugins.addPlugin(DummyPluginInfo.INSTANCE);
return new NodeInfo(VersionUtils.randomVersion(random()), build, node, serviceAttributes, settings, osInfo, process, jvm, threadPoolInfo, transport, htttpInfo, plugins);
}
}

View File

@ -18,12 +18,15 @@
*/ */
package org.elasticsearch.search.aggregations.bucket; package org.elasticsearch.search.aggregations.bucket;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.children.Children; import org.elasticsearch.search.aggregations.bucket.children.Children;
import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.sum.Sum; import org.elasticsearch.search.aggregations.metrics.sum.Sum;
@ -392,6 +395,65 @@ public class ChildrenIT extends ESIntegTestCase {
assertThat(terms.getBuckets().get(0).getDocCount(), equalTo(1l)); assertThat(terms.getBuckets().get(0).getDocCount(), equalTo(1l));
} }
public void testPostCollectAllLeafReaders() throws Exception {
// The 'towns' and 'parent_names' aggs operate on parent docs and if child docs are in different segments we need
// to ensure those segments which child docs are also evaluated to in the post collect phase.
// Before we only evaluated segments that yielded matches in 'towns' and 'parent_names' aggs, which caused
// us to miss to evaluate child docs in segments we didn't have parent matches for.
assertAcked(
prepareCreate("index")
.addMapping("parentType", "name", "type=string,index=not_analyzed", "town", "type=string,index=not_analyzed")
.addMapping("childType", "_parent", "type=parentType", "name", "type=string,index=not_analyzed", "age", "type=integer")
);
List<IndexRequestBuilder> requests = new ArrayList<>();
requests.add(client().prepareIndex("index", "parentType", "1").setSource("name", "Bob", "town", "Memphis"));
requests.add(client().prepareIndex("index", "parentType", "2").setSource("name", "Alice", "town", "Chicago"));
requests.add(client().prepareIndex("index", "parentType", "3").setSource("name", "Bill", "town", "Chicago"));
requests.add(client().prepareIndex("index", "childType", "1").setSource("name", "Jill", "age", 5).setParent("1"));
requests.add(client().prepareIndex("index", "childType", "2").setSource("name", "Joey", "age", 3).setParent("1"));
requests.add(client().prepareIndex("index", "childType", "3").setSource("name", "John", "age", 2).setParent("2"));
requests.add(client().prepareIndex("index", "childType", "4").setSource("name", "Betty", "age", 6).setParent("3"));
requests.add(client().prepareIndex("index", "childType", "5").setSource("name", "Dan", "age", 1).setParent("3"));
indexRandom(true, requests);
SearchResponse response = client().prepareSearch("index")
.setSize(0)
.addAggregation(AggregationBuilders.terms("towns").field("town")
.subAggregation(AggregationBuilders.terms("parent_names").field("name")
.subAggregation(AggregationBuilders.children("child_docs").childType("childType"))
)
)
.get();
Terms towns = response.getAggregations().get("towns");
assertThat(towns.getBuckets().size(), equalTo(2));
assertThat(towns.getBuckets().get(0).getKeyAsString(), equalTo("Chicago"));
assertThat(towns.getBuckets().get(0).getDocCount(), equalTo(2L));
Terms parents = towns.getBuckets().get(0).getAggregations().get("parent_names");
assertThat(parents.getBuckets().size(), equalTo(2));
assertThat(parents.getBuckets().get(0).getKeyAsString(), equalTo("Alice"));
assertThat(parents.getBuckets().get(0).getDocCount(), equalTo(1L));
Children children = parents.getBuckets().get(0).getAggregations().get("child_docs");
assertThat(children.getDocCount(), equalTo(1L));
assertThat(parents.getBuckets().get(1).getKeyAsString(), equalTo("Bill"));
assertThat(parents.getBuckets().get(1).getDocCount(), equalTo(1L));
children = parents.getBuckets().get(1).getAggregations().get("child_docs");
assertThat(children.getDocCount(), equalTo(2L));
assertThat(towns.getBuckets().get(1).getKeyAsString(), equalTo("Memphis"));
assertThat(towns.getBuckets().get(1).getDocCount(), equalTo(1L));
parents = towns.getBuckets().get(1).getAggregations().get("parent_names");
assertThat(parents.getBuckets().size(), equalTo(1));
assertThat(parents.getBuckets().get(0).getKeyAsString(), equalTo("Bob"));
assertThat(parents.getBuckets().get(0).getDocCount(), equalTo(1L));
children = parents.getBuckets().get(0).getAggregations().get("child_docs");
assertThat(children.getDocCount(), equalTo(2L));
}
private static final class Control { private static final class Control {
final String category; final String category;

View File

@ -61,7 +61,7 @@ public class SearchWhileRelocatingIT extends ESIntegTestCase {
final int numShards = between(1, 20); final int numShards = between(1, 20);
client().admin().indices().prepareCreate("test") client().admin().indices().prepareCreate("test")
.setSettings(settingsBuilder().put("index.number_of_shards", numShards).put("index.number_of_replicas", numberOfReplicas)) .setSettings(settingsBuilder().put("index.number_of_shards", numShards).put("index.number_of_replicas", numberOfReplicas))
.addMapping("type1", "loc", "type=geo_point", "test", "type=string").execute().actionGet(); .addMapping("type", "loc", "type=geo_point", "test", "type=string").execute().actionGet();
ensureGreen(); ensureGreen();
List<IndexRequestBuilder> indexBuilders = new ArrayList<>(); List<IndexRequestBuilder> indexBuilders = new ArrayList<>();
final int numDocs = between(10, 20); final int numDocs = between(10, 20);

View File

@ -88,24 +88,26 @@ by raising an issue. Thank you!
Once installed, define the configuration for the `hdfs` repository through `elasticsearch.yml` or the Once installed, define the configuration for the `hdfs` repository through `elasticsearch.yml` or the
{ref}/modules-snapshots.html[REST API]: {ref}/modules-snapshots.html[REST API]:
[source] [source,yaml]
---- ----
repositories repositories
hdfs: hdfs:
uri: "hdfs://<host>:<port>/" # optional - Hadoop file-system URI uri: "hdfs://<host>:<port>/" \# optional - Hadoop file-system URI
path: "some/path" # required - path with the file-system where data is stored/loaded path: "some/path" \# required - path with the file-system where data is stored/loaded
load_defaults: "true" # optional - whether to load the default Hadoop configuration (default) or not load_defaults: "true" \# optional - whether to load the default Hadoop configuration (default) or not
conf_location: "extra-cfg.xml" # optional - Hadoop configuration XML to be loaded (use commas for multi values) conf_location: "extra-cfg.xml" \# optional - Hadoop configuration XML to be loaded (use commas for multi values)
conf.<key> : "<value>" # optional - 'inlined' key=value added to the Hadoop configuration conf.<key> : "<value>" \# optional - 'inlined' key=value added to the Hadoop configuration
concurrent_streams: 5 # optional - the number of concurrent streams (defaults to 5) concurrent_streams: 5 \# optional - the number of concurrent streams (defaults to 5)
compress: "false" # optional - whether to compress the metadata or not (default) compress: "false" \# optional - whether to compress the metadata or not (default)
chunk_size: "10mb" # optional - chunk size (disabled by default) chunk_size: "10mb" \# optional - chunk size (disabled by default)
---- ----
NOTE: Be careful when including a paths within the `uri` setting; Some implementations ignore them completely while NOTE: Be careful when including a paths within the `uri` setting; Some implementations ignore them completely while
others consider them. In general, we recommend keeping the `uri` to a minimum and using the `path` element instead. others consider them. In general, we recommend keeping the `uri` to a minimum and using the `path` element instead.
===== Plugging other file-systems [[repository-hdfs-other-fs]]
==== Plugging other file-systems
Any HDFS-compatible file-systems (like Amazon `s3://` or Google `gs://`) can be used as long as the proper Hadoop Any HDFS-compatible file-systems (like Amazon `s3://` or Google `gs://`) can be used as long as the proper Hadoop
configuration is passed to the Elasticsearch plugin. In practice, this means making sure the correct Hadoop configuration configuration is passed to the Elasticsearch plugin. In practice, this means making sure the correct Hadoop configuration

View File

@ -110,7 +110,7 @@ GET my_index/_search
"bool": { "bool": {
"must": [ "must": [
{ "match": { "user.first": "Alice" }}, { "match": { "user.first": "Alice" }},
{ "match": { "user.last": "White" }} <2> { "match": { "user.last": "Smith" }} <2>
] ]
} }
} }
@ -127,7 +127,7 @@ GET my_index/_search
"bool": { "bool": {
"must": [ "must": [
{ "match": { "user.first": "Alice" }}, { "match": { "user.first": "Alice" }},
{ "match": { "user.last": "Smith" }} <3> { "match": { "user.last": "White" }} <3>
] ]
} }
}, },
@ -137,14 +137,14 @@ GET my_index/_search
"user.first": {} "user.first": {}
} }
} }
}
} }
} }
} }
-------------------------------------------------- --------------------------------------------------
// AUTOSENSE // AUTOSENSE
<1> The `user` field is mapped as type `nested` instead of type `object`. <1> The `user` field is mapped as type `nested` instead of type `object`.
<2> This query doesn't match because `Alice` and `White` are not in the same nested object. <2> This query doesn't match because `Alice` and `Smith` are not in the same nested object.
<3> This query matches because `Alice` and `White` are in the same nested object. <3> This query matches because `Alice` and `White` are in the same nested object.
<4> `inner_hits` allow us to highlight the matching nested documents. <4> `inner_hits` allow us to highlight the matching nested documents.

View File

@ -37,7 +37,6 @@ import java.util.*;
import static org.elasticsearch.index.mapper.MapperBuilders.*; import static org.elasticsearch.index.mapper.MapperBuilders.*;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseMultiField; import static org.elasticsearch.index.mapper.core.TypeParsers.parseMultiField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parsePathType;
/** /**
* <pre> * <pre>
@ -65,7 +64,6 @@ public class AttachmentMapper extends FieldMapper {
public static final String CONTENT_TYPE = "attachment"; public static final String CONTENT_TYPE = "attachment";
public static class Defaults { public static class Defaults {
public static final ContentPath.Type PATH_TYPE = ContentPath.Type.FULL;
public static final AttachmentFieldType FIELD_TYPE = new AttachmentFieldType(); public static final AttachmentFieldType FIELD_TYPE = new AttachmentFieldType();
static { static {
@ -108,8 +106,6 @@ public class AttachmentMapper extends FieldMapper {
public static class Builder extends FieldMapper.Builder<Builder, AttachmentMapper> { public static class Builder extends FieldMapper.Builder<Builder, AttachmentMapper> {
private ContentPath.Type pathType = Defaults.PATH_TYPE;
private Boolean ignoreErrors = null; private Boolean ignoreErrors = null;
private Integer defaultIndexedChars = null; private Integer defaultIndexedChars = null;
@ -140,11 +136,6 @@ public class AttachmentMapper extends FieldMapper {
this.contentBuilder = stringField(FieldNames.CONTENT); this.contentBuilder = stringField(FieldNames.CONTENT);
} }
public Builder pathType(ContentPath.Type pathType) {
this.pathType = pathType;
return this;
}
public Builder content(Mapper.Builder content) { public Builder content(Mapper.Builder content) {
this.contentBuilder = content; this.contentBuilder = content;
return this; return this;
@ -192,8 +183,6 @@ public class AttachmentMapper extends FieldMapper {
@Override @Override
public AttachmentMapper build(BuilderContext context) { public AttachmentMapper build(BuilderContext context) {
ContentPath.Type origPathType = context.path().pathType();
context.path().pathType(pathType);
FieldMapper contentMapper; FieldMapper contentMapper;
if (context.indexCreatedVersion().before(Version.V_2_0_0_beta1)) { if (context.indexCreatedVersion().before(Version.V_2_0_0_beta1)) {
@ -220,8 +209,6 @@ public class AttachmentMapper extends FieldMapper {
FieldMapper language = (FieldMapper) languageBuilder.build(context); FieldMapper language = (FieldMapper) languageBuilder.build(context);
context.path().remove(); context.path().remove();
context.path().pathType(origPathType);
if (defaultIndexedChars == null && context.indexSettings() != null) { if (defaultIndexedChars == null && context.indexSettings() != null) {
defaultIndexedChars = context.indexSettings().getAsInt("index.mapping.attachment.indexed_chars", 100000); defaultIndexedChars = context.indexSettings().getAsInt("index.mapping.attachment.indexed_chars", 100000);
} }
@ -257,7 +244,7 @@ public class AttachmentMapper extends FieldMapper {
defaultFieldType.freeze(); defaultFieldType.freeze();
this.setupFieldType(context); this.setupFieldType(context);
return new AttachmentMapper(name, fieldType, defaultFieldType, pathType, defaultIndexedChars, ignoreErrors, langDetect, contentMapper, return new AttachmentMapper(name, fieldType, defaultFieldType, defaultIndexedChars, ignoreErrors, langDetect, contentMapper,
dateMapper, titleMapper, nameMapper, authorMapper, keywordsMapper, contentTypeMapper, contentLength, dateMapper, titleMapper, nameMapper, authorMapper, keywordsMapper, contentTypeMapper, contentLength,
language, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); language, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
} }
@ -309,10 +296,7 @@ public class AttachmentMapper extends FieldMapper {
Map.Entry<String, Object> entry = iterator.next(); Map.Entry<String, Object> entry = iterator.next();
String fieldName = entry.getKey(); String fieldName = entry.getKey();
Object fieldNode = entry.getValue(); Object fieldNode = entry.getValue();
if (fieldName.equals("path") && parserContext.indexVersionCreated().before(Version.V_2_0_0_beta1)) { if (fieldName.equals("fields")) {
builder.pathType(parsePathType(name, fieldNode.toString()));
iterator.remove();
} else if (fieldName.equals("fields")) {
Map<String, Object> fieldsNode = (Map<String, Object>) fieldNode; Map<String, Object> fieldsNode = (Map<String, Object>) fieldNode;
for (Iterator<Map.Entry<String, Object>> fieldsIterator = fieldsNode.entrySet().iterator(); fieldsIterator.hasNext();) { for (Iterator<Map.Entry<String, Object>> fieldsIterator = fieldsNode.entrySet().iterator(); fieldsIterator.hasNext();) {
Map.Entry<String, Object> entry1 = fieldsIterator.next(); Map.Entry<String, Object> entry1 = fieldsIterator.next();
@ -375,8 +359,6 @@ public class AttachmentMapper extends FieldMapper {
} }
} }
private final ContentPath.Type pathType;
private final int defaultIndexedChars; private final int defaultIndexedChars;
private final boolean ignoreErrors; private final boolean ignoreErrors;
@ -401,13 +383,12 @@ public class AttachmentMapper extends FieldMapper {
private final FieldMapper languageMapper; private final FieldMapper languageMapper;
public AttachmentMapper(String simpleName, MappedFieldType type, MappedFieldType defaultFieldType, ContentPath.Type pathType, int defaultIndexedChars, Boolean ignoreErrors, public AttachmentMapper(String simpleName, MappedFieldType type, MappedFieldType defaultFieldType, int defaultIndexedChars, Boolean ignoreErrors,
Boolean defaultLangDetect, FieldMapper contentMapper, Boolean defaultLangDetect, FieldMapper contentMapper,
FieldMapper dateMapper, FieldMapper titleMapper, FieldMapper nameMapper, FieldMapper authorMapper, FieldMapper dateMapper, FieldMapper titleMapper, FieldMapper nameMapper, FieldMapper authorMapper,
FieldMapper keywordsMapper, FieldMapper contentTypeMapper, FieldMapper contentLengthMapper, FieldMapper keywordsMapper, FieldMapper contentTypeMapper, FieldMapper contentLengthMapper,
FieldMapper languageMapper, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { FieldMapper languageMapper, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
super(simpleName, type, defaultFieldType, indexSettings, multiFields, copyTo); super(simpleName, type, defaultFieldType, indexSettings, multiFields, copyTo);
this.pathType = pathType;
this.defaultIndexedChars = defaultIndexedChars; this.defaultIndexedChars = defaultIndexedChars;
this.ignoreErrors = ignoreErrors; this.ignoreErrors = ignoreErrors;
this.defaultLangDetect = defaultLangDetect; this.defaultLangDetect = defaultLangDetect;
@ -626,9 +607,6 @@ public class AttachmentMapper extends FieldMapper {
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(simpleName()); builder.startObject(simpleName());
builder.field("type", CONTENT_TYPE); builder.field("type", CONTENT_TYPE);
if (indexCreatedBefore2x) {
builder.field("path", pathType.name().toLowerCase(Locale.ROOT));
}
builder.startObject("fields"); builder.startObject("fields");
contentMapper.toXContent(builder, params); contentMapper.toXContent(builder, params);

View File

@ -168,6 +168,7 @@ public class HttpRequestBuilder {
logger.trace("sending request \n{}", stringBuilder.toString()); logger.trace("sending request \n{}", stringBuilder.toString());
} }
for (Map.Entry<String, String> entry : this.headers.entrySet()) { for (Map.Entry<String, String> entry : this.headers.entrySet()) {
logger.trace("adding header [{} => {}]", entry.getKey(), entry.getValue());
httpUriRequest.addHeader(entry.getKey(), entry.getValue()); httpUriRequest.addHeader(entry.getKey(), entry.getValue());
} }
try (CloseableHttpResponse closeableHttpResponse = httpClient.execute(httpUriRequest)) { try (CloseableHttpResponse closeableHttpResponse = httpClient.execute(httpUriRequest)) {