Core: Enable doc values by default, when appropriate
Doc values significantly reduced heap usage, which results in faster GCs. This change makes the default for doc values dynamic: any field that is indexed but not analyzed now has doc values. This only affects fields on indexes created with 2.0+. closes #8312 closes #10209
This commit is contained in:
parent
3f459f69a7
commit
e0334dcb9e
|
@ -90,7 +90,7 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T> {
|
|||
|
||||
public static class Defaults {
|
||||
public static final FieldType FIELD_TYPE = new FieldType();
|
||||
public static final boolean DOC_VALUES = false;
|
||||
public static final boolean PRE_2X_DOC_VALUES = false;
|
||||
|
||||
static {
|
||||
FIELD_TYPE.setTokenized(true);
|
||||
|
@ -302,7 +302,7 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T> {
|
|||
protected FieldDataType fieldDataType;
|
||||
protected final MultiFields multiFields;
|
||||
protected CopyTo copyTo;
|
||||
protected final boolean writePre2xSettings;
|
||||
protected final boolean indexCreatedBefore2x;
|
||||
|
||||
protected AbstractFieldMapper(Names names, float boost, FieldType fieldType, Boolean docValues, NamedAnalyzer indexAnalyzer,
|
||||
NamedAnalyzer searchAnalyzer, SimilarityProvider similarity,
|
||||
|
@ -319,8 +319,10 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T> {
|
|||
this.boost = boost;
|
||||
this.fieldType = fieldType;
|
||||
this.fieldType.freeze();
|
||||
|
||||
if (indexAnalyzer == null && this.fieldType.tokenized() == false && this.fieldType.indexOptions() != IndexOptions.NONE) {
|
||||
this.indexCreatedBefore2x = Version.indexCreated(indexSettings).before(Version.V_2_0_0);
|
||||
|
||||
boolean indexedNotAnalyzed = this.fieldType.tokenized() == false && this.fieldType.indexOptions() != IndexOptions.NONE;
|
||||
if (indexAnalyzer == null && indexedNotAnalyzed) {
|
||||
this.indexAnalyzer = this.searchAnalyzer = Lucene.KEYWORD_ANALYZER;
|
||||
} else {
|
||||
this.indexAnalyzer = indexAnalyzer;
|
||||
|
@ -339,16 +341,22 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T> {
|
|||
ImmutableSettings.builder().put(defaultFieldDataType().getSettings()).put(fieldDataSettings)
|
||||
);
|
||||
}
|
||||
|
||||
if (docValues != null) {
|
||||
// explicitly set
|
||||
this.docValues = docValues;
|
||||
} else if (fieldDataType == null) {
|
||||
this.docValues = false;
|
||||
} else if (fieldDataType != null && FieldDataType.DOC_VALUES_FORMAT_VALUE.equals(fieldDataType.getFormat(indexSettings))) {
|
||||
// convoluted way to enable doc values, should be removed in the future
|
||||
this.docValues = true;
|
||||
} else if (Version.indexCreated(indexSettings).onOrAfter(Version.V_2_0_0)) {
|
||||
// 2.0+ index, default to true when appropriate
|
||||
this.docValues = defaultDocValues();
|
||||
} else {
|
||||
this.docValues = FieldDataType.DOC_VALUES_FORMAT_VALUE.equals(fieldDataType.getFormat(indexSettings));
|
||||
}
|
||||
// old default, disable
|
||||
this.docValues = false;
|
||||
}
|
||||
this.multiFields = multiFields;
|
||||
this.copyTo = copyTo;
|
||||
this.writePre2xSettings = Version.indexCreated(indexSettings).before(Version.V_2_0_0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -360,6 +368,19 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T> {
|
|||
protected String defaultDocValuesFormat() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean defaultDocValues() {
|
||||
if (indexCreatedBefore2x) {
|
||||
return Defaults.PRE_2X_DOC_VALUES;
|
||||
} else {
|
||||
return fieldType.tokenized() == false && fieldType.indexOptions() != IndexOptions.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean hasDocValues() {
|
||||
return docValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
|
@ -683,7 +704,7 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T> {
|
|||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||
|
||||
builder.field("type", contentType());
|
||||
if (writePre2xSettings && (includeDefaults || !names.name().equals(names.indexNameClean()))) {
|
||||
if (indexCreatedBefore2x && (includeDefaults || !names.name().equals(names.indexNameClean()))) {
|
||||
builder.field("index_name", names.indexNameClean());
|
||||
}
|
||||
|
||||
|
@ -701,7 +722,7 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T> {
|
|||
if (includeDefaults || fieldType.stored() != defaultFieldType.stored()) {
|
||||
builder.field("store", fieldType.stored());
|
||||
}
|
||||
if (includeDefaults || hasDocValues() != Defaults.DOC_VALUES) {
|
||||
if (includeDefaults || hasDocValues() != defaultDocValues()) {
|
||||
builder.field(TypeParsers.DOC_VALUES, docValues);
|
||||
}
|
||||
if (includeDefaults || fieldType.storeTermVectors() != defaultFieldType.storeTermVectors()) {
|
||||
|
@ -824,11 +845,6 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T> {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDocValues() {
|
||||
return docValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loading normsLoading(Loading defaultLoading) {
|
||||
return normsLoading == null ? defaultLoading : normsLoading;
|
||||
|
|
|
@ -131,7 +131,7 @@ public class BooleanFieldMapper extends AbstractFieldMapper<Boolean> {
|
|||
protected BooleanFieldMapper(Names names, float boost, FieldType fieldType, Boolean nullValue,
|
||||
SimilarityProvider similarity, Loading normsLoading,
|
||||
@Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||
super(names, boost, fieldType, null, Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER, similarity, normsLoading, fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||
super(names, boost, fieldType, false, Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER, similarity, normsLoading, fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||
this.nullValue = nullValue;
|
||||
}
|
||||
|
||||
|
@ -256,9 +256,4 @@ public class BooleanFieldMapper extends AbstractFieldMapper<Boolean> {
|
|||
builder.field("null_value", nullValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDocValues() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -240,7 +240,7 @@ public class CompletionFieldMapper extends AbstractFieldMapper<String> {
|
|||
// with older postings formats such as Elasticsearch090
|
||||
public CompletionFieldMapper(Names names, NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer, PostingsFormat wrappedPostingsFormat, SimilarityProvider similarity, boolean payloads,
|
||||
boolean preserveSeparators, boolean preservePositionIncrements, int maxInputLength, Settings indexSettings, MultiFields multiFields, CopyTo copyTo, SortedMap<String, ContextMapping> contextMappings) {
|
||||
super(names, 1.0f, Defaults.FIELD_TYPE, null, indexAnalyzer, searchAnalyzer, similarity, null, null, indexSettings, multiFields, copyTo);
|
||||
super(names, 1.0f, Defaults.FIELD_TYPE, false, indexAnalyzer, searchAnalyzer, similarity, null, null, indexSettings, multiFields, copyTo);
|
||||
analyzingSuggestLookupProvider = new AnalyzingCompletionLookupProvider(preserveSeparators, false, preservePositionIncrements, payloads);
|
||||
if (wrappedPostingsFormat == null) {
|
||||
// delayed until postingsFormat() is called
|
||||
|
@ -494,11 +494,6 @@ public class CompletionFieldMapper extends AbstractFieldMapper<String> {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDocValues() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsNullValue() {
|
||||
return false;
|
||||
|
|
|
@ -197,8 +197,8 @@ public class GeoPointFieldMapper extends AbstractFieldMapper<GeoPoint> implement
|
|||
latMapperBuilder.precisionStep(precisionStep);
|
||||
lonMapperBuilder.precisionStep(precisionStep);
|
||||
}
|
||||
latMapper = (DoubleFieldMapper) latMapperBuilder.includeInAll(false).store(fieldType.stored()).build(context);
|
||||
lonMapper = (DoubleFieldMapper) lonMapperBuilder.includeInAll(false).store(fieldType.stored()).build(context);
|
||||
latMapper = (DoubleFieldMapper) latMapperBuilder.includeInAll(false).store(fieldType.stored()).docValues(false).build(context);
|
||||
lonMapper = (DoubleFieldMapper) lonMapperBuilder.includeInAll(false).store(fieldType.stored()).docValues(false).build(context);
|
||||
}
|
||||
StringFieldMapper geohashMapper = null;
|
||||
if (enableGeoHash) {
|
||||
|
@ -470,6 +470,11 @@ public class GeoPointFieldMapper extends AbstractFieldMapper<GeoPoint> implement
|
|||
public FieldDataType defaultFieldDataType() {
|
||||
return new FieldDataType("geo_point");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean defaultDocValues() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public DoubleFieldMapper latMapper() {
|
||||
return latMapper;
|
||||
|
|
|
@ -215,7 +215,7 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper<String> {
|
|||
|
||||
public GeoShapeFieldMapper(FieldMapper.Names names, SpatialPrefixTree tree, String defaultStrategyName, double distanceErrorPct,
|
||||
Orientation shapeOrientation, FieldType fieldType, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||
super(names, 1, fieldType, null, null, null, null, null, null, indexSettings, multiFields, copyTo);
|
||||
super(names, 1, fieldType, false, null, null, null, null, null, indexSettings, multiFields, copyTo);
|
||||
this.recursiveStrategy = new RecursivePrefixTreeStrategy(tree, names.indexName());
|
||||
this.recursiveStrategy.setDistErrPct(distanceErrorPct);
|
||||
this.termStrategy = new TermQueryPrefixTreeStrategy(tree, names.indexName());
|
||||
|
@ -234,11 +234,6 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper<String> {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDocValues() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parse(ParseContext context) throws IOException {
|
||||
try {
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.lucene.index.IndexOptions;
|
|||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||
|
@ -34,6 +35,7 @@ import org.elasticsearch.common.lucene.all.AllField;
|
|||
import org.elasticsearch.common.lucene.all.AllTermQuery;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.loader.SettingsLoader;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||
|
@ -55,6 +57,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue;
|
||||
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeMapValue;
|
||||
import static org.elasticsearch.index.mapper.MapperBuilders.all;
|
||||
import static org.elasticsearch.index.mapper.core.TypeParsers.parseField;
|
||||
|
||||
|
@ -125,6 +128,24 @@ public class AllFieldMapper extends AbstractFieldMapper<String> implements Inter
|
|||
@Override
|
||||
public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
AllFieldMapper.Builder builder = all();
|
||||
|
||||
// parseField below will happily parse the doc_values setting, but it is then never passed to
|
||||
// the AllFieldMapper ctor in the builder since it is not valid. Here we validate
|
||||
// the doc values settings (old and new) are rejected
|
||||
Object docValues = node.get("doc_values");
|
||||
if (docValues != null && nodeBooleanValue(docValues)) {
|
||||
throw new MapperParsingException("Field [" + name + "] is always tokenized and cannot have doc values");
|
||||
}
|
||||
// convoluted way of specifying doc values
|
||||
Object fielddata = node.get("fielddata");
|
||||
if (fielddata != null) {
|
||||
Map<String, Object> fielddataMap = nodeMapValue(fielddata, "fielddata");
|
||||
Object format = fielddataMap.get("format");
|
||||
if ("doc_values".equals(format)) {
|
||||
throw new MapperParsingException("Field [" + name + "] is always tokenized and cannot have doc values");
|
||||
}
|
||||
}
|
||||
|
||||
parseField(builder, builder.name, node, parserContext);
|
||||
for (Iterator<Map.Entry<String, Object>> iterator = node.entrySet().iterator(); iterator.hasNext();) {
|
||||
Map.Entry<String, Object> entry = iterator.next();
|
||||
|
@ -158,11 +179,8 @@ public class AllFieldMapper extends AbstractFieldMapper<String> implements Inter
|
|||
protected AllFieldMapper(String name, FieldType fieldType, NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer,
|
||||
EnabledAttributeMapper enabled, boolean autoBoost, SimilarityProvider similarity, Loading normsLoading,
|
||||
@Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||
super(new Names(name, name, name, name), 1.0f, fieldType, null, indexAnalyzer, searchAnalyzer,
|
||||
super(new Names(name, name, name, name), 1.0f, fieldType, false, indexAnalyzer, searchAnalyzer,
|
||||
similarity, normsLoading, fieldDataSettings, indexSettings);
|
||||
if (hasDocValues()) {
|
||||
throw new MapperParsingException("Field [" + names.fullName() + "] is always tokenized and cannot have doc values");
|
||||
}
|
||||
this.enabledState = enabled;
|
||||
this.autoBoost = autoBoost;
|
||||
|
||||
|
|
|
@ -268,7 +268,7 @@ public class FieldNamesFieldMapper extends AbstractFieldMapper<String> implement
|
|||
if (includeDefaults || enabledState != Defaults.ENABLED_STATE) {
|
||||
builder.field("enabled", enabledState.enabled);
|
||||
}
|
||||
if (writePre2xSettings && (includeDefaults || fieldType().equals(Defaults.FIELD_TYPE) == false)) {
|
||||
if (indexCreatedBefore2x && (includeDefaults || fieldType().equals(Defaults.FIELD_TYPE) == false)) {
|
||||
super.doXContentBody(builder, includeDefaults, params);
|
||||
}
|
||||
|
||||
|
|
|
@ -349,7 +349,7 @@ public class IdFieldMapper extends AbstractFieldMapper<String> implements Intern
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
if (writePre2xSettings == false) {
|
||||
if (indexCreatedBefore2x == false) {
|
||||
return builder;
|
||||
}
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.elasticsearch.Version;
|
|||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.lucene.Lucene;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||
|
@ -90,7 +89,7 @@ public class IndexFieldMapper extends AbstractFieldMapper<String> implements Int
|
|||
|
||||
@Override
|
||||
public IndexFieldMapper build(BuilderContext context) {
|
||||
return new IndexFieldMapper(name, indexName, boost, fieldType, docValues, enabledState, fieldDataSettings, context.indexSettings());
|
||||
return new IndexFieldMapper(name, indexName, boost, fieldType, enabledState, fieldDataSettings, context.indexSettings());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,12 +118,12 @@ public class IndexFieldMapper extends AbstractFieldMapper<String> implements Int
|
|||
private EnabledAttributeMapper enabledState;
|
||||
|
||||
public IndexFieldMapper(Settings indexSettings) {
|
||||
this(Defaults.NAME, Defaults.NAME, Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), null, Defaults.ENABLED_STATE, null, indexSettings);
|
||||
this(Defaults.NAME, Defaults.NAME, Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), Defaults.ENABLED_STATE, null, indexSettings);
|
||||
}
|
||||
|
||||
public IndexFieldMapper(String name, String indexName, float boost, FieldType fieldType, Boolean docValues, EnabledAttributeMapper enabledState,
|
||||
public IndexFieldMapper(String name, String indexName, float boost, FieldType fieldType, EnabledAttributeMapper enabledState,
|
||||
@Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||
super(new Names(name, indexName, indexName, name), boost, fieldType, docValues, Lucene.KEYWORD_ANALYZER,
|
||||
super(new Names(name, indexName, indexName, name), boost, fieldType, false, Lucene.KEYWORD_ANALYZER,
|
||||
Lucene.KEYWORD_ANALYZER, null, null, fieldDataSettings, indexSettings);
|
||||
this.enabledState = enabledState;
|
||||
}
|
||||
|
@ -143,11 +142,6 @@ public class IndexFieldMapper extends AbstractFieldMapper<String> implements Int
|
|||
return new FieldDataType(IndexFieldMapper.NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDocValues() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String value(Document document) {
|
||||
Field field = (Field) document.getField(names.indexName());
|
||||
return field == null ? null : value(field);
|
||||
|
@ -203,14 +197,14 @@ public class IndexFieldMapper extends AbstractFieldMapper<String> implements Int
|
|||
return builder;
|
||||
}
|
||||
builder.startObject(CONTENT_TYPE);
|
||||
if (writePre2xSettings && (includeDefaults || fieldType().stored() != Defaults.FIELD_TYPE.stored())) {
|
||||
if (indexCreatedBefore2x && (includeDefaults || fieldType().stored() != Defaults.FIELD_TYPE.stored())) {
|
||||
builder.field("store", fieldType().stored());
|
||||
}
|
||||
if (includeDefaults || enabledState != Defaults.ENABLED_STATE) {
|
||||
builder.field("enabled", enabledState.enabled);
|
||||
}
|
||||
|
||||
if (writePre2xSettings) {
|
||||
if (indexCreatedBefore2x) {
|
||||
if (customFieldDataSettings != null) {
|
||||
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
||||
} else if (includeDefaults) {
|
||||
|
|
|
@ -151,7 +151,7 @@ public class ParentFieldMapper extends AbstractFieldMapper<Uid> implements Inter
|
|||
private final BytesRef typeAsBytes;
|
||||
|
||||
protected ParentFieldMapper(String name, String indexName, String type, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||
super(new Names(name, indexName, indexName, name), Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), null,
|
||||
super(new Names(name, indexName, indexName, name), Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), false,
|
||||
Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER, null, null, fieldDataSettings, indexSettings);
|
||||
this.type = type;
|
||||
this.typeAsBytes = type == null ? null : new BytesRef(type);
|
||||
|
@ -176,11 +176,6 @@ public class ParentFieldMapper extends AbstractFieldMapper<Uid> implements Inter
|
|||
return new FieldDataType("_parent", settingsBuilder().put(Loading.KEY, Loading.EAGER_VALUE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDocValues() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preParse(ParseContext context) throws IOException {
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ public class RoutingFieldMapper extends AbstractFieldMapper<String> implements I
|
|||
}
|
||||
|
||||
protected RoutingFieldMapper(FieldType fieldType, boolean required, String path, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||
super(new Names(Defaults.NAME, Defaults.NAME, Defaults.NAME, Defaults.NAME), 1.0f, fieldType, null, Lucene.KEYWORD_ANALYZER,
|
||||
super(new Names(Defaults.NAME, Defaults.NAME, Defaults.NAME, Defaults.NAME), 1.0f, fieldType, false, Lucene.KEYWORD_ANALYZER,
|
||||
Lucene.KEYWORD_ANALYZER, null, null, fieldDataSettings, indexSettings);
|
||||
this.required = required;
|
||||
this.path = path;
|
||||
|
@ -147,11 +147,6 @@ public class RoutingFieldMapper extends AbstractFieldMapper<String> implements I
|
|||
return new FieldDataType("string");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDocValues() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void markAsRequired() {
|
||||
this.required = true;
|
||||
}
|
||||
|
@ -229,16 +224,16 @@ public class RoutingFieldMapper extends AbstractFieldMapper<String> implements I
|
|||
return builder;
|
||||
}
|
||||
builder.startObject(CONTENT_TYPE);
|
||||
if (writePre2xSettings && (includeDefaults || indexed != indexedDefault)) {
|
||||
if (indexCreatedBefore2x && (includeDefaults || indexed != indexedDefault)) {
|
||||
builder.field("index", indexTokenizeOptionToString(indexed, fieldType.tokenized()));
|
||||
}
|
||||
if (writePre2xSettings && (includeDefaults || fieldType.stored() != Defaults.FIELD_TYPE.stored())) {
|
||||
if (indexCreatedBefore2x && (includeDefaults || fieldType.stored() != Defaults.FIELD_TYPE.stored())) {
|
||||
builder.field("store", fieldType.stored());
|
||||
}
|
||||
if (includeDefaults || required != Defaults.REQUIRED) {
|
||||
builder.field("required", required);
|
||||
}
|
||||
if (writePre2xSettings && (includeDefaults || path != Defaults.PATH)) {
|
||||
if (indexCreatedBefore2x && (includeDefaults || path != Defaults.PATH)) {
|
||||
builder.field("path", path);
|
||||
}
|
||||
builder.endObject();
|
||||
|
|
|
@ -108,17 +108,12 @@ public class SizeFieldMapper extends IntegerFieldMapper implements RootMapper {
|
|||
}
|
||||
|
||||
public SizeFieldMapper(EnabledAttributeMapper enabled, FieldType fieldType, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||
super(new Names(Defaults.NAME), Defaults.PRECISION_STEP_32_BIT, Defaults.BOOST, fieldType, null, Defaults.NULL_VALUE,
|
||||
super(new Names(Defaults.NAME), Defaults.PRECISION_STEP_32_BIT, Defaults.BOOST, fieldType, false, Defaults.NULL_VALUE,
|
||||
Defaults.IGNORE_MALFORMED, Defaults.COERCE, null, null, fieldDataSettings,
|
||||
indexSettings, MultiFields.empty(), null);
|
||||
this.enabledState = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDocValues() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String contentType() {
|
||||
return Defaults.NAME;
|
||||
|
@ -164,14 +159,14 @@ public class SizeFieldMapper extends IntegerFieldMapper implements RootMapper {
|
|||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
||||
// all are defaults, no need to write it at all
|
||||
if (!includeDefaults && enabledState == Defaults.ENABLED_STATE && (writePre2xSettings == false || fieldType().stored() == false)) {
|
||||
if (!includeDefaults && enabledState == Defaults.ENABLED_STATE && (indexCreatedBefore2x == false || fieldType().stored() == false)) {
|
||||
return builder;
|
||||
}
|
||||
builder.startObject(contentType());
|
||||
if (includeDefaults || enabledState != Defaults.ENABLED_STATE) {
|
||||
builder.field("enabled", enabledState.enabled);
|
||||
}
|
||||
if (writePre2xSettings && (includeDefaults || fieldType().stored() == true)) {
|
||||
if (indexCreatedBefore2x && (includeDefaults || fieldType().stored() == true)) {
|
||||
builder.field("store", fieldType().stored());
|
||||
}
|
||||
builder.endObject();
|
||||
|
|
|
@ -207,7 +207,7 @@ public class SourceFieldMapper extends AbstractFieldMapper<byte[]> implements In
|
|||
|
||||
protected SourceFieldMapper(String name, boolean enabled, String format, Boolean compress, long compressThreshold,
|
||||
String[] includes, String[] excludes, Settings indexSettings) {
|
||||
super(new Names(name, name, name, name), Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), null,
|
||||
super(new Names(name, name, name, name), Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), false,
|
||||
Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER, null, null, null, indexSettings); // Only stored.
|
||||
this.enabled = enabled;
|
||||
this.compress = compress;
|
||||
|
@ -241,11 +241,6 @@ public class SourceFieldMapper extends AbstractFieldMapper<byte[]> implements In
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDocValues() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preParse(ParseContext context) throws IOException {
|
||||
super.parse(context);
|
||||
|
|
|
@ -132,7 +132,7 @@ public class TTLFieldMapper extends LongFieldMapper implements InternalMapper, R
|
|||
protected TTLFieldMapper(FieldType fieldType, EnabledAttributeMapper enabled, long defaultTTL, Explicit<Boolean> ignoreMalformed,
|
||||
Explicit<Boolean> coerce, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||
super(new Names(Defaults.NAME, Defaults.NAME, Defaults.NAME, Defaults.NAME), Defaults.PRECISION_STEP_64_BIT,
|
||||
Defaults.BOOST, fieldType, null, Defaults.NULL_VALUE, ignoreMalformed, coerce,
|
||||
Defaults.BOOST, fieldType, false, Defaults.NULL_VALUE, ignoreMalformed, coerce,
|
||||
null, null, fieldDataSettings, indexSettings, MultiFields.empty(), null);
|
||||
this.enabledState = enabled;
|
||||
this.defaultTTL = defaultTTL;
|
||||
|
@ -146,11 +146,6 @@ public class TTLFieldMapper extends LongFieldMapper implements InternalMapper, R
|
|||
return this.defaultTTL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDocValues() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Overrides valueForSearch to display live value of remaining ttl
|
||||
@Override
|
||||
public Object valueForSearch(Object value) {
|
||||
|
|
|
@ -230,6 +230,11 @@ public class TimestampFieldMapper extends DateFieldMapper implements InternalMap
|
|||
return defaultFieldType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean defaultDocValues() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean enabled() {
|
||||
return this.enabledState.enabled;
|
||||
}
|
||||
|
@ -310,7 +315,7 @@ public class TimestampFieldMapper extends DateFieldMapper implements InternalMap
|
|||
fieldType.stored() == Defaults.FIELD_TYPE.stored() && enabledState == Defaults.ENABLED && path == Defaults.PATH
|
||||
&& dateTimeFormatter.format().equals(Defaults.DATE_TIME_FORMATTER.format())
|
||||
&& Defaults.DEFAULT_TIMESTAMP.equals(defaultTimestamp)
|
||||
&& Defaults.DOC_VALUES == hasDocValues()) {
|
||||
&& defaultDocValues() == hasDocValues()) {
|
||||
return builder;
|
||||
}
|
||||
builder.startObject(CONTENT_TYPE);
|
||||
|
@ -323,7 +328,7 @@ public class TimestampFieldMapper extends DateFieldMapper implements InternalMap
|
|||
if (includeDefaults || fieldType.stored() != Defaults.FIELD_TYPE.stored()) {
|
||||
builder.field("store", fieldType.stored());
|
||||
}
|
||||
if (includeDefaults || hasDocValues() != Defaults.DOC_VALUES) {
|
||||
if (includeDefaults || hasDocValues() != defaultDocValues()) {
|
||||
builder.field(TypeParsers.DOC_VALUES, docValues);
|
||||
}
|
||||
if (includeDefaults || path != Defaults.PATH) {
|
||||
|
|
|
@ -34,7 +34,6 @@ import org.elasticsearch.Version;
|
|||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.lucene.BytesRefs;
|
||||
import org.elasticsearch.common.lucene.Lucene;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||
|
@ -109,7 +108,7 @@ public class TypeFieldMapper extends AbstractFieldMapper<String> implements Inte
|
|||
}
|
||||
|
||||
public TypeFieldMapper(String name, String indexName, float boost, FieldType fieldType, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||
super(new Names(name, indexName, indexName, name), boost, fieldType, null, Lucene.KEYWORD_ANALYZER,
|
||||
super(new Names(name, indexName, indexName, name), boost, fieldType, false, Lucene.KEYWORD_ANALYZER,
|
||||
Lucene.KEYWORD_ANALYZER, null, null, fieldDataSettings, indexSettings);
|
||||
}
|
||||
|
||||
|
@ -123,11 +122,6 @@ public class TypeFieldMapper extends AbstractFieldMapper<String> implements Inte
|
|||
return new FieldDataType("string");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDocValues() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String value(Object value) {
|
||||
if (value == null) {
|
||||
|
@ -191,7 +185,7 @@ public class TypeFieldMapper extends AbstractFieldMapper<String> implements Inte
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
if (writePre2xSettings == false) {
|
||||
if (indexCreatedBefore2x == false) {
|
||||
return builder;
|
||||
}
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
|
|
@ -108,9 +108,16 @@ public class UidFieldMapper extends AbstractFieldMapper<Uid> implements Internal
|
|||
}
|
||||
|
||||
protected UidFieldMapper(String name, String indexName, Boolean docValues, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||
super(new Names(name, indexName, indexName, name), Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), docValues,
|
||||
super(new Names(name, indexName, indexName, name), Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), docValuesEnabled(docValues, indexSettings),
|
||||
Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER, null, null, fieldDataSettings, indexSettings);
|
||||
}
|
||||
|
||||
static Boolean docValuesEnabled(Boolean docValues, Settings indexSettings) {
|
||||
if (Version.indexCreated(indexSettings).onOrAfter(Version.V_2_0_0)) {
|
||||
return false; // explicitly disable doc values for 2.0+, for now
|
||||
}
|
||||
return docValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldType defaultFieldType() {
|
||||
|
@ -202,7 +209,7 @@ public class UidFieldMapper extends AbstractFieldMapper<Uid> implements Internal
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
if (writePre2xSettings == false) {
|
||||
if (indexCreatedBefore2x == false) {
|
||||
return builder;
|
||||
}
|
||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||
|
|
|
@ -96,7 +96,7 @@ public class VersionFieldMapper extends AbstractFieldMapper<Long> implements Int
|
|||
};
|
||||
|
||||
public VersionFieldMapper(Settings indexSettings) {
|
||||
super(new Names(NAME, NAME, NAME, NAME), Defaults.BOOST, Defaults.FIELD_TYPE, null, null, null, null, null, null, indexSettings);
|
||||
super(new Names(NAME, NAME, NAME, NAME), Defaults.BOOST, Defaults.FIELD_TYPE, true, null, null, null, null, null, indexSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -170,9 +170,4 @@ public class VersionFieldMapper extends AbstractFieldMapper<Long> implements Int
|
|||
public void close() {
|
||||
fieldCache.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDocValues() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,32 +61,36 @@ public abstract class AbstractFieldDataTests extends ElasticsearchSingleNodeTest
|
|||
}
|
||||
|
||||
public <IFD extends IndexFieldData<?>> IFD getForField(String fieldName) {
|
||||
return getForField(getFieldDataType(), fieldName);
|
||||
return getForField(getFieldDataType(), fieldName, hasDocValues());
|
||||
}
|
||||
|
||||
public <IFD extends IndexFieldData<?>> IFD getForField(FieldDataType type, String fieldName) {
|
||||
return getForField(type, fieldName, hasDocValues());
|
||||
}
|
||||
|
||||
public <IFD extends IndexFieldData<?>> IFD getForField(FieldDataType type, String fieldName, boolean docValues) {
|
||||
final FieldMapper<?> mapper;
|
||||
final BuilderContext context = new BuilderContext(indexService.settingsService().getSettings(), new ContentPath(1));
|
||||
if (type.getType().equals("string")) {
|
||||
mapper = MapperBuilders.stringField(fieldName).tokenized(false).fieldDataSettings(type.getSettings()).build(context);
|
||||
mapper = MapperBuilders.stringField(fieldName).tokenized(false).docValues(docValues).fieldDataSettings(type.getSettings()).build(context);
|
||||
} else if (type.getType().equals("float")) {
|
||||
mapper = MapperBuilders.floatField(fieldName).fieldDataSettings(type.getSettings()).build(context);
|
||||
mapper = MapperBuilders.floatField(fieldName).docValues(docValues).fieldDataSettings(type.getSettings()).build(context);
|
||||
} else if (type.getType().equals("double")) {
|
||||
mapper = MapperBuilders.doubleField(fieldName).fieldDataSettings(type.getSettings()).build(context);
|
||||
mapper = MapperBuilders.doubleField(fieldName).docValues(docValues).fieldDataSettings(type.getSettings()).build(context);
|
||||
} else if (type.getType().equals("long")) {
|
||||
mapper = MapperBuilders.longField(fieldName).fieldDataSettings(type.getSettings()).build(context);
|
||||
mapper = MapperBuilders.longField(fieldName).docValues(docValues).fieldDataSettings(type.getSettings()).build(context);
|
||||
} else if (type.getType().equals("int")) {
|
||||
mapper = MapperBuilders.integerField(fieldName).fieldDataSettings(type.getSettings()).build(context);
|
||||
mapper = MapperBuilders.integerField(fieldName).docValues(docValues).fieldDataSettings(type.getSettings()).build(context);
|
||||
} else if (type.getType().equals("short")) {
|
||||
mapper = MapperBuilders.shortField(fieldName).fieldDataSettings(type.getSettings()).build(context);
|
||||
mapper = MapperBuilders.shortField(fieldName).docValues(docValues).fieldDataSettings(type.getSettings()).build(context);
|
||||
} else if (type.getType().equals("byte")) {
|
||||
mapper = MapperBuilders.byteField(fieldName).fieldDataSettings(type.getSettings()).build(context);
|
||||
mapper = MapperBuilders.byteField(fieldName).docValues(docValues).fieldDataSettings(type.getSettings()).build(context);
|
||||
} else if (type.getType().equals("geo_point")) {
|
||||
mapper = MapperBuilders.geoPointField(fieldName).fieldDataSettings(type.getSettings()).build(context);
|
||||
mapper = MapperBuilders.geoPointField(fieldName).docValues(docValues).fieldDataSettings(type.getSettings()).build(context);
|
||||
} else if (type.getType().equals("_parent")) {
|
||||
mapper = MapperBuilders.parent().type(fieldName).build(context);
|
||||
} else if (type.getType().equals("binary")) {
|
||||
mapper = MapperBuilders.binaryField(fieldName).fieldDataSettings(type.getSettings()).build(context);
|
||||
mapper = MapperBuilders.binaryField(fieldName).docValues(docValues).fieldDataSettings(type.getSettings()).build(context);
|
||||
} else {
|
||||
throw new UnsupportedOperationException(type.getType());
|
||||
}
|
||||
|
|
|
@ -474,7 +474,7 @@ public abstract class AbstractStringFieldDataTests extends AbstractFieldDataImpl
|
|||
fillExtendedMvSet();
|
||||
refreshReader();
|
||||
FieldDataType fieldDataType = new FieldDataType("string", ImmutableSettings.builder().put("global_values", "fixed"));
|
||||
IndexOrdinalsFieldData ifd = getForField(fieldDataType, "value");
|
||||
IndexOrdinalsFieldData ifd = getForField(fieldDataType, "value", hasDocValues());
|
||||
IndexOrdinalsFieldData globalOrdinals = ifd.loadGlobal(topLevelReader);
|
||||
assertThat(topLevelReader.leaves().size(), equalTo(3));
|
||||
|
||||
|
@ -601,11 +601,12 @@ public abstract class AbstractStringFieldDataTests extends AbstractFieldDataImpl
|
|||
fillExtendedMvSet();
|
||||
refreshReader();
|
||||
FieldDataType fieldDataType = new FieldDataType("string", ImmutableSettings.builder().put("global_values", "fixed").put("cache", "node"));
|
||||
IndexOrdinalsFieldData ifd = getForField(fieldDataType, "value");
|
||||
IndexOrdinalsFieldData ifd = getForField(fieldDataType, "value", hasDocValues());
|
||||
IndexOrdinalsFieldData globalOrdinals = ifd.loadGlobal(topLevelReader);
|
||||
assertThat(ifd.loadGlobal(topLevelReader), sameInstance(globalOrdinals));
|
||||
// 3 b/c 1 segment level caches and 1 top level cache
|
||||
assertThat(indicesFieldDataCache.getCache().size(), equalTo(4l));
|
||||
// in case of doc values, we don't cache atomic FD, so only the top-level cache is there
|
||||
assertThat(indicesFieldDataCache.getCache().size(), equalTo(hasDocValues() ? 1L : 4L));
|
||||
|
||||
IndexOrdinalsFieldData cachedInstance = null;
|
||||
for (Accountable ramUsage : indicesFieldDataCache.getCache().asMap().values()) {
|
||||
|
@ -617,7 +618,7 @@ public abstract class AbstractStringFieldDataTests extends AbstractFieldDataImpl
|
|||
assertThat(cachedInstance, sameInstance(globalOrdinals));
|
||||
topLevelReader.close();
|
||||
// Now only 3 segment level entries, only the toplevel reader has been closed, but the segment readers are still used by IW
|
||||
assertThat(indicesFieldDataCache.getCache().size(), equalTo(3l));
|
||||
assertThat(indicesFieldDataCache.getCache().size(), equalTo(hasDocValues() ? 0L : 3L));
|
||||
|
||||
refreshReader();
|
||||
assertThat(ifd.loadGlobal(topLevelReader), not(sameInstance(globalOrdinals)));
|
||||
|
|
|
@ -37,6 +37,11 @@ import static org.hamcrest.Matchers.equalTo;
|
|||
*/
|
||||
public class BinaryDVFieldDataTests extends AbstractFieldDataTests {
|
||||
|
||||
@Override
|
||||
protected boolean hasDocValues() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDocValue() throws Exception {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("test")
|
||||
|
|
|
@ -52,7 +52,7 @@ public class IndexFieldDataServiceTests extends ElasticsearchSingleNodeTest {
|
|||
final IndexFieldDataService ifdService = indexService.fieldData();
|
||||
for (boolean docValues : Arrays.asList(true, false)) {
|
||||
final BuilderContext ctx = new BuilderContext(indexService.settingsService().getSettings(), new ContentPath(1));
|
||||
final StringFieldMapper stringMapper = new StringFieldMapper.Builder("string").tokenized(false).fieldDataSettings(docValues ? DOC_VALUES_SETTINGS : ImmutableSettings.EMPTY).build(ctx);
|
||||
final StringFieldMapper stringMapper = new StringFieldMapper.Builder("string").tokenized(false).docValues(docValues).build(ctx);
|
||||
ifdService.clear();
|
||||
IndexFieldData<?> fd = ifdService.getForField(stringMapper);
|
||||
if (docValues) {
|
||||
|
@ -62,10 +62,10 @@ public class IndexFieldDataServiceTests extends ElasticsearchSingleNodeTest {
|
|||
}
|
||||
|
||||
for (FieldMapper<?> mapper : Arrays.asList(
|
||||
new ByteFieldMapper.Builder("int").fieldDataSettings(docValues ? DOC_VALUES_SETTINGS : ImmutableSettings.EMPTY).build(ctx),
|
||||
new ShortFieldMapper.Builder("int").fieldDataSettings(docValues ? DOC_VALUES_SETTINGS : ImmutableSettings.EMPTY).build(ctx),
|
||||
new IntegerFieldMapper.Builder("int").fieldDataSettings(docValues ? DOC_VALUES_SETTINGS : ImmutableSettings.EMPTY).build(ctx),
|
||||
new LongFieldMapper.Builder("long").fieldDataSettings(docValues ? DOC_VALUES_SETTINGS : ImmutableSettings.EMPTY).build(ctx)
|
||||
new ByteFieldMapper.Builder("int").docValues(docValues).build(ctx),
|
||||
new ShortFieldMapper.Builder("int").docValues(docValues).build(ctx),
|
||||
new IntegerFieldMapper.Builder("int").docValues(docValues).build(ctx),
|
||||
new LongFieldMapper.Builder("long").docValues(docValues).build(ctx)
|
||||
)) {
|
||||
ifdService.clear();
|
||||
fd = ifdService.getForField(mapper);
|
||||
|
@ -76,7 +76,7 @@ public class IndexFieldDataServiceTests extends ElasticsearchSingleNodeTest {
|
|||
}
|
||||
}
|
||||
|
||||
final FloatFieldMapper floatMapper = new FloatFieldMapper.Builder("float").fieldDataSettings(docValues ? DOC_VALUES_SETTINGS : ImmutableSettings.EMPTY).build(ctx);
|
||||
final FloatFieldMapper floatMapper = new FloatFieldMapper.Builder("float").docValues(docValues).build(ctx);
|
||||
ifdService.clear();
|
||||
fd = ifdService.getForField(floatMapper);
|
||||
if (docValues) {
|
||||
|
@ -85,7 +85,7 @@ public class IndexFieldDataServiceTests extends ElasticsearchSingleNodeTest {
|
|||
assertTrue(fd instanceof FloatArrayIndexFieldData);
|
||||
}
|
||||
|
||||
final DoubleFieldMapper doubleMapper = new DoubleFieldMapper.Builder("double").fieldDataSettings(docValues ? DOC_VALUES_SETTINGS : ImmutableSettings.EMPTY).build(ctx);
|
||||
final DoubleFieldMapper doubleMapper = new DoubleFieldMapper.Builder("double").docValues(docValues).build(ctx);
|
||||
ifdService.clear();
|
||||
fd = ifdService.getForField(doubleMapper);
|
||||
if (docValues) {
|
||||
|
|
|
@ -29,6 +29,11 @@ public class SortedSetDVStringFieldDataTests extends AbstractStringFieldDataTest
|
|||
return new FieldDataType("string", ImmutableSettings.builder().put("format", "doc_values").put(OrdinalsBuilder.FORCE_MULTI_ORDINALS, randomBoolean()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasDocValues() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long minRamBytesUsed() {
|
||||
return 0;
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* 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.index.mapper.all;
|
||||
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
public class AllMapperOnCusterTests extends ElasticsearchIntegrationTest {
|
||||
|
||||
private static final String INDEX = "index";
|
||||
private static final String TYPE = "type";
|
||||
|
||||
@Test
|
||||
public void test_doc_valuesInvalidMapping() throws Exception {
|
||||
String mapping = jsonBuilder().startObject().startObject("mappings").startObject(TYPE).startObject("_all").startObject("fielddata").field("format", "doc_values").endObject().endObject().endObject().endObject().endObject().string();
|
||||
try {
|
||||
prepareCreate(INDEX).setSource(mapping).get();
|
||||
fail();
|
||||
} catch (MapperParsingException e) {
|
||||
assertThat(e.getDetailedMessage(), containsString("[_all] is always tokenized and cannot have doc values"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,8 @@ package org.elasticsearch.index.mapper.all;
|
|||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.collect.Tuple;
|
||||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||
|
@ -29,6 +31,8 @@ import org.elasticsearch.common.lucene.all.AllEntries;
|
|||
import org.elasticsearch.common.lucene.all.AllField;
|
||||
import org.elasticsearch.common.lucene.all.AllTermQuery;
|
||||
import org.elasticsearch.common.lucene.all.AllTokenStream;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
|
@ -427,4 +431,31 @@ public class SimpleAllMapperTests extends ElasticsearchSingleNodeTest {
|
|||
mapping += "\"properties\":{}}" ;
|
||||
createIndex("test").mapperService().documentMapperParser().parse("test", mapping);
|
||||
}
|
||||
|
||||
public void testDocValuesNotAllowed() throws IOException {
|
||||
String mapping = jsonBuilder().startObject().startObject("type")
|
||||
.startObject("_all")
|
||||
.field("doc_values", true)
|
||||
.endObject().endObject().endObject().string();
|
||||
try {
|
||||
createIndex("test").mapperService().documentMapperParser().parse(mapping);
|
||||
fail();
|
||||
} catch (MapperParsingException e) {
|
||||
assertThat(e.getDetailedMessage(), containsString("[_all] is always tokenized and cannot have doc values"));
|
||||
}
|
||||
|
||||
|
||||
mapping = jsonBuilder().startObject().startObject("type")
|
||||
.startObject("_all")
|
||||
.startObject("fielddata")
|
||||
.field("format", "doc_values")
|
||||
.endObject().endObject().endObject().endObject().string();
|
||||
Settings legacySettings = ImmutableSettings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2.id).build();
|
||||
try {
|
||||
createIndex("test_old", legacySettings).mapperService().documentMapperParser().parse(mapping);
|
||||
fail();
|
||||
} catch (MapperParsingException e) {
|
||||
assertThat(e.getDetailedMessage(), containsString("[_all] is always tokenized and cannot have doc values"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ public class CopyToMapperTests extends ElasticsearchSingleNodeTest {
|
|||
|
||||
.startObject("int_to_str_test")
|
||||
.field("type", "integer")
|
||||
.field("doc_values", false)
|
||||
.array("copy_to", "another_field", "new_field")
|
||||
.endObject()
|
||||
.endObject().endObject().endObject().string();
|
||||
|
@ -111,7 +112,7 @@ public class CopyToMapperTests extends ElasticsearchSingleNodeTest {
|
|||
assertThat(doc.getFields("int_to_str_test").length, equalTo(1));
|
||||
assertThat(doc.getFields("int_to_str_test")[0].numericValue().intValue(), equalTo(42));
|
||||
|
||||
assertThat(doc.getFields("new_field").length, equalTo(1));
|
||||
assertThat(doc.getFields("new_field").length, equalTo(2)); // new field has doc values
|
||||
assertThat(doc.getFields("new_field")[0].numericValue().intValue(), equalTo(42));
|
||||
|
||||
fieldMapper = docMapper.mappers().name("new_field").mapper();
|
||||
|
@ -234,14 +235,27 @@ public class CopyToMapperTests extends ElasticsearchSingleNodeTest {
|
|||
XContentBuilder mapping = jsonBuilder().startObject()
|
||||
.startObject("type")
|
||||
.startObject("properties")
|
||||
.startObject("target")
|
||||
.field("type", "long")
|
||||
.field("doc_values", false)
|
||||
.endObject()
|
||||
.startObject("n1")
|
||||
.field("type", "nested")
|
||||
.startObject("properties")
|
||||
.startObject("target")
|
||||
.field("type", "long")
|
||||
.field("doc_values", false)
|
||||
.endObject()
|
||||
.startObject("n2")
|
||||
.field("type", "nested")
|
||||
.startObject("properties")
|
||||
.startObject("target")
|
||||
.field("type", "long")
|
||||
.field("doc_values", false)
|
||||
.endObject()
|
||||
.startObject("source")
|
||||
.field("type", "long")
|
||||
.field("doc_values", false)
|
||||
.startArray("copy_to")
|
||||
.value("target") // should go to the root doc
|
||||
.value("n1.target") // should go to the parent doc
|
||||
|
@ -250,7 +264,7 @@ public class CopyToMapperTests extends ElasticsearchSingleNodeTest {
|
|||
.endObject();
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (mapped) {
|
||||
mapping = mapping.startObject("target").field("type", "long").endObject();
|
||||
mapping = mapping.startObject("target").field("type", "long").field("doc_values", false).endObject();
|
||||
}
|
||||
mapping = mapping.endObject().endObject();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.index.mapper.date;
|
|||
|
||||
import org.apache.lucene.analysis.NumericTokenStream.NumericTermAttribute;
|
||||
import org.apache.lucene.analysis.TokenStream;
|
||||
import org.apache.lucene.index.DocValuesType;
|
||||
import org.apache.lucene.search.Filter;
|
||||
import org.apache.lucene.search.NumericRangeFilter;
|
||||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
|
@ -32,7 +33,12 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
|
|||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||
import org.elasticsearch.index.mapper.*;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.DocumentMapperParser;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.index.mapper.ParseContext;
|
||||
import org.elasticsearch.index.mapper.ParsedDocument;
|
||||
import org.elasticsearch.index.mapper.core.DateFieldMapper;
|
||||
import org.elasticsearch.index.mapper.core.LongFieldMapper;
|
||||
import org.elasticsearch.index.mapper.core.StringFieldMapper;
|
||||
|
@ -41,17 +47,25 @@ import org.elasticsearch.test.ElasticsearchSingleNodeTest;
|
|||
import org.elasticsearch.test.TestSearchContext;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.string.SimpleStringMappingTests.docValuesType;
|
||||
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasKey;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
public class SimpleDateMappingTests extends ElasticsearchSingleNodeTest {
|
||||
|
||||
@Test
|
||||
|
||||
public void testAutomaticDateParser() throws Exception {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("properties").endObject()
|
||||
|
@ -82,7 +96,6 @@ public class SimpleDateMappingTests extends ElasticsearchSingleNodeTest {
|
|||
assertThat(fieldMapper, instanceOf(StringFieldMapper.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseLocal() {
|
||||
assertThat(Locale.GERMAN, equalTo(LocaleUtils.parse("de")));
|
||||
assertThat(Locale.GERMANY, equalTo(LocaleUtils.parse("de_DE")));
|
||||
|
@ -98,7 +111,6 @@ public class SimpleDateMappingTests extends ElasticsearchSingleNodeTest {
|
|||
assertThat(Locale.ROOT, equalTo(LocaleUtils.parse("ROOT")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocale() throws IOException {
|
||||
String mapping = XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
|
@ -169,7 +181,6 @@ public class SimpleDateMappingTests extends ElasticsearchSingleNodeTest {
|
|||
assertThat(pos, equalTo(values.size()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTimestampAsDate() throws Exception {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("properties").startObject("date_field").field("type", "date").endObject().endObject()
|
||||
|
@ -187,7 +198,6 @@ public class SimpleDateMappingTests extends ElasticsearchSingleNodeTest {
|
|||
assertThat(doc.rootDoc().getField("date_field").tokenStream(defaultMapper.mappers().indexAnalyzer(), null), notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDateDetection() throws Exception {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.field("date_detection", false)
|
||||
|
@ -203,11 +213,10 @@ public class SimpleDateMappingTests extends ElasticsearchSingleNodeTest {
|
|||
.endObject()
|
||||
.bytes());
|
||||
|
||||
assertThat(doc.rootDoc().get("date_field"), nullValue());
|
||||
assertThat(doc.rootDoc().get("date_field"), equalTo("1262304000000"));
|
||||
assertThat(doc.rootDoc().get("date_field_x"), equalTo("2010-01-01"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
public void testHourFormat() throws Exception {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.field("date_detection", false)
|
||||
|
@ -235,9 +244,7 @@ public class SimpleDateMappingTests extends ElasticsearchSingleNodeTest {
|
|||
assertThat(rangeFilter.getMax(), equalTo(new DateTime(TimeValue.timeValueHours(11).millis()).getMillis()));
|
||||
assertThat(rangeFilter.getMin(), equalTo(new DateTime(TimeValue.timeValueHours(10).millis()).getMillis()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
|
||||
public void testDayWithoutYearFormat() throws Exception {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.field("date_detection", false)
|
||||
|
@ -265,8 +272,7 @@ public class SimpleDateMappingTests extends ElasticsearchSingleNodeTest {
|
|||
assertThat(rangeFilter.getMax(), equalTo(new DateTime(TimeValue.timeValueHours(35).millis()).getMillis()));
|
||||
assertThat(rangeFilter.getMin(), equalTo(new DateTime(TimeValue.timeValueHours(34).millis()).getMillis()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
public void testIgnoreMalformedOption() throws Exception {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("properties")
|
||||
|
@ -330,7 +336,6 @@ public class SimpleDateMappingTests extends ElasticsearchSingleNodeTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThatMergingWorks() throws Exception {
|
||||
String initialMapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("properties")
|
||||
|
@ -366,6 +371,22 @@ public class SimpleDateMappingTests extends ElasticsearchSingleNodeTest {
|
|||
Map<String, String> mergedConfig = getConfigurationViaXContent(mergedFieldMapper);
|
||||
assertThat(mergedConfig.get("format"), is("EEE MMM dd HH:mm:ss.S Z yyyy||EEE MMM dd HH:mm:ss.SSS Z yyyy||yyyy-MM-dd'T'HH:mm:ss.SSSZZ"));
|
||||
}
|
||||
|
||||
public void testDefaultDocValues() throws Exception {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("properties").startObject("date_field").field("type", "date").endObject().endObject()
|
||||
.endObject().endObject().string();
|
||||
|
||||
DocumentMapper defaultMapper = mapper(mapping);
|
||||
|
||||
ParsedDocument parsedDoc = defaultMapper.parse("type", "1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.field("date_field", "2010-01-01")
|
||||
.endObject()
|
||||
.bytes());
|
||||
ParseContext.Document doc = parsedDoc.rootDoc();
|
||||
assertEquals(DocValuesType.SORTED_NUMERIC, docValuesType(doc, "date_field"));
|
||||
}
|
||||
|
||||
private Map<String, String> getConfigurationViaXContent(DateFieldMapper dateFieldMapper) throws IOException {
|
||||
XContentBuilder builder = JsonXContent.contentBuilder().startObject();
|
||||
|
|
|
@ -55,7 +55,7 @@ public class SimpleIpMappingTests extends ElasticsearchSingleNodeTest {
|
|||
.bytes());
|
||||
|
||||
assertThat(doc.rootDoc().getField("ip").numericValue().longValue(), is(2130706433L));
|
||||
assertThat(doc.rootDoc().get("ip"), is(nullValue()));
|
||||
assertThat(doc.rootDoc().get("ip"), is("2130706433"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
package org.elasticsearch.index.mapper.string;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import org.apache.lucene.index.DocValuesType;
|
||||
import org.apache.lucene.index.IndexOptions;
|
||||
import org.apache.lucene.index.IndexableField;
|
||||
|
@ -28,19 +27,25 @@ import org.apache.lucene.index.IndexableFieldType;
|
|||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.queries.TermFilter;
|
||||
import org.apache.lucene.queries.TermsFilter;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.lucene.search.Queries;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.index.IndexService;
|
||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||
import org.elasticsearch.index.mapper.*;
|
||||
import org.elasticsearch.index.mapper.ContentPath;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper.MergeFlags;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper.MergeResult;
|
||||
import org.elasticsearch.index.mapper.DocumentMapperParser;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.index.mapper.Mapper.BuilderContext;
|
||||
import org.elasticsearch.index.mapper.ParseContext.Document;
|
||||
import org.elasticsearch.index.mapper.ParsedDocument;
|
||||
import org.elasticsearch.index.mapper.core.StringFieldMapper;
|
||||
import org.elasticsearch.index.IndexService;
|
||||
import org.elasticsearch.test.ElasticsearchSingleNodeTest;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -48,7 +53,9 @@ import org.junit.Test;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
/**
|
||||
*/
|
||||
|
@ -285,34 +292,83 @@ public class SimpleStringMappingTests extends ElasticsearchSingleNodeTest {
|
|||
assertThat(doc.rootDoc().getField("field6").fieldType().storeTermVectorPayloads(), equalTo(true));
|
||||
}
|
||||
|
||||
public void testDocValues() throws Exception {
|
||||
// doc values only work on non-analyzed content
|
||||
public void testDocValuesFielddata() throws Exception {
|
||||
IndexService indexService = createIndex("index");
|
||||
DocumentMapperParser parser = indexService.mapperService().documentMapperParser();
|
||||
final BuilderContext ctx = new BuilderContext(indexService.settingsService().getSettings(), new ContentPath(1));
|
||||
try {
|
||||
new StringFieldMapper.Builder("anything").fieldDataSettings(DOC_VALUES_SETTINGS).build(ctx);
|
||||
fail();
|
||||
} catch (Exception e) { /* OK */ }
|
||||
new StringFieldMapper.Builder("anything").tokenized(false).fieldDataSettings(DOC_VALUES_SETTINGS).build(ctx);
|
||||
new StringFieldMapper.Builder("anything").index(false).fieldDataSettings(DOC_VALUES_SETTINGS).build(ctx);
|
||||
|
||||
assertFalse(new StringFieldMapper.Builder("anything").index(false).build(ctx).hasDocValues());
|
||||
assertTrue(new StringFieldMapper.Builder("anything").index(false).fieldDataSettings(DOC_VALUES_SETTINGS).build(ctx).hasDocValues());
|
||||
assertTrue(new StringFieldMapper.Builder("anything").index(false).docValues(true).build(ctx).hasDocValues());
|
||||
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("properties")
|
||||
.startObject("str1")
|
||||
.field("type", "string")
|
||||
.startObject("fielddata")
|
||||
.field("format", "fst")
|
||||
.endObject()
|
||||
.endObject()
|
||||
.startObject("str2")
|
||||
.field("type", "string")
|
||||
.field("index", "not_analyzed")
|
||||
.startObject("fielddata")
|
||||
.field("format", "doc_values")
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject().endObject().string();
|
||||
|
||||
DocumentMapper defaultMapper = parser.parse(mapping);
|
||||
|
||||
ParsedDocument parsedDoc = defaultMapper.parse("type", "1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.field("str1", "1234")
|
||||
.field("str2", "1234")
|
||||
.endObject()
|
||||
.bytes());
|
||||
final Document doc = parsedDoc.rootDoc();
|
||||
assertEquals(DocValuesType.NONE, docValuesType(doc, "str1"));
|
||||
assertEquals(DocValuesType.SORTED_SET, docValuesType(doc, "str2"));
|
||||
}
|
||||
|
||||
public void testDocValues() throws Exception {
|
||||
// doc values only work on non-analyzed content
|
||||
final BuilderContext ctx = new BuilderContext(indexService.settingsService().getSettings(), new ContentPath(1));
|
||||
try {
|
||||
new StringFieldMapper.Builder("anything").docValues(true).build(ctx);
|
||||
fail();
|
||||
} catch (Exception e) { /* OK */ }
|
||||
|
||||
assertFalse(new StringFieldMapper.Builder("anything").index(false).build(ctx).hasDocValues());
|
||||
assertTrue(new StringFieldMapper.Builder("anything").index(true).tokenized(false).build(ctx).hasDocValues());
|
||||
assertFalse(new StringFieldMapper.Builder("anything").index(true).tokenized(true).build(ctx).hasDocValues());
|
||||
assertFalse(new StringFieldMapper.Builder("anything").index(false).tokenized(false).docValues(false).build(ctx).hasDocValues());
|
||||
assertTrue(new StringFieldMapper.Builder("anything").index(false).docValues(true).build(ctx).hasDocValues());
|
||||
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("properties")
|
||||
.startObject("str1")
|
||||
.field("type", "string")
|
||||
.startObject("fielddata")
|
||||
.field("format", "fst")
|
||||
.endObject()
|
||||
.field("index", "no")
|
||||
.endObject()
|
||||
.startObject("str2")
|
||||
.field("type", "string")
|
||||
.field("index", "not_analyzed")
|
||||
.startObject("fielddata")
|
||||
.field("format", "doc_values")
|
||||
.endObject()
|
||||
.endObject()
|
||||
.startObject("str3")
|
||||
.field("type", "string")
|
||||
.field("index", "analyzed")
|
||||
.endObject()
|
||||
.startObject("str4")
|
||||
.field("type", "string")
|
||||
.field("index", "not_analyzed")
|
||||
.field("doc_values", false)
|
||||
.endObject()
|
||||
.startObject("str5")
|
||||
.field("type", "string")
|
||||
.field("index", "no")
|
||||
.field("doc_values", true)
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject().endObject().string();
|
||||
|
@ -323,13 +379,21 @@ public class SimpleStringMappingTests extends ElasticsearchSingleNodeTest {
|
|||
.startObject()
|
||||
.field("str1", "1234")
|
||||
.field("str2", "1234")
|
||||
.field("str3", "1234")
|
||||
.field("str4", "1234")
|
||||
.field("str5", "1234")
|
||||
.endObject()
|
||||
.bytes());
|
||||
final Document doc = parsedDoc.rootDoc();
|
||||
assertEquals(DocValuesType.NONE, docValuesType(doc, "str1"));
|
||||
assertEquals(DocValuesType.SORTED_SET, docValuesType(doc, "str2"));
|
||||
assertEquals(DocValuesType.NONE, docValuesType(doc, "str3"));
|
||||
assertEquals(DocValuesType.NONE, docValuesType(doc, "str4"));
|
||||
assertEquals(DocValuesType.SORTED_SET, docValuesType(doc, "str5"));
|
||||
|
||||
}
|
||||
|
||||
// TODO: this function shouldn't be necessary. parsing should just add a single field that is indexed and dv
|
||||
public static DocValuesType docValuesType(Document document, String fieldName) {
|
||||
for (IndexableField field : document.getFields(fieldName)) {
|
||||
if (field.fieldType().docValuesType() != DocValuesType.NONE) {
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
|||
import org.elasticsearch.common.joda.Joda;
|
||||
import org.elasticsearch.common.lucene.Lucene;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
|
@ -183,6 +184,7 @@ public class TimestampMappingTests extends ElasticsearchSingleNodeTest {
|
|||
IndexRequest request = new IndexRequest("test", "type", "1").source(doc);
|
||||
try {
|
||||
request.process(metaData, mappingMetaData, true, "test");
|
||||
fail();
|
||||
} catch (TimestampParsingException e) {
|
||||
assertThat(e.getDetailedMessage(), containsString("timestamp is required by mapping"));
|
||||
}
|
||||
|
@ -488,11 +490,12 @@ public class TimestampMappingTests extends ElasticsearchSingleNodeTest {
|
|||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("_timestamp").field("enabled", randomBoolean()).startObject("fielddata").field("loading", "lazy").field("format", "doc_values").endObject().field("store", "yes").endObject()
|
||||
.endObject().endObject().string();
|
||||
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
|
||||
Settings indexSettings = ImmutableSettings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2.id).build();
|
||||
DocumentMapperParser parser = createIndex("test", indexSettings).mapperService().documentMapperParser();
|
||||
|
||||
DocumentMapper docMapper = parser.parse(mapping);
|
||||
assertThat(docMapper.timestampFieldMapper().fieldDataType().getLoading(), equalTo(FieldMapper.Loading.LAZY));
|
||||
assertThat(docMapper.timestampFieldMapper().fieldDataType().getFormat(docMapper.timestampFieldMapper().fieldDataType().getSettings()), equalTo("doc_values"));
|
||||
assertThat(docMapper.timestampFieldMapper().fieldDataType().getFormat(indexSettings), equalTo("doc_values"));
|
||||
mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("_timestamp").field("enabled", randomBoolean()).startObject("fielddata").field("loading", "eager").field("format", "array").endObject().field("store", "yes").endObject()
|
||||
.endObject().endObject().string();
|
||||
|
@ -500,7 +503,7 @@ public class TimestampMappingTests extends ElasticsearchSingleNodeTest {
|
|||
DocumentMapper.MergeResult mergeResult = docMapper.merge(parser.parse(mapping), DocumentMapper.MergeFlags.mergeFlags().simulate(false));
|
||||
assertThat(mergeResult.conflicts().length, equalTo(0));
|
||||
assertThat(docMapper.timestampFieldMapper().fieldDataType().getLoading(), equalTo(FieldMapper.Loading.EAGER));
|
||||
assertThat(docMapper.timestampFieldMapper().fieldDataType().getFormat(docMapper.timestampFieldMapper().fieldDataType().getSettings()), equalTo("array"));
|
||||
assertThat(docMapper.timestampFieldMapper().fieldDataType().getFormat(indexSettings), equalTo("array"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -558,7 +561,8 @@ public class TimestampMappingTests extends ElasticsearchSingleNodeTest {
|
|||
.field("default", "1970-01-01")
|
||||
.endObject()
|
||||
.endObject().endObject().string();
|
||||
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
|
||||
Settings indexSettings = ImmutableSettings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2.id).build();
|
||||
DocumentMapperParser parser = createIndex("test", indexSettings).mapperService().documentMapperParser();
|
||||
|
||||
DocumentMapper docMapper = parser.parse(mapping);
|
||||
assertThat(docMapper.timestampFieldMapper().fieldDataType().getLoading(), equalTo(FieldMapper.Loading.LAZY));
|
||||
|
@ -581,7 +585,7 @@ public class TimestampMappingTests extends ElasticsearchSingleNodeTest {
|
|||
assertThat(mergeResult.conflicts().length, equalTo(expectedConflicts.length));
|
||||
assertThat(docMapper.timestampFieldMapper().fieldDataType().getLoading(), equalTo(FieldMapper.Loading.LAZY));
|
||||
assertTrue(docMapper.timestampFieldMapper().enabled());
|
||||
assertThat(docMapper.timestampFieldMapper().fieldDataType().getFormat(docMapper.timestampFieldMapper().fieldDataType().getSettings()), equalTo("doc_values"));
|
||||
assertThat(docMapper.timestampFieldMapper().fieldDataType().getFormat(indexSettings), equalTo("doc_values"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -607,7 +611,14 @@ public class TimestampMappingTests extends ElasticsearchSingleNodeTest {
|
|||
.endObject().endObject().string();
|
||||
|
||||
DocumentMapper.MergeResult mergeResult = docMapper.merge(parser.parse(mapping), DocumentMapper.MergeFlags.mergeFlags().simulate(true));
|
||||
String[] expectedConflicts = {"mapper [_timestamp] has different index values", "mapper [_timestamp] has different tokenize values"};
|
||||
List<String> expectedConflicts = new ArrayList<>();
|
||||
expectedConflicts.add("mapper [_timestamp] has different index values");
|
||||
expectedConflicts.add("mapper [_timestamp] has different tokenize values");
|
||||
if (indexValues.get(0).equals("not_analyzed") == false) {
|
||||
// if the only index value left is not_analyzed, then the doc values setting will be the same, but in the
|
||||
// other two cases, it will change
|
||||
expectedConflicts.add("mapper [_timestamp] has different doc_values values");
|
||||
}
|
||||
|
||||
for (String conflict : mergeResult.conflicts()) {
|
||||
assertThat(conflict, isIn(expectedConflicts));
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"type":{"_timestamp":{"enabled":false,"doc_values":true,"fielddata":{"format":"doc_values"}},"_index":{"enabled":false},"_size":{"enabled":false},"properties":{}}}
|
||||
{"type":{"_timestamp":{"enabled":false},"_index":{"enabled":false},"_size":{"enabled":false},"properties":{}}}
|
|
@ -81,13 +81,13 @@ public class FieldDataTermsFilterTests extends ElasticsearchSingleNodeTest {
|
|||
new IndexWriterConfig(new StandardAnalyzer()));
|
||||
|
||||
// setup field mappers
|
||||
strMapper = new StringFieldMapper.Builder("str_value")
|
||||
strMapper = new StringFieldMapper.Builder("str_value").docValues(false)
|
||||
.build(new Mapper.BuilderContext(settings, new ContentPath(1)));
|
||||
|
||||
lngMapper = new LongFieldMapper.Builder("lng_value")
|
||||
lngMapper = new LongFieldMapper.Builder("lng_value").docValues(false)
|
||||
.build(new Mapper.BuilderContext(settings, new ContentPath(1)));
|
||||
|
||||
dblMapper = new DoubleFieldMapper.Builder("dbl_value")
|
||||
dblMapper = new DoubleFieldMapper.Builder("dbl_value").docValues(false)
|
||||
.build(new Mapper.BuilderContext(settings, new ContentPath(1)));
|
||||
|
||||
int numDocs = 10;
|
||||
|
|
|
@ -61,7 +61,7 @@ public abstract class AbstractChildTests extends ElasticsearchSingleNodeLuceneTe
|
|||
// Parent/child parsers require that the parent and child type to be presented in mapping
|
||||
// Sometimes we want a nested object field in the parent type that triggers nonNestedDocsFilter to be used
|
||||
mapperService.merge(parentType, new CompressedString(PutMappingRequest.buildFromSimplifiedDef(parentType, "nested_field", random().nextBoolean() ? "type=nested" : "type=object").string()), true);
|
||||
mapperService.merge(childType, new CompressedString(PutMappingRequest.buildFromSimplifiedDef(childType, "_parent", "type=" + parentType, CHILD_SCORE_NAME, "type=double").string()), true);
|
||||
mapperService.merge(childType, new CompressedString(PutMappingRequest.buildFromSimplifiedDef(childType, "_parent", "type=" + parentType, CHILD_SCORE_NAME, "type=double,doc_values=false").string()), true);
|
||||
return createSearchContext(indexService);
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ public class RandomExceptionCircuitBreakerTests extends ElasticsearchIntegration
|
|||
.startObject("test-str")
|
||||
.field("type", "string")
|
||||
.field("index", "not_analyzed")
|
||||
.field("doc_values", randomBoolean())
|
||||
.startObject("fielddata")
|
||||
.field("format", randomBytesFieldDataFormat())
|
||||
.endObject() // fielddata
|
||||
|
|
|
@ -51,6 +51,7 @@ import org.elasticsearch.rest.RestStatus;
|
|||
import org.elasticsearch.search.highlight.HighlightBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilders;
|
||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||
import org.elasticsearch.test.hamcrest.ElasticsearchAssertions;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -187,7 +188,7 @@ public class PercolatorTests extends ElasticsearchIntegrationTest {
|
|||
|
||||
@Test
|
||||
public void testSimple2() throws Exception {
|
||||
assertAcked(prepareCreate("test").addMapping("type1", "field1", "type=long"));
|
||||
assertAcked(prepareCreate("test").addMapping("type1", "field1", "type=long,doc_values=true"));
|
||||
ensureGreen();
|
||||
|
||||
// introduce the doc
|
||||
|
@ -250,15 +251,19 @@ public class PercolatorTests extends ElasticsearchIntegrationTest {
|
|||
response = client().preparePercolate()
|
||||
.setIndices("test").setDocumentType("type1")
|
||||
.setSource(doc).execute().actionGet();
|
||||
assertMatchCount(response, 2l);
|
||||
assertThat(response.getMatches(), arrayWithSize(2));
|
||||
assertThat(convertFromTextArray(response.getMatches(), "test"), arrayContainingInAnyOrder("test1", "test3"));
|
||||
ElasticsearchAssertions.assertFailures(response);
|
||||
// TODO: with doc values by default, fielddata execution mode causes a doc values
|
||||
// lookup, but memory index doesn't have doc values. we should consider just removing
|
||||
// execution mode.
|
||||
//assertMatchCount(response, 2l);
|
||||
//assertThat(response.getMatches(), arrayWithSize(2));
|
||||
//assertThat(convertFromTextArray(response.getMatches(), "test"), arrayContainingInAnyOrder("test1", "test3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRangeFilterThatUsesFD() throws Exception {
|
||||
client().admin().indices().prepareCreate("test")
|
||||
.addMapping("type1", "field1", "type=long")
|
||||
.addMapping("type1", "field1", "type=long,doc_values=false")
|
||||
.get();
|
||||
|
||||
|
||||
|
|
|
@ -317,12 +317,13 @@ public abstract class ElasticsearchIntegrationTest extends ElasticsearchTestCase
|
|||
if (frequently() && randomDynamicTemplates()) {
|
||||
mappings = XContentFactory.jsonBuilder().startObject().startObject("_default_");
|
||||
if (randomBoolean()) {
|
||||
boolean timestampEnabled = randomBoolean();
|
||||
mappings.startObject(TimestampFieldMapper.NAME)
|
||||
.field("enabled", randomBoolean())
|
||||
.startObject("fielddata")
|
||||
.field(FieldDataType.FORMAT_KEY, randomFrom("array", "doc_values"))
|
||||
.endObject()
|
||||
.endObject();
|
||||
.field("enabled", timestampEnabled);
|
||||
if (timestampEnabled) {
|
||||
mappings.field("doc_values", randomBoolean());
|
||||
}
|
||||
mappings.endObject();
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
mappings.startObject(SizeFieldMapper.NAME)
|
||||
|
@ -332,62 +333,54 @@ public abstract class ElasticsearchIntegrationTest extends ElasticsearchTestCase
|
|||
if (randomBoolean()) {
|
||||
mappings.startObject(AllFieldMapper.NAME)
|
||||
.field("auto_boost", true)
|
||||
.endObject();
|
||||
.endObject();
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
mappings.startObject(SourceFieldMapper.NAME)
|
||||
.field("compress", randomBoolean())
|
||||
.endObject();
|
||||
}
|
||||
if (compatibilityVersion().onOrAfter(Version.V_1_3_0) && compatibilityVersion().before(Version.V_2_0_0)) {
|
||||
// some tests rely on this BWC version behavior that we wanna keep
|
||||
mappings.startObject(FieldNamesFieldMapper.NAME)
|
||||
.startObject("fielddata")
|
||||
.field(FieldDataType.FORMAT_KEY, randomFrom("paged_bytes", "fst", "doc_values"))
|
||||
.endObject()
|
||||
.endObject();
|
||||
}
|
||||
mappings.startArray("dynamic_templates")
|
||||
.startObject()
|
||||
.startObject("template-strings")
|
||||
.field("match_mapping_type", "string")
|
||||
.startObject("template-strings")
|
||||
.field("match_mapping_type", "string")
|
||||
.startObject("mapping")
|
||||
.startObject("fielddata")
|
||||
.field(FieldDataType.FORMAT_KEY, randomFrom("paged_bytes", "fst")) // unfortunately doc values only work on not_analyzed fields
|
||||
.field(Loading.KEY, randomLoadingValues())
|
||||
.startObject("fielddata")
|
||||
.field(FieldDataType.FORMAT_KEY, randomFrom("paged_bytes", "fst"))
|
||||
.field(Loading.KEY, randomLoadingValues())
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject()
|
||||
.startObject()
|
||||
.startObject("template-longs")
|
||||
.field("match_mapping_type", "long")
|
||||
.startObject("mapping")
|
||||
.startObject("fielddata")
|
||||
.field(FieldDataType.FORMAT_KEY, randomFrom("array", "doc_values"))
|
||||
.field(Loading.KEY, randomFrom(Loading.LAZY, Loading.EAGER))
|
||||
.startObject("template-longs")
|
||||
.field("match_mapping_type", "long")
|
||||
.startObject("mapping")
|
||||
.field("doc_values", randomBoolean())
|
||||
.startObject("fielddata")
|
||||
.field(Loading.KEY, randomFrom(Loading.LAZY, Loading.EAGER))
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject()
|
||||
.startObject()
|
||||
.startObject("template-doubles")
|
||||
.field("match_mapping_type", "double")
|
||||
.startObject("mapping")
|
||||
.startObject("fielddata")
|
||||
.field(FieldDataType.FORMAT_KEY, randomFrom("array", "doc_values"))
|
||||
.field(Loading.KEY, randomFrom(Loading.LAZY, Loading.EAGER))
|
||||
.startObject("template-doubles")
|
||||
.field("match_mapping_type", "double")
|
||||
.startObject("mapping")
|
||||
.field("doc_values", randomBoolean())
|
||||
.startObject("fielddata")
|
||||
.field(Loading.KEY, randomFrom(Loading.LAZY, Loading.EAGER))
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject()
|
||||
.startObject()
|
||||
.startObject("template-geo_points")
|
||||
.field("match_mapping_type", "geo_point")
|
||||
.startObject("mapping")
|
||||
.startObject("fielddata")
|
||||
.field(FieldDataType.FORMAT_KEY, randomFrom("array", "doc_values"))
|
||||
.field(Loading.KEY, randomFrom(Loading.LAZY, Loading.EAGER))
|
||||
.startObject("template-geo_points")
|
||||
.field("match_mapping_type", "geo_point")
|
||||
.startObject("mapping")
|
||||
.field("doc_values", randomBoolean())
|
||||
.startObject("fielddata")
|
||||
.field(Loading.KEY, randomFrom(Loading.LAZY, Loading.EAGER))
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject()
|
||||
|
@ -1735,7 +1728,7 @@ public abstract class ElasticsearchIntegrationTest extends ElasticsearchTestCase
|
|||
* "paged_bytes", "fst", or "doc_values".
|
||||
*/
|
||||
public static String randomBytesFieldDataFormat() {
|
||||
return randomFrom(Arrays.asList("paged_bytes", "fst", "doc_values"));
|
||||
return randomFrom(Arrays.asList("paged_bytes", "fst"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -280,6 +280,12 @@ public class ElasticsearchAssertions {
|
|||
}
|
||||
}
|
||||
|
||||
public static void assertFailures(PercolateResponse percolateResponse) {
|
||||
assertThat("Expected at least one shard failure, got none",
|
||||
percolateResponse.getShardFailures().length, greaterThan(0));
|
||||
assertVersionSerializable(percolateResponse);
|
||||
}
|
||||
|
||||
public static void assertNoFailures(BroadcastOperationResponse response) {
|
||||
assertThat("Unexpected ShardFailures: " + Arrays.toString(response.getShardFailures()), response.getFailedShards(), equalTo(0));
|
||||
assertVersionSerializable(response);
|
||||
|
|
|
@ -32,7 +32,11 @@ import java.util.Locale;
|
|||
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.lessThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
/**
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue