From ebf1c8a1f545ce5f091d4b21f9b64816dd4bc871 Mon Sep 17 00:00:00 2001 From: Miroslav Pokorny Date: Sat, 28 Apr 2018 22:38:08 +1000 Subject: [PATCH] New field type=alias including support for querying and most reading. - #23714 - attempts to index an alias field fail. - introduced MappedFieldType.nameForMessages(), nameForIndex(), fieldTypeForIndex(), in the right places these are used rather than just a "raw" field or MappedFieldType.name() Goals and non goals. - Attempts to index into the alias field would result in an exception - it is read only - Queries - aggregations - "field" substituted with alias target. - "filter" fields substituted. - suggestions - scripts (using doc[]) (Not Done) - highlighting - fielddata_fields (deprecated/ Not Done) - docvalue_fields, - stored_fields would just get the data (and mapping) from the specified path - Source filtering would not work with the aliased field (Not done) - _source field when returned remains unmodified. --- docs/reference/mapping/types.asciidoc | 2 + docs/reference/mapping/types/alias.asciidoc | 145 ++ .../mapper/murmur3/Murmur3FieldMapper.java | 2 +- .../fielddata/IndexFieldDataService.java | 6 +- .../index/mapper/AliasFieldMapper.java | 711 ++++++++++ .../index/mapper/BooleanFieldMapper.java | 11 +- .../index/mapper/DateFieldMapper.java | 3 +- .../index/mapper/FieldMapper.java | 35 + .../index/mapper/GeoShapeFieldMapper.java | 2 +- .../index/mapper/IpFieldMapper.java | 5 +- .../index/mapper/MappedFieldType.java | 74 +- .../elasticsearch/index/mapper/Mapper.java | 7 + .../index/mapper/NumberFieldMapper.java | 4 +- .../index/mapper/RootObjectMapper.java | 36 + .../index/mapper/SimpleMappedFieldType.java | 6 +- .../index/query/QueryShardContext.java | 5 +- .../elasticsearch/indices/IndicesModule.java | 3 + .../search/fetch/FetchPhase.java | 3 + .../highlight/FastVectorHighlighter.java | 32 +- .../subphase/highlight/HighlightPhase.java | 6 +- .../subphase/highlight/HighlightUtils.java | 2 +- .../SourceSimpleFragmentsBuilder.java | 6 +- .../highlight/UnifiedHighlighter.java | 16 +- .../search/suggest/SuggestionBuilder.java | 3 +- .../index/mapper/AliasFieldMapperTests.java | 285 ++++ .../AliasFieldTypeBooleanFieldTypeTests.java | 46 + .../AliasFieldTypeDateFieldTypeTests.java | 51 + .../AliasFieldTypeGeoPointFieldTypeTests.java | 46 + .../AliasFieldTypeGeoShapeFieldTypeTests.java | 52 + .../AliasFieldTypeIpFieldTypeTests.java | 46 + .../AliasFieldTypeKeywordFieldTypeTests.java | 52 + .../AliasFieldTypeNumberFieldTypeTests.java | 46 + .../AliasFieldTypeRangeFieldTypeTests.java | 52 + .../AliasFieldTypeTextFieldTypeTests.java | 52 + .../index/mapper/BooleanFieldTypeTests.java | 27 +- .../index/mapper/DateFieldTypeTests.java | 56 +- .../index/mapper/DocumentParserTests.java | 190 ++- .../index/mapper/FieldMapperTestCase.java | 193 +++ .../index/mapper/GeoPointFieldTypeTests.java | 16 + .../index/mapper/GeoShapeFieldTypeTests.java | 42 +- .../index/mapper/IpFieldTypeTests.java | 71 +- .../index/mapper/KeywordFieldTypeTests.java | 65 +- .../index/mapper/MapperTesting.java | 33 + .../index/mapper/NumberFieldTypeTests.java | 117 +- .../index/mapper/RangeFieldTypeTests.java | 98 +- .../index/mapper/TextFieldTypeTests.java | 67 +- .../support/ValuesSourceConfigTests.java | 54 + .../highlight/HighlighterSearchIT.java | 1185 +++++++++-------- .../highlight/PlainHighlighterTests.java | 5 + .../search/sort/FieldSortBuilderTests.java | 19 + .../AbstractSuggestionBuilderTestCase.java | 11 +- .../CompletionSuggesterBuilderTests.java | 3 +- .../index/mapper/FieldTypeTestCase.java | 12 +- 53 files changed, 3236 insertions(+), 881 deletions(-) create mode 100644 docs/reference/mapping/types/alias.asciidoc create mode 100644 server/src/main/java/org/elasticsearch/index/mapper/AliasFieldMapper.java create mode 100644 server/src/test/java/org/elasticsearch/index/mapper/AliasFieldMapperTests.java create mode 100644 server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeBooleanFieldTypeTests.java create mode 100644 server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeDateFieldTypeTests.java create mode 100644 server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeGeoPointFieldTypeTests.java create mode 100644 server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeGeoShapeFieldTypeTests.java create mode 100644 server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeIpFieldTypeTests.java create mode 100644 server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeKeywordFieldTypeTests.java create mode 100644 server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeNumberFieldTypeTests.java create mode 100644 server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeRangeFieldTypeTests.java create mode 100644 server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeTextFieldTypeTests.java create mode 100644 server/src/test/java/org/elasticsearch/index/mapper/FieldMapperTestCase.java create mode 100644 server/src/test/java/org/elasticsearch/index/mapper/MapperTesting.java diff --git a/docs/reference/mapping/types.asciidoc b/docs/reference/mapping/types.asciidoc index 2cbc3a5bc54ad..bda4e5645166b 100644 --- a/docs/reference/mapping/types.asciidoc +++ b/docs/reference/mapping/types.asciidoc @@ -80,6 +80,8 @@ include::types/object.asciidoc[] include::types/text.asciidoc[] +include::types/alias.asciidoc[] + include::types/token-count.asciidoc[] include::types/percolator.asciidoc[] diff --git a/docs/reference/mapping/types/alias.asciidoc b/docs/reference/mapping/types/alias.asciidoc new file mode 100644 index 0000000000000..8198ad946a711 --- /dev/null +++ b/docs/reference/mapping/types/alias.asciidoc @@ -0,0 +1,145 @@ +[[alias]] +=== Alias datatype + +An alias is an alternate name to an existing single field of any type. It is not possible +to perform any sort of computation or reference or combination in anyway involving +multiple fields in any way. Aliases are simply a mechanism to provide an alternate +or shorthand name for any number of reasons. Queries and similar operations will yield +the same results using either the alias or target field name. The value specifically +for the field will be identical for both the alias or target. + +Aliases cannot be used to update the index or target field, any such attempts will result in +an error and the operation will be aborted. + +Below is an example of a mapping for an alias field pointing to a alias field: + +[source,js] +-------------------------------- +PUT my_index +{ + "mappings": { + "simpledocument": { + "properties": { + "textField1": { + "type": "text" + }, + "aliasToTextField2": { + "path": "textField1" + } + } + } + } +} +-------------------------------- +// CONSOLE + +The example below includes an alias in the root of the document, which points to a field +in a nested object and longer path. Queries and other similar supported operations,may thus +use the `place` field name or the longer `country.cityOrTown.name` with identical values +in the outcomes. + +[source,js] +-------------------------------------------------- +PUT my_index2 +{ + "mappings": { + "documenttype": { + "properties": { + "country": { + "properties": { + "name": { + "type": + "text" + }, + "cityOrTown": { + "properties": { + "name": { "type": "text" }, <1> + "population": { "type": "integer" } + } + } + } + } + "place": { + "type": "alias" + "path" "country.cityOrTown.name" <2> + }, + } + } + } +} +-------------------------------------------------- +// CONSOLE +<1> The target of the alias. This is used for index and similar operations. +<2> The alias `path` shorthand for `country.cityOrTown.name` + +[[text-params]] +==== Parameters for alias fields + +The following parameter(s) are accepted by `alias` fields: + +[horizontal] + +<>:: + + A path to another existing non alias field. Note `.` must be used to + denote a field nested with one or more objects. + +Paths limitations + +* cannot point to another alias. +* cannot point to an object +* target field must exist at the time of the mapping declaration. + + +No other fields are supported. + +[[indexing]] +==== Indexing + +Aliases are not a means of defining an index field or data to be index and as such do +not support any index or index store like fields. Any such attempts will fail with +an error message with details of the operation. + +[[supported-operations]] +==== Supported operations + +Aliases may be performed in only the following features, most of which have a +`field` parameter. The results will use the alias field name in the reply rather +than the target. + +- queries +- aggregations + - field `field` + - filter `field` + - missing `field` + - range `field` +- filters +- highlighting fields references +- docvalue_fields field references +- stored_field field references +- suggestions + +The results and values using either the alias or the target field, will receive +in the response the value. It is possible to request (eg docvalues) both the +alias and target and the response will contain both fields with the same value. + + +[[unsupported-operations]] +==== Unsupported operations + +The following features which take or support fields references do not honour alias +target references. Attempts to use the alias in place of a valid field will be equivalent +to referencing an unknown or non existing field. + +- index document additions +- index document updates. +- alias to a dynamic field, only fields present at the original mapping definition may + be aliased. +- scripts +- fielddata_fields (which are deprecated) +- Source filtering +- _source field holding the original index document remains untouched and since aliases + never actually in the indexed document never contains (mentions) the alias. +- wildcard queries hoping to match aliases. + +It is not possible to use an alias to perform a search against 2 fields. \ No newline at end of file diff --git a/plugins/mapper-murmur3/src/main/java/org/elasticsearch/index/mapper/murmur3/Murmur3FieldMapper.java b/plugins/mapper-murmur3/src/main/java/org/elasticsearch/index/mapper/murmur3/Murmur3FieldMapper.java index a6dc27b1f8a1c..658eef6d184ae 100644 --- a/plugins/mapper-murmur3/src/main/java/org/elasticsearch/index/mapper/murmur3/Murmur3FieldMapper.java +++ b/plugins/mapper-murmur3/src/main/java/org/elasticsearch/index/mapper/murmur3/Murmur3FieldMapper.java @@ -135,7 +135,7 @@ public Query existsQuery(QueryShardContext context) { @Override public Query termQuery(Object value, QueryShardContext context) { - throw new QueryShardException(context, "Murmur3 fields are not searchable: [" + name() + "]"); + throw new QueryShardException(context, "Murmur3 fields are not searchable: " + this.nameForMessages()); } } diff --git a/server/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java b/server/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java index a9d8df1cb264f..1478d262885f3 100644 --- a/server/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java +++ b/server/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java @@ -111,7 +111,7 @@ public > IFD getForField(MappedFieldType fieldType @SuppressWarnings("unchecked") public > IFD getForField(MappedFieldType fieldType, String fullyQualifiedIndexName) { - final String fieldName = fieldType.name(); + final String fieldName = fieldType.nameForIndex(); IndexFieldData.Builder builder = fieldType.fielddataBuilder(fullyQualifiedIndexName); IndexFieldDataCache cache; @@ -124,13 +124,13 @@ public > IFD getForField(MappedFieldType fieldType } else if ("none".equals(cacheType)){ cache = new IndexFieldDataCache.None(); } else { - throw new IllegalArgumentException("cache type not supported [" + cacheType + "] for field [" + fieldName + "]"); + throw new IllegalArgumentException("cache type not supported [" + cacheType + "] for field " + fieldType.nameForMessages()); } fieldDataCaches.put(fieldName, cache); } } - return (IFD) builder.build(indexSettings, fieldType, cache, circuitBreakerService, mapperService); + return (IFD) builder.build(indexSettings, fieldType.fieldTypeForIndex(), cache, circuitBreakerService, mapperService); } /** diff --git a/server/src/main/java/org/elasticsearch/index/mapper/AliasFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/AliasFieldMapper.java new file mode 100644 index 0000000000000..2c265f24853ee --- /dev/null +++ b/server/src/main/java/org/elasticsearch/index/mapper/AliasFieldMapper.java @@ -0,0 +1,711 @@ +/* + * 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; + +import joptsimple.internal.Strings; +import org.apache.lucene.index.DocValuesType; +import org.apache.lucene.index.IndexOptions; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.MultiTermQuery; +import org.apache.lucene.search.Query; +import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.geo.ShapeRelation; +import org.elasticsearch.common.joda.DateMathParser; +import org.elasticsearch.common.unit.Fuzziness; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.support.XContentMapValues; +import org.elasticsearch.index.analysis.NamedAnalyzer; +import org.elasticsearch.index.fielddata.IndexFieldData; +import org.elasticsearch.index.query.QueryRewriteContext; +import org.elasticsearch.index.query.QueryShardContext; +import org.elasticsearch.index.similarity.SimilarityProvider; +import org.elasticsearch.search.DocValueFormat; +import org.joda.time.DateTimeZone; + +import java.io.IOException; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static org.elasticsearch.index.mapper.TypeParsers.parseField; + +/** + * A field mapper for alias fields. + */ +public class AliasFieldMapper extends FieldMapper { + + public static final String CONTENT_TYPE = "alias"; + + public static class Defaults { + + public static final AliasFieldType FIELD_TYPE = new AliasFieldType(); + + // the next two options are just dummy values and shouldnt be considered sensible. + static final IndexOptions INDEX_OPTION = IndexOptions.NONE; + static final boolean DOCS_VALUE_SET = false; + + static { + FIELD_TYPE.freeze(); + } + } + + // captures the values from a mapping... + + /** + * Used to convert a property definition in a mapping where type=alias into a builder. + */ + public static class TypeParser implements Mapper.TypeParser { + + public static final String PATH = "path"; + + @Override + public AliasFieldMapper.Builder parse(final String name, + final Map node, + final ParserContext parserContext) throws MapperParsingException { + AliasFieldMapper.Builder builder = new AliasFieldMapper.Builder(name); + parseField(builder, name, node, parserContext); + + String path = null; + + for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); + String propName = entry.getKey(); + Object propNode = entry.getValue(); + if (propName.equals(PATH)) { + if (propNode == null) { + throw new MapperParsingException(propertyPathNull()); + } + path = XContentMapValues.nodeStringValue(propNode, name + "." + PATH).trim(); + if (path.isEmpty()) { + throw new MapperParsingException(propertyPathEmptyOrBlank()); + } + builder.path(path); + iterator.remove(); + } + } + + if(null == path){ + throw new MapperParsingException(propertyPathMissing()); + } + + return builder; + } + } + + /** + * Collects the properties of an alias property definition and eventually builds a AliasFieldMapper + */ + public static class Builder extends FieldMapper.Builder { + + private String path; + + public Builder(String name) { + super(name, Defaults.FIELD_TYPE, Defaults.FIELD_TYPE, Defaults.INDEX_OPTION, Defaults.DOCS_VALUE_SET); + this.builder = this; + } + + public Builder path(final String path) { + // TODO validate field names...HERE cant be null/empty etc. + this.path = path; + return this; + } + + @Override + public Builder tokenized(boolean tokenized) { + return readOnly(); + } + + @Override + public AliasFieldMapper build(BuilderContext context) { + if(true) setupFieldType(context); + return new AliasFieldMapper(this.name, this.path, (AliasFieldType)this.fieldType); + } + + @Override + protected void setupFieldType(BuilderContext context) { + // override to avoid calls to other setters. + fieldType.setName(buildFullName(context)); + } + } + + /* @VisibleForTesting*/ + public static class AliasFieldType extends MappedFieldType{ + + // @VisibleForTesting + public static String nameInMessage(final String aliasName, final String targetName) { + return nameInMessage(aliasName) + " -> " + nameInMessage(targetName); + } + + final RootObjectMapper mapping; + + final String pathTo; + + /** + * Might be initialised late. + */ + MappedFieldType aliasTarget; + + AliasFieldType() { + this(null, null, null, null); + } + + AliasFieldType(final RootObjectMapper rootObjectMapper, final String name, final String pathTo, final MappedFieldType aliasTarget) { + this.mapping = rootObjectMapper; + this.setName(name); + this.pathTo = pathTo; + + MappedFieldType aliasTarget0 = aliasTarget; + if(null==aliasTarget && null != rootObjectMapper) { + final FieldMapper fieldMapper = (FieldMapper) rootObjectMapper.mapperForPath(pathTo); + aliasTarget0 = fieldMapper.fieldType(); + } + + if(null!=aliasTarget0) { + // so the messages thrown will hold the alias name! + aliasTarget0.setAlias(this); //setAliased(this); + } + this.aliasTarget = aliasTarget0; + } + + public boolean isAlias() { + return true; + } + + public void setAlias(AliasFieldMapper.AliasFieldType alias) { + throw new IllegalArgumentException(propertyPathToAnotherAlias(alias.nameForMessages())); + } + + private boolean isAliasTargetPresent() { + return null != this.aliasTarget; + } + + MappedFieldType aliasTarget() { + Objects.requireNonNull(this.aliasTarget, "alias target not set"); + return this.aliasTarget; + } + + public String nameForIndex() { + return this.aliasTarget().name(); + } + + public String nameForMessages() { + return nameInMessage(this.name(), this.aliasTarget.name()); + } + + public MappedFieldType fieldTypeForIndex() { + return this.aliasTarget; + } + + @Override + void init() { + // overridden to stop super.init which setting some defaults by calling setters, + // which all throw UOE because the alias target is null + } + + @Override + public String typeName() { + return CONTENT_TYPE; + } + + // features... + + @Override + public boolean isSearchable() { + return this.aliasTarget().isSearchable(); + } + + @Override + public boolean isAggregatable() { + return this.aliasTarget().isAggregatable(); + } + + public void freeze() { + super.freeze(); + + // without this if, AliasFieldMapper.Defaults.FIELD_TYPE will throw + if(this.isAliasTargetPresent()) { + this.aliasTarget().freeze(); + } + } + + //@Override + public void checkCompatibility(MappedFieldType other, List conflicts) { + this.checkTypeName(other); + + final AliasFieldType aliasFieldType = (AliasFieldType) other; + this.aliasTarget().checkCompatibility(aliasFieldType.aliasTarget(), conflicts); + } + + // CAPABILITIES ETCs ALL read ops delegate, setters throw + + @Override + public boolean stored() { + return this.aliasTarget().stored(); + } + + @Override + public void setStored(boolean value) { + readOnly(); + } + + @Override + public boolean tokenized() { + return this.isAliasTargetPresent() ? this.aliasTarget().tokenized() : null; + } + + @Override + public void setTokenized(boolean value) { + readOnly(); + } + + @Override + public boolean storeTermVectors() { + return this.aliasTarget().storeTermVectors(); + } + + @Override + public void setStoreTermVectors(boolean value) { + readOnly(); + } + + @Override + public boolean storeTermVectorOffsets() { + return this.aliasTarget().storeTermVectorOffsets(); + } + + @Override + public void setStoreTermVectorOffsets(boolean value) { + readOnly(); + } + + @Override + public boolean storeTermVectorPositions() { + return this.aliasTarget().storeTermVectorPositions(); + } + + @Override + public void setStoreTermVectorPositions(boolean value) { + readOnly(); + } + + @Override + public boolean storeTermVectorPayloads() { + return this.aliasTarget().storeTermVectorPayloads(); + } + + @Override + public void setStoreTermVectorPayloads(boolean value) { + readOnly(); + } + + @Override + public boolean omitNorms() { + return this.aliasTarget().omitNorms(); + } + + @Override + public void setOmitNorms(boolean value) { + readOnly(); + } + + @Override + public IndexOptions indexOptions() { + return this.aliasTarget().indexOptions(); + } + + @Override + public void setIndexOptions(IndexOptions value) { + this.aliasTarget().setIndexOptions(value); + } + + @Override + public void setDimensions(int dimensionCount, int dimensionNumBytes) { + super.setDimensions(dimensionCount, dimensionNumBytes); + } + + @Override + public int pointDimensionCount() { + return this.aliasTarget().pointDimensionCount(); + } + + @Override + public int pointNumBytes() { + return this.aliasTarget().pointNumBytes(); + } + + @Override + public DocValuesType docValuesType() { + return this.aliasTarget().docValuesType(); + } + + @Override + public void setDocValuesType(DocValuesType type) { + readOnly(); + } + + @Override + public MappedFieldType clone() { + return new AliasFieldType(this.mapping, + this.name(), + this.pathTo, + this.isAliasTargetPresent() ? this.aliasTarget().clone() : null); + } + + + // INDEX PROPS + + @Override + public boolean hasDocValues() { + return this.aliasTarget().hasDocValues(); + } + + @Override + public void setHasDocValues(boolean hasDocValues) { + this.aliasTarget().setHasDocValues(hasDocValues); + } + + // INDEXING OPS + + @Override + public Object nullValue() { + return this.aliasTarget().nullValue(); + } + + @Override + public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) { + return this.aliasTarget().fielddataBuilder(fullyQualifiedIndexName); + } + + @Override + public DocValueFormat docValueFormat(@Nullable String format, DateTimeZone timeZone) { + return this.aliasTarget().docValueFormat(format, timeZone); + } + + // MISC... + + @Override + public boolean eagerGlobalOrdinals() { + return this.aliasTarget().eagerGlobalOrdinals(); + } + + @Override + public void setEagerGlobalOrdinals(boolean eagerGlobalOrdinals) { + this.aliasTarget().setEagerGlobalOrdinals(eagerGlobalOrdinals); + } + + // ANALYZER + + @Override + public NamedAnalyzer indexAnalyzer() { + return this.isAliasTargetPresent() ? this.aliasTarget().indexAnalyzer() : null; + } + + @Override + public void setIndexAnalyzer(NamedAnalyzer analyzer) { + this.aliasTarget().setIndexAnalyzer(analyzer); + } + + @Override + public NamedAnalyzer searchAnalyzer() { + return this.isAliasTargetPresent() ? this.aliasTarget().searchAnalyzer() : null; + } + + @Override + public void setSearchAnalyzer(NamedAnalyzer analyzer) { + this.aliasTarget().setSearchAnalyzer(analyzer); + } + + @Override + public NamedAnalyzer searchQuoteAnalyzer() { + return this.isAliasTargetPresent() ? this.aliasTarget().searchQuoteAnalyzer() : null; + } + + @Override + public void setSearchQuoteAnalyzer(NamedAnalyzer analyzer) { + this.aliasTarget().setSearchQuoteAnalyzer(analyzer); + } + + @Override + public SimilarityProvider similarity() { + return this.aliasTarget().similarity(); + } + + @Override + public void setSimilarity(SimilarityProvider similarity) { + this.aliasTarget().setSimilarity(similarity); + } + + @Override + public String nullValueAsString() { + return this.aliasTarget().nullValueAsString(); + } + + @Override + public void setNullValue(Object nullValue) { + this.aliasTarget().setNullValue(nullValue); + } + + // all query methods delegate to aliased target... + + @Override + public Query existsQuery(QueryShardContext context) { + return this.aliasTarget().existsQuery(context); + } + + @Override + public Query fuzzyQuery(Object value, + Fuzziness fuzziness, + int prefixLength, + int maxExpansions, + boolean transpositions) { + return this.aliasTarget().fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions); + } + + @Override + public Relation isFieldWithinQuery(IndexReader reader, + Object from, + Object to, + boolean includeLower, + boolean includeUpper, + DateTimeZone timeZone, + DateMathParser dateMathParser, + QueryRewriteContext context) throws IOException { + return this.aliasTarget().isFieldWithinQuery(reader, + from, + to, + includeLower, + includeUpper, + timeZone, + dateMathParser, + context); + } + + @Override + public Query nullValueQuery() { + return this.aliasTarget().nullValueQuery(); + } + + @Override + public Query prefixQuery(String value, MultiTermQuery.RewriteMethod method, QueryShardContext context) { + return this.aliasTarget().prefixQuery(value, method, context); + } + + @Override + public Query queryStringTermQuery(Term term) { + return this.aliasTarget().queryStringTermQuery(term); + } + + @Override + public Query rangeQuery(Object lowerTerm, + Object upperTerm, + boolean includeLower, + boolean includeUpper, + ShapeRelation relation, + DateTimeZone timeZone, + DateMathParser parser, + QueryShardContext context) { + return this.aliasTarget().rangeQuery(lowerTerm, + upperTerm, + includeLower, + includeUpper, + relation, + timeZone, + parser, + context); + } + + @Override + public Query regexpQuery(String value, + int flags, + int maxDeterminizedStates, + MultiTermQuery.RewriteMethod method, + QueryShardContext context) { + return this.aliasTarget().regexpQuery(value, flags, maxDeterminizedStates, method, context); + } + + @Override + public Query termQuery(Object value, QueryShardContext context) { + return this.aliasTarget().termQuery(value, context); + } + + @Override + public Query termsQuery(List values, QueryShardContext context) { + return this.aliasTarget().termsQuery(values, context); + } + + @Override + public float boost() { + return this.aliasTarget().boost(); + } + + @Override + public void setBoost(float boost) { + this.aliasTarget().setBoost(boost); + } + + // DISPLAY ... + @Override + public Object valueForDisplay(Object value) { + return this.aliasTarget().valueForDisplay(value); + } + + @Override + public boolean equals(final Object other) { + return this == other || other instanceof AliasFieldType && this.equals0((AliasFieldType) other); + } + + private boolean equals0(final AliasFieldType other) { + return this.name().equals(other.name()) && + Objects.equals(this.pathTo, other.pathTo) && + Objects.equals(this.aliasTarget, other.aliasTarget); // $aliasTarget could be null + } + + @Override + public int hashCode() { + return Objects.hash(this.name(), this.pathTo, this.aliasTarget); + } + + public String toString(){ + return CONTENT_TYPE; + } + } + + private final String path; + + private RootObjectMapper rootObjectMapper; + + protected AliasFieldMapper(final String simpleName, final String path, final AliasFieldType fieldType) { + super(simpleName); + + if(Strings.isNullOrEmpty(path)){ + throw new IllegalArgumentException(propertyPathMissing()); + } + this.path = path; + this.fieldType = fieldType; + this.multiFields = MultiFields.empty(); + this.copyTo = CopyTo.empty(); + } + + public MappedFieldType fieldType() { + return this.fieldType; + } + + @Override + public Iterator iterator() { + return Collections.emptyList().iterator(); + } + + /** + * Performs some validations on the path property. + * - does the path exist ? FAIL + * - is the path pointing to self ? FAIL + * - is the path pointing to another alias ? FAIL + * @param root the root holding all mappings. + */ + protected void rootObjectMapper(final RootObjectMapper root) { + this.rootObjectMapper = root; + + final String path = this.path; + final Mapper mapper = this.rootObjectMapper.mapperForPath(path); + if(null==mapper) { + report(propertyPathUnknown(path)); + } + if(this == mapper) { + report(propertyPathToSelf(path)); + } + if(mapper instanceof AliasFieldMapper) { + report(propertyPathToAnotherAlias(path)); + } + if(false == mapper instanceof FieldMapper) { + report(propertyPathNotField(path)); + } + + final FieldMapper fieldMapper = (FieldMapper) mapper; + +// final AliasFieldType type = (AliasFieldType)this.fieldType; +// //type.aliased = fieldMapper.fieldType(); +// type.set + fieldMapper.fieldType().setAlias((AliasFieldType)this.fieldType()); + } + + @Override + protected void parseCreateField(ParseContext context, List fields) throws IOException { + throw new UnsupportedOperationException(indexingUnsupported(name(), this.path)); + } + + @Override + protected String contentType() { + return CONTENT_TYPE; + } + + @Override + protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException { + // we only wish to write type and path fields + builder.field("type", contentType()); + if (null!=this.path) { + builder.field(TypeParser.PATH, this.path); + } + } + + // @VisibleForTesting + + static T readOnly() { + throw new UnsupportedOperationException("Fields of type [" + CONTENT_TYPE + "] are read only"); + } + + static String propertyPathMissing(){ + return "Property [" + TypeParser.PATH + "] required but is missing"; + } + + static String propertyPathNull(){ + return "Property [" + TypeParser.PATH + "] required but is null"; + } + + static String propertyPathEmptyOrBlank() { + return "Property [" + TypeParser.PATH + "] required but is empty or blank"; + } + + static String propertyPathUnknown(final String path) { + return "Property [" + TypeParser.PATH + "] is not mapped to a field path=[" + path + "]"; + } + + static String propertyPathToSelf(final String alias) { + return "Property [" + TypeParser.PATH + "] points to self " + alias; + } + + static String propertyPathToAnotherAlias(final String alias) { + return "Property [" + TypeParser.PATH + "] points to another alias " + alias; + } + + static String propertyPathNotField(final String path) { + return "Property [" + TypeParser.PATH + "] must point to a field (not object) path=[" + path + "]"; + } + + static String indexingUnsupported(final String aliasPath, final String pathTo) { + return "Field [" + aliasPath + "] is an alias field which cannot be indexed, perhaps you meant its target [" + pathTo + "]"; + } + + static void report(final String message) { + throw new MapperException(message); + } +} diff --git a/server/src/main/java/org/elasticsearch/index/mapper/BooleanFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/BooleanFieldMapper.java index 52b9a0d46e55d..1c8606610eaf9 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/BooleanFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/BooleanFieldMapper.java @@ -174,7 +174,7 @@ public BytesRef indexedValueForSearch(Object value) { return Values.FALSE; default: throw new IllegalArgumentException("Can't parse boolean value [" + - sValue + "], expected [true] or [false]"); + sValue + "], expected [true] or [false] in " + this.nameForMessages()); } } @@ -189,7 +189,8 @@ public Boolean valueForDisplay(Object value) { case "T": return true; default: - throw new IllegalArgumentException("Expected [T] or [F] but got [" + value + "]"); + throw new IllegalArgumentException("Expected [T] or [F] but got [" + value + "]" + + " in " + this.nameForMessages()); } } @@ -201,12 +202,12 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) { @Override public DocValueFormat docValueFormat(@Nullable String format, DateTimeZone timeZone) { + this.name(); if (format != null) { - throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] does not support custom formats"); + this.failUnsupportedFeature("custom formats"); } if (timeZone != null) { - throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() - + "] does not support custom time zones"); + this.failUnsupportedFeature("custom time zones"); } return DocValueFormat.BOOLEAN; } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java index 7f1f0b9568209..c7e754d0a70fb 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java @@ -265,8 +265,7 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower @Nullable DateTimeZone timeZone, @Nullable DateMathParser forcedDateParser, QueryShardContext context) { failIfNotIndexed(); if (relation == ShapeRelation.DISJOINT) { - throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + - "] does not support DISJOINT ranges"); + this.failUnsupportedFeature("DISJOINT ranges"); } DateMathParser parser = forcedDateParser == null ? dateMathParser diff --git a/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java index f23a8d0ce96aa..bb7ea08a65234 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java @@ -74,6 +74,29 @@ protected Builder(String name, MappedFieldType fieldType, MappedFieldType defaul multiFieldsBuilder = new MultiFields.Builder(); } + /** + * This ctor is only intended to be called by {@link AliasFieldMapper.Builder} and exists only + * because the other ctor above makes calls such as {@link MappedFieldType#indexOptions()} that will fail + * because the alias target is not yet set. + * @param name + * @param fieldType + * @param defaultFieldType + * @param defaultOptions + * @param docValuesSet + */ + protected Builder(final String name, + final MappedFieldType fieldType, + final MappedFieldType defaultFieldType, + final IndexOptions defaultOptions, + final boolean docValuesSet) { + super(name); + this.fieldType = fieldType.clone(); + this.defaultFieldType = defaultFieldType.clone(); + this.defaultOptions = defaultOptions; + this.docValuesSet = docValuesSet; + multiFieldsBuilder = new MultiFields.Builder(); + } + public MappedFieldType fieldType() { return fieldType; } @@ -247,6 +270,18 @@ protected FieldMapper(String simpleName, MappedFieldType fieldType, MappedFieldT this.copyTo = Objects.requireNonNull(copyTo); } + protected FieldMapper(String simpleName) { + super(simpleName); + if (simpleName.isEmpty()) { + throw new IllegalArgumentException("name cannot be empty string"); + } + this.indexCreatedVersion = null; + this.fieldType = null; + this.defaultFieldType = null; + this.multiFields = null; + this.copyTo = null; + } + @Override public String name() { return fieldType().name(); diff --git a/server/src/main/java/org/elasticsearch/index/mapper/GeoShapeFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/GeoShapeFieldMapper.java index 753d91f7be231..0c5fdb2710b2d 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/GeoShapeFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/GeoShapeFieldMapper.java @@ -455,7 +455,7 @@ public Query existsQuery(QueryShardContext context) { @Override public Query termQuery(Object value, QueryShardContext context) { - throw new QueryShardException(context, "Geo fields do not support exact searching, use dedicated geo queries instead"); + throw new QueryShardException(context, "Geo fields " + this.nameForMessages() + " do not support exact searching, use dedicated geo queries instead"); } } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/IpFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/IpFieldMapper.java index fd5dc080011e6..49e6b4fef2cbc 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/IpFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/IpFieldMapper.java @@ -305,11 +305,10 @@ public Object valueForDisplay(Object value) { @Override public DocValueFormat docValueFormat(@Nullable String format, DateTimeZone timeZone) { if (format != null) { - throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] does not support custom formats"); + this.failUnsupportedFeature("custom formats"); } if (timeZone != null) { - throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() - + "] does not support custom time zones"); + this.failUnsupportedFeature("custom time zones"); } return DocValueFormat.IP; } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java b/server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java index 69189ab129762..49eeda926f64c 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java @@ -56,6 +56,10 @@ */ public abstract class MappedFieldType extends FieldType { + public static String nameInMessage(final String name) { + return "[" + name + "]"; + } + private String name; private float boost; // TODO: remove this docvalues flag and use docValuesType @@ -83,6 +87,12 @@ protected MappedFieldType(MappedFieldType ref) { } public MappedFieldType() { + this.init(); + } + + // intended to only be overridden by AliasFieldMapper + void init() + { setTokenized(true); setStored(false); setStoreTermVectors(false); @@ -144,7 +154,7 @@ public int hashCode() { public abstract String typeName(); /** Checks this type is the same type as other. Adds a conflict if they are different. */ - private void checkTypeName(MappedFieldType other) { + protected final void checkTypeName(MappedFieldType other) { if (typeName().equals(other.typeName()) == false) { throw new IllegalArgumentException("mapper [" + name + "] cannot be changed from type [" + typeName() + "] to [" + other.typeName() + "]"); } else if (getClass() != other.getClass()) { @@ -213,6 +223,35 @@ public void setName(String name) { this.name = name; } + public boolean isAlias() { + return false; + } + + private AliasFieldMapper.AliasFieldType alias; + + public AliasFieldMapper.AliasFieldType alias() { + return alias; + } + + public void setAlias(AliasFieldMapper.AliasFieldType alias) { + // unfortunately aliases are set rather late after the type has been frozen! + this.alias = alias; + alias.aliasTarget = this; + } + + public String nameForIndex() { + return this.name(); + } + + public String nameForMessages() { + final AliasFieldMapper.AliasFieldType aliased = this.alias; + return null != aliased ? aliased.nameForMessages() : MappedFieldType.nameInMessage(this.name()); + } + + public MappedFieldType fieldTypeForIndex() { + return this; + } + public float boost() { return boost; } @@ -336,19 +375,23 @@ public Query rangeQuery( boolean includeLower, boolean includeUpper, ShapeRelation relation, DateTimeZone timeZone, DateMathParser parser, QueryShardContext context) { - throw new IllegalArgumentException("Field [" + name + "] of type [" + typeName() + "] does not support range queries"); + return this.failUnsupportedFeature("range queries"); } public Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) { - throw new IllegalArgumentException("Can only use fuzzy queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]"); + throw new IllegalArgumentException(this.invalidQuery("fuzzy")); } public Query prefixQuery(String value, @Nullable MultiTermQuery.RewriteMethod method, QueryShardContext context) { - throw new QueryShardException(context, "Can only use prefix queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]"); + throw new QueryShardException(context, this.invalidQuery("prefix")); } public Query regexpQuery(String value, int flags, int maxDeterminizedStates, @Nullable MultiTermQuery.RewriteMethod method, QueryShardContext context) { - throw new QueryShardException(context, "Can only use regexp queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]"); + throw new QueryShardException(context, this.invalidQuery("regexp")); + } + + private String invalidQuery(final String queryType) { + return "Can only use " + queryType + " queries on keyword and text fields - not on " + this.nameForMessages() + " which is of type [" + typeName() + "]"; } public Query nullValueQuery() { @@ -394,8 +437,8 @@ public Query queryStringTermQuery(Term term) { **/ protected final void failIfNoDocValues() { if (hasDocValues() == false) { - throw new IllegalArgumentException("Can't load fielddata on [" + name() - + "] because fielddata is unsupported on fields of type [" + throw new IllegalArgumentException("Can't load fielddata on " + this.nameForMessages() + + " because fielddata is unsupported on fields of type [" + typeName() + "]. Use doc values instead."); } } @@ -403,7 +446,7 @@ protected final void failIfNoDocValues() { protected final void failIfNotIndexed() { if (indexOptions() == IndexOptions.NONE && pointDimensionCount() == 0) { // we throw an IAE rather than an ISE so that it translates to a 4xx code rather than 5xx code on the http layer - throw new IllegalArgumentException("Cannot search on field [" + name() + "] since it is not indexed."); + throw new IllegalArgumentException("Cannot search on field " + this.nameForMessages() + " since it is not indexed."); } } @@ -421,10 +464,10 @@ public void setEagerGlobalOrdinals(boolean eagerGlobalOrdinals) { * The default implementation returns a {@link DocValueFormat#RAW}. */ public DocValueFormat docValueFormat(@Nullable String format, DateTimeZone timeZone) { if (format != null) { - throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] does not support custom formats"); + this.failUnsupportedFeature("custom formats"); } if (timeZone != null) { - throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] does not support custom time zones"); + this.failUnsupportedFeature("custom time zones"); } return DocValueFormat.RAW; } @@ -457,4 +500,15 @@ public static Term extractTerm(Query termQuery) { } return ((TermQuery) termQuery).getTerm(); } + + /** + * This method builds a message that is typically meant to be read by the user and reports something like an invalid + * query attempt. If this field is aliased, then the alias name will be used instead. + * @param feature A short string holding the feature + * @param Anything. + * @return Never happens because this always throws {@link IllegalArgumentException} + */ + protected final T failUnsupportedFeature(final String feature) { + throw new IllegalArgumentException("Field " + this.nameForMessages() + " of type [" + typeName() + "] does not support " + feature); + } } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/Mapper.java b/server/src/main/java/org/elasticsearch/index/mapper/Mapper.java index 051ac9da7f2ec..3bc559e873e92 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/Mapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/Mapper.java @@ -183,4 +183,11 @@ public final String simpleName() { * so that the current mapper is not modified. */ public abstract Mapper updateFieldType(Map fullNameToFieldType); + + /** + * Called just after a {@link RootObjectMapper} receives all contained mappers. + * @param root The enclosing {@link RootObjectMapper} + */ + protected void rootObjectMapper(final RootObjectMapper root) { + } } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java index 69793ca89b57d..0cbce010d9da2 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java @@ -927,9 +927,7 @@ public Object valueForDisplay(Object value) { @Override public DocValueFormat docValueFormat(String format, DateTimeZone timeZone) { if (timeZone != null) { - throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() - + "] does not support custom time zones"); - } + this.failUnsupportedFeature("custom time zones"); } if (format == null) { return DocValueFormat.RAW; } else { diff --git a/server/src/main/java/org/elasticsearch/index/mapper/RootObjectMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/RootObjectMapper.java index 009caf2b8e814..a4046fdd8812f 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/RootObjectMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/RootObjectMapper.java @@ -36,6 +36,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.HashMap; import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue; import static org.elasticsearch.index.mapper.TypeParsers.parseDateTimeFormatter; @@ -196,6 +197,7 @@ protected boolean processField(RootObjectMapper.Builder builder, String fieldNam private Explicit dateDetection; private Explicit numericDetection; private Explicit dynamicTemplates; + private final Map pathToMapper; RootObjectMapper(String name, boolean enabled, Dynamic dynamic, Map mappers, Explicit dynamicDateTimeFormatters, Explicit dynamicTemplates, @@ -205,6 +207,30 @@ protected boolean processField(RootObjectMapper.Builder builder, String fieldNam this.dynamicDateTimeFormatters = dynamicDateTimeFormatters; this.dateDetection = dateDetection; this.numericDetection = numericDetection; + + this.pathToMapper = new HashMap<>(); + this.collect(mappers.values().iterator(), ""); + this.pathToMapper.values() + .stream() + .forEach(m -> m.rootObjectMapper(this)); + } + + /** + * Builds a map holding the full path of all fields and the mapper handling each particular field. + * Note this method is called recursively due to the tree structure. + * @param mappers Iterator of mappers. + * @param pathPrefix The prefix to be added before all found mappers. + */ + private void collect(final Iterator mappers, final String pathPrefix) { + while(mappers.hasNext()){ + final Mapper m = mappers.next(); + final String path = pathPrefix + m.simpleName(); + this.pathToMapper.put(path, m); + if(m instanceof ObjectMapper){ + final ObjectMapper o = (ObjectMapper)m; + collect(o.iterator(), path + "."); + } + } } @Override @@ -324,4 +350,14 @@ protected void doXContent(XContentBuilder builder, ToXContent.Params params) thr builder.field("numeric_detection", numericDetection.value()); } } + + /** + * Returns a view of all full field paths to mappers + * + * @param path The path. + * @return The {@link Mapper} or null if none was found. + */ + public Mapper mapperForPath(final String path) { + return this.pathToMapper.get(path); + } } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/SimpleMappedFieldType.java b/server/src/main/java/org/elasticsearch/index/mapper/SimpleMappedFieldType.java index b91be82cd6b26..dea5f28fe1590 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/SimpleMappedFieldType.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/SimpleMappedFieldType.java @@ -42,8 +42,7 @@ protected SimpleMappedFieldType(MappedFieldType ref) { public final Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, ShapeRelation relation, DateTimeZone timeZone, DateMathParser parser, QueryShardContext context) { if (relation == ShapeRelation.DISJOINT) { - throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + - "] does not support DISJOINT ranges"); + this.failUnsupportedFeature("DISJOINT ranges"); } // We do not fail on non-null time zones and date parsers // The reasoning is that on query parsers, you might want to set a time zone or format for date fields @@ -57,7 +56,6 @@ public final Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includ */ protected Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, QueryShardContext context) { - throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() + "] does not support range queries"); + return this.failUnsupportedFeature("range queries"); } - } diff --git a/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java b/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java index 32a1f64d37b33..9d38980e49d80 100644 --- a/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java +++ b/server/src/main/java/org/elasticsearch/index/query/QueryShardContext.java @@ -59,6 +59,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.LongSupplier; @@ -162,7 +163,9 @@ public BitSetProducer bitsetFilter(Query filter) { } public > IFD getForField(MappedFieldType fieldType) { - return (IFD) indexFieldDataService.apply(fieldType, fullyQualifiedIndexName); + Objects.requireNonNull(fieldType, "fieldType is null"); + + return (IFD) indexFieldDataService.apply(fieldType.fieldTypeForIndex(), fullyQualifiedIndexName); } public void addNamedQuery(String name, Query query) { diff --git a/server/src/main/java/org/elasticsearch/indices/IndicesModule.java b/server/src/main/java/org/elasticsearch/indices/IndicesModule.java index 92faa0a71fda6..2b63268730577 100644 --- a/server/src/main/java/org/elasticsearch/indices/IndicesModule.java +++ b/server/src/main/java/org/elasticsearch/indices/IndicesModule.java @@ -27,6 +27,7 @@ import org.elasticsearch.common.geo.ShapesAvailability; import org.elasticsearch.common.inject.AbstractModule; import org.elasticsearch.common.io.stream.NamedWriteableRegistry.Entry; +import org.elasticsearch.index.mapper.AliasFieldMapper; import org.elasticsearch.index.mapper.BinaryFieldMapper; import org.elasticsearch.index.mapper.BooleanFieldMapper; import org.elasticsearch.index.mapper.CompletionFieldMapper; @@ -110,6 +111,8 @@ private Map getMappers(List mapperPlugi mappers.put(ObjectMapper.NESTED_CONTENT_TYPE, new ObjectMapper.TypeParser()); mappers.put(CompletionFieldMapper.CONTENT_TYPE, new CompletionFieldMapper.TypeParser()); mappers.put(GeoPointFieldMapper.CONTENT_TYPE, new GeoPointFieldMapper.TypeParser()); + mappers.put(AliasFieldMapper.CONTENT_TYPE, new AliasFieldMapper.TypeParser()); + if (ShapesAvailability.JTS_AVAILABLE && ShapesAvailability.SPATIAL4J_AVAILABLE) { mappers.put(GeoShapeFieldMapper.CONTENT_TYPE, new GeoShapeFieldMapper.TypeParser()); } diff --git a/server/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java b/server/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java index 683f7bbde168f..c8613c9479c4d 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java @@ -118,6 +118,9 @@ public void execute(SearchContext context) { if (context.getObjectMapper(fieldName) != null) { throw new IllegalArgumentException("field [" + fieldName + "] isn't a leaf field"); } + } else { + // fieldType might be an alias...get real index field name. + fieldName = fieldType.nameForIndex(); } if (fieldNames == null) { fieldNames = new HashSet<>(); diff --git a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/FastVectorHighlighter.java b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/FastVectorHighlighter.java index 22895807af69e..6fd7882481043 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/FastVectorHighlighter.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/FastVectorHighlighter.java @@ -36,7 +36,9 @@ import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.text.Text; +import org.elasticsearch.index.mapper.AliasFieldMapper; import org.elasticsearch.index.mapper.FieldMapper; +import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.search.fetch.FetchPhaseExecutionException; import org.elasticsearch.search.fetch.FetchSubPhase; import org.elasticsearch.search.fetch.subphase.highlight.SearchContextHighlight.Field; @@ -72,10 +74,11 @@ public HighlightField highlight(HighlighterContext highlighterContext) { SearchContext context = highlighterContext.context; FetchSubPhase.HitContext hitContext = highlighterContext.hitContext; FieldMapper mapper = highlighterContext.mapper; + final MappedFieldType fieldType = mapper.fieldType(); + final String fieldIndex = fieldType.nameForIndex(); if (canHighlight(mapper) == false) { - throw new IllegalArgumentException("the field [" + highlighterContext.fieldName + - "] should be indexed with term vector with position offsets to be used with fast vector highlighter"); + reportCantHighlight(fieldType); } Encoder encoder = field.fieldOptions().encoder().equals("html") ? @@ -97,7 +100,7 @@ public HighlightField highlight(HighlighterContext highlighterContext) { if (field.fieldOptions().numberOfFragments() == 0) { fragListBuilder = new SingleFragListBuilder(); - if (!forceSource && mapper.fieldType().stored()) { + if (!forceSource && fieldType.stored()) { fragmentsBuilder = new SimpleFragmentsBuilder(mapper, field.fieldOptions().preTags(), field.fieldOptions().postTags(), boundaryScanner); } else { @@ -108,7 +111,7 @@ public HighlightField highlight(HighlighterContext highlighterContext) { fragListBuilder = field.fieldOptions().fragmentOffset() == -1 ? new SimpleFragListBuilder() : new SimpleFragListBuilder(field.fieldOptions().fragmentOffset()); if (field.fieldOptions().scoreOrdered()) { - if (!forceSource && mapper.fieldType().stored()) { + if (!forceSource && fieldType.stored()) { fragmentsBuilder = new ScoreOrderFragmentsBuilder(field.fieldOptions().preTags(), field.fieldOptions().postTags(), boundaryScanner); } else { @@ -116,7 +119,7 @@ public HighlightField highlight(HighlighterContext highlighterContext) { field.fieldOptions().preTags(), field.fieldOptions().postTags(), boundaryScanner); } } else { - if (!forceSource && mapper.fieldType().stored()) { + if (!forceSource && fieldType.stored()) { fragmentsBuilder = new SimpleFragmentsBuilder(mapper, field.fieldOptions().preTags(), field.fieldOptions().postTags(), boundaryScanner); } else { @@ -173,12 +176,12 @@ public HighlightField highlight(HighlighterContext highlighterContext) { // Only send matched fields if they were requested to save time. if (field.fieldOptions().matchedFields() != null && !field.fieldOptions().matchedFields().isEmpty()) { fragments = cache.fvh.getBestFragments(fieldQuery, hitContext.reader(), hitContext.docId(), - mapper.fieldType().name(), field.fieldOptions().matchedFields(), fragmentCharSize, + fieldIndex, field.fieldOptions().matchedFields(), fragmentCharSize, numberOfFragments, entry.fragListBuilder, entry.fragmentsBuilder, field.fieldOptions().preTags(), field.fieldOptions().postTags(), encoder); } else { fragments = cache.fvh.getBestFragments(fieldQuery, hitContext.reader(), hitContext.docId(), - mapper.fieldType().name(), fragmentCharSize, numberOfFragments, entry.fragListBuilder, + fieldIndex, fragmentCharSize, numberOfFragments, entry.fragListBuilder, entry.fragmentsBuilder, field.fieldOptions().preTags(), field.fieldOptions().postTags(), encoder); } @@ -193,7 +196,7 @@ public HighlightField highlight(HighlighterContext highlighterContext) { FieldFragList fieldFragList = new SimpleFieldFragList(-1 /*ignored*/); fieldFragList.add(0, noMatchSize, Collections.emptyList()); fragments = entry.fragmentsBuilder.createFragments(hitContext.reader(), hitContext.docId(), - mapper.fieldType().name(), fieldFragList, 1, field.fieldOptions().preTags(), + fieldIndex, fieldFragList, 1, field.fieldOptions().preTags(), field.fieldOptions().postTags(), encoder); if (fragments != null && fragments.length > 0) { return new HighlightField(highlighterContext.fieldName, Text.convertFromStringArray(fragments)); @@ -204,14 +207,21 @@ public HighlightField highlight(HighlighterContext highlighterContext) { } catch (Exception e) { throw new FetchPhaseExecutionException(context, - "Failed to highlight field [" + highlighterContext.fieldName + "]", e); + "Failed to highlight field " + fieldType.nameForMessages(), e); } } @Override public boolean canHighlight(FieldMapper fieldMapper) { - return fieldMapper.fieldType().storeTermVectors() && fieldMapper.fieldType().storeTermVectorOffsets() - && fieldMapper.fieldType().storeTermVectorPositions(); + final MappedFieldType fieldType = fieldMapper.fieldType(); + return fieldType.storeTermVectors() && + fieldType.storeTermVectorOffsets() && + fieldType.storeTermVectorPositions(); + } + + private void reportCantHighlight(final MappedFieldType fieldType) { + throw new IllegalArgumentException("the field " + fieldType.nameForMessages() + + " should be indexed with term vector with position offsets to be used with fast vector highlighter"); } private static BoundaryScanner getBoundaryScanner(Field field) { diff --git a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightPhase.java b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightPhase.java index 6b9121b8f7b71..2c2d0fe590e6d 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightPhase.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightPhase.java @@ -26,6 +26,7 @@ import org.elasticsearch.index.mapper.DocumentMapper; import org.elasticsearch.index.mapper.FieldMapper; import org.elasticsearch.index.mapper.KeywordFieldMapper; +import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.SourceFieldMapper; import org.elasticsearch.index.mapper.TextFieldMapper; import org.elasticsearch.search.fetch.FetchSubPhase; @@ -84,9 +85,10 @@ public void hitExecute(SearchContext context, HitContext hitContext) { // it was a mistake and do not process it. // If the field was explicitly given we assume that whoever issued the query knew // what they were doing and try to highlight anyway. + final MappedFieldType fieldType = fieldMapper.fieldType().fieldTypeForIndex(); if (fieldNameContainsWildcards) { - if (fieldMapper.fieldType().typeName().equals(TextFieldMapper.CONTENT_TYPE) == false && - fieldMapper.fieldType().typeName().equals(KeywordFieldMapper.CONTENT_TYPE) == false) { + if (fieldType.typeName().equals(TextFieldMapper.CONTENT_TYPE) == false && + fieldType.typeName().equals(KeywordFieldMapper.CONTENT_TYPE) == false) { continue; } } diff --git a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightUtils.java b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightUtils.java index b241a686a248f..1488ae97cc4a7 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightUtils.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightUtils.java @@ -62,7 +62,7 @@ public static List loadFieldValues(SearchContextHighlight.Field field, F } else { SourceLookup sourceLookup = searchContext.lookup().source(); sourceLookup.setSegmentAndDocument(hitContext.readerContext(), hitContext.docId()); - textsToHighlight = sourceLookup.extractRawValues(mapper.fieldType().name()); + textsToHighlight = sourceLookup.extractRawValues(mapper.fieldType().nameForIndex()); } assert textsToHighlight != null; return textsToHighlight; diff --git a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/SourceSimpleFragmentsBuilder.java b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/SourceSimpleFragmentsBuilder.java index cd37863a67eea..9079df3b461de 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/SourceSimpleFragmentsBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/SourceSimpleFragmentsBuilder.java @@ -44,17 +44,19 @@ public SourceSimpleFragmentsBuilder(FieldMapper mapper, SearchContext searchCont @Override protected Field[] getFields(IndexReader reader, int docId, String fieldName) throws IOException { + // $fieldName is ignored as we ask mapper.fieldType which may or may not be an alias. // we know its low level reader, and matching docId, since that's how we call the highlighter with SourceLookup sourceLookup = searchContext.lookup().source(); sourceLookup.setSegmentAndDocument((LeafReaderContext) reader.getContext(), docId); - List values = sourceLookup.extractRawValues(mapper.fieldType().name()); + final String fieldInIndex = mapper.fieldType().nameForIndex(); + List values = sourceLookup.extractRawValues(fieldInIndex); if (values.isEmpty()) { return EMPTY_FIELDS; } Field[] fields = new Field[values.size()]; for (int i = 0; i < values.size(); i++) { - fields[i] = new Field(mapper.fieldType().name(), values.get(i).toString(), TextField.TYPE_NOT_STORED); + fields[i] = new Field(fieldInIndex, values.get(i).toString(), TextField.TYPE_NOT_STORED); } return fields; } diff --git a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/UnifiedHighlighter.java b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/UnifiedHighlighter.java index c7ada10fcf6fc..d6f63f18077c9 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/UnifiedHighlighter.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/UnifiedHighlighter.java @@ -59,6 +59,9 @@ public boolean canHighlight(FieldMapper fieldMapper) { @Override public HighlightField highlight(HighlighterContext highlighterContext) { FieldMapper fieldMapper = highlighterContext.mapper; + final MappedFieldType fieldType = fieldMapper.fieldType(); + final String fieldNameIndex = fieldType.nameForIndex(); + SearchContextHighlight.Field field = highlighterContext.field; SearchContext context = highlighterContext.context; FetchSubPhase.HitContext hitContext = highlighterContext.hitContext; @@ -72,18 +75,18 @@ public HighlightField highlight(HighlighterContext highlighterContext) { try { final Analyzer analyzer = - getAnalyzer(context.mapperService().documentMapper(hitContext.hit().getType()), fieldMapper.fieldType()); + getAnalyzer(context.mapperService().documentMapper(hitContext.hit().getType()), fieldType); List fieldValues = HighlightUtils.loadFieldValues(field, fieldMapper, context, hitContext); fieldValues = fieldValues.stream() - .map((s) -> convertFieldValue(fieldMapper.fieldType(), s)) + .map((s) -> convertFieldValue(fieldType, s)) .collect(Collectors.toList()); final IndexSearcher searcher = new IndexSearcher(hitContext.reader()); final CustomUnifiedHighlighter highlighter; final String fieldValue = mergeFieldValues(fieldValues, MULTIVAL_SEP_CHAR); - final OffsetSource offsetSource = getOffsetSource(fieldMapper.fieldType()); + final OffsetSource offsetSource = getOffsetSource(fieldType); if ((offsetSource == OffsetSource.ANALYSIS) && (fieldValue.length() > maxAnalyzedOffset)) { throw new IllegalArgumentException( - "The length of [" + highlighterContext.fieldName + "] field of [" + hitContext.hit().getId() + + "The length of [" + fieldNameIndex + "] field of [" + hitContext.hit().getId() + "] doc of [" + context.indexShard().shardId().getIndexName() + "] index " + "has exceeded [" + maxAnalyzedOffset + "] - maximum allowed to be analyzed for highlighting. " + "This maximum can be set by changing the [" + IndexSettings.MAX_ANALYZED_OFFSET_SETTING.getKey() + @@ -107,13 +110,12 @@ public HighlightField highlight(HighlighterContext highlighterContext) { } if (field.fieldOptions().requireFieldMatch()) { - final String fieldName = highlighterContext.fieldName; - highlighter.setFieldMatcher((name) -> fieldName.equals(name)); + highlighter.setFieldMatcher((name) -> fieldNameIndex.equals(name)); } else { highlighter.setFieldMatcher((name) -> true); } - Snippet[] fieldSnippets = highlighter.highlightField(highlighterContext.fieldName, + Snippet[] fieldSnippets = highlighter.highlightField(fieldNameIndex, highlighterContext.query, hitContext.docId(), numberOfFragments); for (Snippet fieldSnippet : fieldSnippets) { if (Strings.hasText(fieldSnippet.getText())) { diff --git a/server/src/main/java/org/elasticsearch/search/suggest/SuggestionBuilder.java b/server/src/main/java/org/elasticsearch/search/suggest/SuggestionBuilder.java index dcdc669539f53..06f388aabddb8 100644 --- a/server/src/main/java/org/elasticsearch/search/suggest/SuggestionBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/suggest/SuggestionBuilder.java @@ -321,7 +321,8 @@ protected void populateCommonFields(MapperService mapperService, SuggestionSearc suggestionContext.setAnalyzer(luceneAnalyzer); } - suggestionContext.setField(field); + // need to read actual MappedFieldType (rather than $field) to support aliases... + suggestionContext.setField(fieldType.nameForIndex()); if (size != null) { suggestionContext.setSize(size); diff --git a/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldMapperTests.java b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldMapperTests.java new file mode 100644 index 0000000000000..8d790d98cf05f --- /dev/null +++ b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldMapperTests.java @@ -0,0 +1,285 @@ +/* + * 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; + +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.xcontent.XContentFactory; + +import java.io.IOException; +import java.util.List; + +public class AliasFieldMapperTests extends FieldMapperTestCase { + + private static final String ALIAS1 = "alias1"; + private static final String NESTED2 = "nested2"; + private static final String TEXT3 = "text3"; + private static final String TEXT4 = "text4"; + private static final String TEXT5 = "text5"; + + private static final String ALIAS_TO_PATH = fieldPath(TEXT4); + private static final String ALIAS1_FIELD_MAPPING = aliasFieldMapping(TEXT4); + + private static final String VALUE4 = "value4"; + private static final String VALUE5 = "value5"; + + // MAPPING VALIDATION... + + public void testPathMissingFails() throws Exception { + final String mapping = Strings.toString(XContentFactory.jsonBuilder() + .startObject() + .startObject(TYPE) + .startObject("properties") + .startObject(ALIAS1) + .field("type", AliasFieldMapper.CONTENT_TYPE) + .endObject() + .endObject() + .endObject() + .endObject()); + this.documentMapperFails(mapping, + MapperParsingException.class, + AliasFieldMapper.propertyPathMissing()); + } + + public void testPathEmptyFails() throws Exception { + this.documentMapperFails(this.mapping(""), + MapperParsingException.class, + AliasFieldMapper.propertyPathEmptyOrBlank()); + } + + public void testPathBlankFails() throws Exception { + this.documentMapperFails(this.mapping(" "), + MapperParsingException.class, + AliasFieldMapper.propertyPathEmptyOrBlank()); + } + + public void testPathUnknownFails() throws Exception { + final String path = "path.to.nothing"; + this.documentMapperFails(this.mapping(path), + MapperException.class, + AliasFieldMapper.propertyPathUnknown(path)); + } + + public void testPathSelfFails() throws Exception { + this.documentMapperFails(this.mapping(ALIAS1), + MapperException.class, + AliasFieldMapper.propertyPathToSelf(ALIAS1)); + } + + public void testPathToAnotherAliasFails() throws Exception { + final String alias2 = "alias2"; + + final String mapping = Strings.toString(XContentFactory.jsonBuilder() + .startObject() + .startObject(TYPE) + .startObject("properties") + .startObject(ALIAS1) + .field("type", AliasFieldMapper.CONTENT_TYPE) + .field(AliasFieldMapper.TypeParser.PATH, alias2) + .endObject() + .startObject(alias2) + .field("type", AliasFieldMapper.CONTENT_TYPE) + .field(AliasFieldMapper.TypeParser.PATH, TEXT3) + .endObject() + .startObject(TEXT3).field("type", "text").endObject() + .endObject() + .endObject() + .endObject()); + this.documentMapperFails(mapping, + MapperException.class, + AliasFieldMapper.propertyPathToAnotherAlias(alias2)); + } + + public void testPathToNestedAliasFails() throws Exception { + final String alias3 = "alias3"; + final String pathTo3 = fieldPath(NESTED2, alias3); + + final String mapping = Strings.toString(XContentFactory.jsonBuilder() + .startObject() + .startObject(TYPE) + .startObject("properties") + .startObject(ALIAS1) + .field("type", AliasFieldMapper.CONTENT_TYPE) + .field(AliasFieldMapper.TypeParser.PATH, pathTo3) + .endObject() + .startObject(NESTED2) + .field("type", "nested") + .startObject("properties") + .startObject(alias3) + .field("type", AliasFieldMapper.CONTENT_TYPE) + .field(AliasFieldMapper.TypeParser.PATH, TEXT4) + .endObject() + .endObject() + .endObject() + .startObject(TEXT4).field("type", "text").endObject() + .endObject() + .endObject() + .endObject()); + this.documentMapperFails(mapping, + MapperException.class, + AliasFieldMapper.propertyPathToAnotherAlias(pathTo3)); + } + + public void testPathToNestedNestedAliasFails() throws Exception { + final String nested3 = "nested3"; + final String alias4 = "alias4"; + final String pathTo4 = fieldPath(NESTED2, nested3, alias4); + final String text5 = "text5"; + + final String mapping = Strings.toString(XContentFactory.jsonBuilder() + .startObject() + .startObject(TYPE) + .startObject("properties") + .startObject(ALIAS1) + .field("type", AliasFieldMapper.CONTENT_TYPE) + .field(AliasFieldMapper.TypeParser.PATH, pathTo4) + .endObject() + .startObject(NESTED2) + .field("type", "nested") + .startObject("properties") + .startObject(nested3) + .field("type", "nested") + .startObject("properties") + .startObject(alias4) + .field("type", AliasFieldMapper.CONTENT_TYPE) + .field(AliasFieldMapper.TypeParser.PATH, text5) + .endObject() + .endObject() + .endObject() + .endObject() + .endObject() + .startObject(text5).field("type", "text").endObject() + .endObject() + .endObject() + .endObject()); + this.documentMapperFails(mapping, + MapperException.class, + AliasFieldMapper.propertyPathToAnotherAlias(pathTo4)); + } + + public void testPathToObjectFails() throws Exception { + this.documentMapperFails(this.mapping(NESTED2), + MapperException.class, + AliasFieldMapper.propertyPathNotField(NESTED2)); + } + + public void testMappingValid() throws Exception { + this.documentMapper(); + } + + public void testSerialization() throws IOException { + this.checkFieldMapping(this.documentMapper(), + ALIAS1, + aliasFieldMapping(TEXT4)); + } + + // MERGE MAPPING... + + public void testMappingMergeSameMapping() throws Exception { + final String mapping = this.mapping(); + this.documentMapper(mapping); + this.mergeMapping(mapping); + + this.checkFieldMapping(this.documentMapperFromIndexService(), + ALIAS1, + ALIAS1_FIELD_MAPPING); + } + + public void testMappingMergeInvalidFails() throws Exception { + this.documentMapper(this.mapping(TEXT4)); + + this.mergeMappingFails(this.mapping(ALIAS1), + MapperException.class, + AliasFieldMapper.propertyPathToSelf(ALIAS1)); + } + + public void testMappingMergeUpdateDifferentMapping() throws Exception { + this.documentMapper(this.mapping(TEXT4)); + this.mergeMapping(this.mapping(TEXT5)); + + this.checkFieldMapping(this.documentMapperFromIndexService(), + ALIAS1, + aliasFieldMapping(TEXT5)); + } + + // INDEXING..... + + public void testMappingParseAliasFieldFails() throws Exception { + final BytesReference source = BytesReference + .bytes(XContentFactory.jsonBuilder() + .startObject() + .field(ALIAS1, VALUE4) + .endObject()); + + this.mappingParseFails(source, + MapperParsingException.class, + AliasFieldMapper.indexingUnsupported(ALIAS1, ALIAS_TO_PATH)); + } + + public void testMappingParseWithoutAliasField() throws Exception { + final List documents = this.mappingParse(this.source(VALUE4, VALUE5)); + this.checkDocumentCount(1, documents); + + final ParseContext.Document root = documents.get(0); + this.checkField(root, TEXT4, VALUE4); + this.checkField(root, TEXT5, VALUE5); + } + + @Override + protected String mapping() throws IOException { + return this.mapping(ALIAS_TO_PATH); + } + + private String mapping(final String aliasToPath) throws IOException { + return Strings.toString(XContentFactory.jsonBuilder() + .startObject() + .startObject(TYPE) + .startObject("properties") + .startObject(ALIAS1) + .field("type", AliasFieldMapper.CONTENT_TYPE) + .field(AliasFieldMapper.TypeParser.PATH, aliasToPath) + //.field("type", "text") + .endObject() + .startObject(NESTED2) + .field("type", "nested") + .startObject("properties") + .startObject(TEXT3).field("type", "text").field("index", true).endObject() + .endObject() + .endObject() + .startObject(TEXT4).field("type", "text").field("index", true).endObject() + .startObject(TEXT5).field("type", "text").field("index", true).endObject() + .endObject() + .endObject() + .endObject()); + } + + private static String aliasFieldMapping(final String pathTo) { + return "{\"alias1\":{\"type\":\"" + AliasFieldMapper.CONTENT_TYPE + "\",\"" + + AliasFieldMapper.TypeParser.PATH + "\":\"" + pathTo + "\"}}"; + } + + private BytesReference source(final String value4, final String value5) throws IOException { + return BytesReference + .bytes(XContentFactory.jsonBuilder() + .startObject() + .field(TEXT4, value4) + .field(TEXT5, value5) + .endObject()); + } +} diff --git a/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeBooleanFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeBooleanFieldTypeTests.java new file mode 100644 index 0000000000000..ff41a2eb1f145 --- /dev/null +++ b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeBooleanFieldTypeTests.java @@ -0,0 +1,46 @@ +/* + * 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; + +public class AliasFieldTypeBooleanFieldTypeTests extends BooleanFieldTypeTests { + + private static final String ALIASFIELD = "alias2"; + private final String PATHTO = BOOLEANFIELD; + + @Override + protected AliasFieldMapper.AliasFieldType createDefaultFieldType() { + return new AliasFieldMapper.AliasFieldType(null, + null, + PATHTO, + new BooleanFieldMapper.BooleanFieldType()); + } + + @Override + MappedFieldType createNamedDefaultFieldType() { + final AliasFieldMapper.AliasFieldType fieldType = this.createDefaultFieldType(); + fieldType.setName(ALIASFIELD); + fieldType.aliasTarget().setName(this.fieldTypeName()); + return fieldType; + } + + @Override + String fieldInMessage() { + return AliasFieldMapper.AliasFieldType.nameInMessage(ALIASFIELD, PATHTO); + } +} diff --git a/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeDateFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeDateFieldTypeTests.java new file mode 100644 index 0000000000000..a3a556501b196 --- /dev/null +++ b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeDateFieldTypeTests.java @@ -0,0 +1,51 @@ +/* + * 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; + +public class AliasFieldTypeDateFieldTypeTests extends DateFieldTypeTests { + + private static final String ALIASFIELD = "alias3"; + private final String PATHTO = DATEFIELD1; + + @Override + protected AliasFieldMapper.AliasFieldType createDefaultFieldType() { + return new AliasFieldMapper.AliasFieldType(null, + null, + PATHTO, + new DateFieldMapper.DateFieldType()); + } + + @Override + MappedFieldType createNamedDefaultFieldType() { + final AliasFieldMapper.AliasFieldType fieldType = this.createDefaultFieldType(); + fieldType.setName(ALIASFIELD); + fieldType.aliasTarget().setName(this.fieldTypeName()); + return fieldType; + } + + @Override + String fieldInMessage() { + return AliasFieldMapper.AliasFieldType.nameInMessage(ALIASFIELD, PATHTO); + } + + DateFieldMapper.DateFieldType toDateFieldType(final MappedFieldType fieldType) { + final AliasFieldMapper.AliasFieldType alias = (AliasFieldMapper.AliasFieldType)fieldType; + return (DateFieldMapper.DateFieldType) alias.aliasTarget(); + } +} diff --git a/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeGeoPointFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeGeoPointFieldTypeTests.java new file mode 100644 index 0000000000000..ccc328b4ded7e --- /dev/null +++ b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeGeoPointFieldTypeTests.java @@ -0,0 +1,46 @@ +/* + * 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; + +public class AliasFieldTypeGeoPointFieldTypeTests extends GeoPointFieldTypeTests { + + private static final String ALIASFIELD = "alias2"; + private final String PATHTO = GEOPOINTFIELD; + + @Override + protected AliasFieldMapper.AliasFieldType createDefaultFieldType() { + return new AliasFieldMapper.AliasFieldType(null, + null, + PATHTO, + new GeoPointFieldMapper.GeoPointFieldType()); + } + + @Override + MappedFieldType createNamedDefaultFieldType() { + final AliasFieldMapper.AliasFieldType fieldType = this.createDefaultFieldType(); + fieldType.setName(ALIASFIELD); + fieldType.aliasTarget().setName(this.fieldTypeName()); + return fieldType; + } + + @Override + String fieldInMessage() { + return ALIASFIELD; + } +} diff --git a/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeGeoShapeFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeGeoShapeFieldTypeTests.java new file mode 100644 index 0000000000000..42b1f10ba3f6d --- /dev/null +++ b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeGeoShapeFieldTypeTests.java @@ -0,0 +1,52 @@ +/* + * 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; + +public class AliasFieldTypeGeoShapeFieldTypeTests extends GeoShapeFieldTypeTests { + + private static final String ALIASFIELD = "alias2"; + private final String PATHTO = GEOSHAPEFIELD; + + @Override + protected AliasFieldMapper.AliasFieldType createDefaultFieldType() { + return new AliasFieldMapper.AliasFieldType(null, + null, + PATHTO, + new GeoShapeFieldMapper.GeoShapeFieldType()); + } + + @Override + MappedFieldType createNamedDefaultFieldType() { + final AliasFieldMapper.AliasFieldType fieldType = this.createDefaultFieldType(); + fieldType.setName(ALIASFIELD); + fieldType.aliasTarget().setName(this.fieldTypeName()); + return fieldType; + } + + @Override + String fieldInMessage() { + return ALIASFIELD; + } + + @Override + protected GeoShapeFieldMapper.GeoShapeFieldType toGeoShapeFieldType(final MappedFieldType fieldType) { + final AliasFieldMapper.AliasFieldType alias = (AliasFieldMapper.AliasFieldType)fieldType; + return (GeoShapeFieldMapper.GeoShapeFieldType) alias.aliasTarget(); + } +} diff --git a/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeIpFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeIpFieldTypeTests.java new file mode 100644 index 0000000000000..ed14d38482663 --- /dev/null +++ b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeIpFieldTypeTests.java @@ -0,0 +1,46 @@ +/* + * 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; + +public class AliasFieldTypeIpFieldTypeTests extends IpFieldTypeTests { + + private static final String ALIASFIELD = "alias2"; + private final String PATH = IPFIELD; + + @Override + protected AliasFieldMapper.AliasFieldType createDefaultFieldType() { + return new AliasFieldMapper.AliasFieldType(null, + null, + PATH, + new IpFieldMapper.IpFieldType()); + } + + @Override + MappedFieldType createNamedDefaultFieldType() { + final AliasFieldMapper.AliasFieldType fieldType = this.createDefaultFieldType(); + fieldType.setName(ALIASFIELD); + fieldType.aliasTarget().setName(this.fieldTypeName()); + return fieldType; + } + + @Override + String fieldInMessage() { + return AliasFieldMapper.AliasFieldType.nameInMessage(ALIASFIELD, PATH); + } +} diff --git a/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeKeywordFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeKeywordFieldTypeTests.java new file mode 100644 index 0000000000000..3b279d263329e --- /dev/null +++ b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeKeywordFieldTypeTests.java @@ -0,0 +1,52 @@ +/* + * 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; + +public class AliasFieldTypeKeywordFieldTypeTests extends KeywordFieldTypeTests { + + private static final String ALIASFIELD = "alias2"; + private final String PATHTO = KEYWORDFIELD; + + @Override + protected AliasFieldMapper.AliasFieldType createDefaultFieldType() { + return new AliasFieldMapper.AliasFieldType(null, + null, + PATHTO, + new KeywordFieldMapper.KeywordFieldType()); + } + + @Override + MappedFieldType createNamedDefaultFieldType() { + final AliasFieldMapper.AliasFieldType fieldType = this.createDefaultFieldType(); + fieldType.setName(ALIASFIELD); + fieldType.aliasTarget().setName(this.fieldTypeName()); + return fieldType; + } + + @Override + String fieldInMessage() { + return AliasFieldMapper.AliasFieldType.nameInMessage(ALIASFIELD, PATHTO); + } + + @Override + protected KeywordFieldMapper.KeywordFieldType toKeywordFieldType(final MappedFieldType fieldType) { + final AliasFieldMapper.AliasFieldType alias = (AliasFieldMapper.AliasFieldType)fieldType; + return (KeywordFieldMapper.KeywordFieldType) alias.aliasTarget(); + } +} diff --git a/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeNumberFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeNumberFieldTypeTests.java new file mode 100644 index 0000000000000..7101513a36bc3 --- /dev/null +++ b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeNumberFieldTypeTests.java @@ -0,0 +1,46 @@ +/* + * 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; + +public class AliasFieldTypeNumberFieldTypeTests extends NumberFieldTypeTests { + + private static final String ALIASFIELD = "alias2"; + private final String PATHTO = NUMBERFIELD; + + @Override + protected AliasFieldMapper.AliasFieldType createDefaultFieldType() { + return new AliasFieldMapper.AliasFieldType(null, + null, + PATHTO, + new NumberFieldMapper.NumberFieldType(this.type)); + } + + @Override + MappedFieldType createNamedDefaultFieldType() { + final AliasFieldMapper.AliasFieldType fieldType = this.createDefaultFieldType(); + fieldType.setName(ALIASFIELD); + fieldType.aliasTarget().setName(this.fieldTypeName()); + return fieldType; + } + + @Override + String fieldInMessage() { + return AliasFieldMapper.AliasFieldType.nameInMessage(ALIASFIELD, PATHTO); + } +} diff --git a/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeRangeFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeRangeFieldTypeTests.java new file mode 100644 index 0000000000000..79bdc0a1ef61c --- /dev/null +++ b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeRangeFieldTypeTests.java @@ -0,0 +1,52 @@ +/* + * 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; + +public class AliasFieldTypeRangeFieldTypeTests extends RangeFieldTypeTests { + + private static final String ALIASFIELD = "alias2"; + private final String PATHTO = RANGEFIELD; + + @Override + protected AliasFieldMapper.AliasFieldType createDefaultFieldType() { + return new AliasFieldMapper.AliasFieldType(null, + null, + PATHTO, + new RangeFieldMapper.RangeFieldType(this.type, this.version)); + } + + @Override + MappedFieldType createNamedDefaultFieldType() { + final AliasFieldMapper.AliasFieldType fieldType = this.createDefaultFieldType(); + fieldType.setName(ALIASFIELD); + fieldType.aliasTarget().setName(fieldTypeName()); + return fieldType; + } + + @Override + String fieldInMessage() { + return ALIASFIELD; + } + + @Override + protected RangeFieldMapper.RangeFieldType toRangeFieldType(final MappedFieldType fieldType) { + final AliasFieldMapper.AliasFieldType alias = (AliasFieldMapper.AliasFieldType)fieldType; + return (RangeFieldMapper.RangeFieldType) alias.aliasTarget(); + } +} diff --git a/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeTextFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeTextFieldTypeTests.java new file mode 100644 index 0000000000000..e5301d12a2787 --- /dev/null +++ b/server/src/test/java/org/elasticsearch/index/mapper/AliasFieldTypeTextFieldTypeTests.java @@ -0,0 +1,52 @@ +/* + * 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; + +public class AliasFieldTypeTextFieldTypeTests extends TextFieldTypeTests { + + private static final String ALIASFIELD = "alias2"; + private final String PATHTO = TEXTFIELD; + + @Override + protected AliasFieldMapper.AliasFieldType createDefaultFieldType() { + return new AliasFieldMapper.AliasFieldType(null, + null, + PATHTO, + new TextFieldMapper.TextFieldType()); + } + + @Override + MappedFieldType createNamedDefaultFieldType() { + final AliasFieldMapper.AliasFieldType fieldType = this.createDefaultFieldType(); + fieldType.setName(ALIASFIELD); + fieldType.aliasTarget().setName(this.fieldTypeName()); + return fieldType; + } + + @Override + String fieldInMessage() { + return AliasFieldMapper.AliasFieldType.nameInMessage(ALIASFIELD, PATHTO); + } + + @Override + protected TextFieldMapper.TextFieldType toTextFieldType(final MappedFieldType fieldType) { + final AliasFieldMapper.AliasFieldType alias = (AliasFieldMapper.AliasFieldType)fieldType; + return (TextFieldMapper.TextFieldType) alias.aliasTarget(); + } +} diff --git a/server/src/test/java/org/elasticsearch/index/mapper/BooleanFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/BooleanFieldTypeTests.java index d119a27f22eb5..6e4e458617c09 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/BooleanFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/BooleanFieldTypeTests.java @@ -24,6 +24,9 @@ import org.junit.Before; public class BooleanFieldTypeTests extends FieldTypeTestCase { + + protected static final String BOOLEANFIELD = "booleanField1"; + @Override protected MappedFieldType createDefaultFieldType() { return new BooleanFieldMapper.BooleanFieldType(); @@ -41,7 +44,7 @@ public void testValueFormat() { } public void testValueForSearch() { - MappedFieldType ft = createDefaultFieldType(); + MappedFieldType ft = createNamedDefaultFieldType(); assertEquals(true, ft.valueForDisplay("T")); assertEquals(false, ft.valueForDisplay("F")); expectThrows(IllegalArgumentException.class, () -> ft.valueForDisplay(0)); @@ -50,15 +53,27 @@ public void testValueForSearch() { } public void testTermQuery() { - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = createNamedDefaultFieldType(); ft.setIndexOptions(IndexOptions.DOCS); - assertEquals(new TermQuery(new Term("field", "T")), ft.termQuery("true", null)); - assertEquals(new TermQuery(new Term("field", "F")), ft.termQuery("false", null)); + assertEquals(new TermQuery(new Term(this.fieldInQuery(), "T")), ft.termQuery("true", null)); + assertEquals(new TermQuery(new Term(this.fieldInQuery(), "F")), ft.termQuery("false", null)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.termQuery("true", null)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field " + this.fieldInMessage() + " since it is not indexed.", e.getMessage()); + } + + @Override + protected String fieldTypeName() { + return BOOLEANFIELD; + } + + String fieldInQuery() { + return BOOLEANFIELD; + } + + String fieldInMessage() { + return MappedFieldType.nameInMessage(BOOLEANFIELD); } } diff --git a/server/src/test/java/org/elasticsearch/index/mapper/DateFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/DateFieldTypeTests.java index ad9d0c414946b..668f963d6d1fc 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/DateFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/DateFieldTypeTests.java @@ -48,6 +48,10 @@ import java.util.Locale; public class DateFieldTypeTests extends FieldTypeTestCase { + + protected static final String DATEFIELD1 = "dateField1"; + protected static final String DATEFIELD2 = "dateField2"; + @Override protected MappedFieldType createDefaultFieldType() { return new DateFieldMapper.DateFieldType(); @@ -61,13 +65,13 @@ public void setupProperties() { addModifier(new Modifier("format", false) { @Override public void modify(MappedFieldType ft) { - ((DateFieldType) ft).setDateTimeFormatter(Joda.forPattern("basic_week_date", Locale.ROOT)); + toDateFieldType(ft).setDateTimeFormatter(Joda.forPattern("basic_week_date", Locale.ROOT)); } }); addModifier(new Modifier("locale", false) { @Override public void modify(MappedFieldType ft) { - ((DateFieldType) ft).setDateTimeFormatter(Joda.forPattern("date_optional_time", Locale.CANADA)); + toDateFieldType(ft).setDateTimeFormatter(Joda.forPattern("date_optional_time", Locale.CANADA)); } }); nowInMillis = randomNonNegativeLong(); @@ -77,12 +81,12 @@ public void testIsFieldWithinQueryEmptyReader() throws IOException { QueryRewriteContext context = new QueryRewriteContext(xContentRegistry(), writableRegistry(), null, () -> nowInMillis); IndexReader reader = new MultiReader(); DateFieldType ft = new DateFieldType(); - ft.setName("my_date"); + ft.setName(DATEFIELD1); assertEquals(Relation.DISJOINT, ft.isFieldWithinQuery(reader, "2015-10-12", "2016-04-03", randomBoolean(), randomBoolean(), null, null, context)); } - private void doTestIsFieldWithinQuery(DateFieldType ft, DirectoryReader reader, + private void doTestIsFieldWithinQuery(MappedFieldType ft, DirectoryReader reader, DateTimeZone zone, DateMathParser alternateFormat) throws IOException { QueryRewriteContext context = new QueryRewriteContext(xContentRegistry(), writableRegistry(), null, () -> nowInMillis); assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(reader, "2015-10-09", "2016-01-02", @@ -113,14 +117,13 @@ public void testIsFieldWithinQuery() throws IOException { long instant1 = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parser().parseDateTime("2015-10-12").getMillis(); long instant2 = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parser().parseDateTime("2016-04-03").getMillis(); Document doc = new Document(); - LongPoint field = new LongPoint("my_date", instant1); + LongPoint field = new LongPoint(fieldTypeName(), instant1); doc.add(field); w.addDocument(doc); field.setLongValue(instant2); w.addDocument(doc); DirectoryReader reader = DirectoryReader.open(w); - DateFieldType ft = new DateFieldType(); - ft.setName("my_date"); + MappedFieldType ft = this.createNamedDefaultFieldType(); DateMathParser alternateFormat = new DateMathParser(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER); doTestIsFieldWithinQuery(ft, reader, null, null); doTestIsFieldWithinQuery(ft, reader, null, alternateFormat); @@ -129,7 +132,7 @@ public void testIsFieldWithinQuery() throws IOException { // Fields with no value indexed. DateFieldType ft2 = new DateFieldType(); - ft2.setName("my_date2"); + ft2.setName(DATEFIELD2); QueryRewriteContext context = new QueryRewriteContext(xContentRegistry(), writableRegistry(), null, () -> nowInMillis); assertEquals(Relation.DISJOINT, ft2.isFieldWithinQuery(reader, "2015-10-09", "2016-01-02", false, false, null, null, context)); @@ -154,7 +157,7 @@ public void testValueFormat() { } public void testValueForSearch() { - MappedFieldType ft = createDefaultFieldType(); + MappedFieldType ft = createNamedDefaultFieldType(); String date = "2015-10-12T12:09:55.000Z"; long instant = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parser().parseDateTime(date).getMillis(); assertEquals(date, ft.valueForDisplay(instant)); @@ -167,20 +170,19 @@ public void testTermQuery() { new IndexSettings(IndexMetaData.builder("foo").settings(indexSettings).build(), indexSettings), null, null, null, null, null, xContentRegistry(), writableRegistry(), null, null, () -> nowInMillis, null); - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = createNamedDefaultFieldType(); String date = "2015-10-12T14:10:55"; long instant = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parser().parseDateTime(date).getMillis(); ft.setIndexOptions(IndexOptions.DOCS); Query expected = new IndexOrDocValuesQuery( - LongPoint.newRangeQuery("field", instant, instant + 999), - SortedNumericDocValuesField.newSlowRangeQuery("field", instant, instant + 999)); + LongPoint.newRangeQuery(this.fieldInQuery(), instant, instant + 999), + SortedNumericDocValuesField.newSlowRangeQuery(this.fieldInQuery(), instant, instant + 999)); assertEquals(expected, ft.termQuery(date, context)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.termQuery(date, context)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field " + this.fieldInMessage() + " since it is not indexed.", e.getMessage()); } public void testRangeQuery() throws IOException { @@ -189,22 +191,38 @@ public void testRangeQuery() throws IOException { QueryShardContext context = new QueryShardContext(0, new IndexSettings(IndexMetaData.builder("foo").settings(indexSettings).build(), indexSettings), null, null, null, null, null, xContentRegistry(), writableRegistry(), null, null, () -> nowInMillis, null); - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = createNamedDefaultFieldType(); String date1 = "2015-10-12T14:10:55"; String date2 = "2016-04-28T11:33:52"; long instant1 = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parser().parseDateTime(date1).getMillis(); long instant2 = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.parser().parseDateTime(date2).getMillis() + 999; ft.setIndexOptions(IndexOptions.DOCS); Query expected = new IndexOrDocValuesQuery( - LongPoint.newRangeQuery("field", instant1, instant2), - SortedNumericDocValuesField.newSlowRangeQuery("field", instant1, instant2)); + LongPoint.newRangeQuery(this.fieldInQuery(), instant1, instant2), + SortedNumericDocValuesField.newSlowRangeQuery(this.fieldInQuery(), instant1, instant2)); assertEquals(expected, ft.rangeQuery(date1, date2, true, true, null, null, null, context).rewrite(new MultiReader())); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.rangeQuery(date1, date2, true, true, null, null, null, context)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field "+this.fieldInMessage() +" since it is not indexed.", e.getMessage()); + } + + @Override + protected String fieldTypeName() { + return DATEFIELD1; + } + + String fieldInQuery() { + return DATEFIELD1; + } + + String fieldInMessage() { + return MappedFieldType.nameInMessage(DATEFIELD1); + } + + DateFieldMapper.DateFieldType toDateFieldType(final MappedFieldType fieldType) { + return (DateFieldMapper.DateFieldType) fieldType; } } diff --git a/server/src/test/java/org/elasticsearch/index/mapper/DocumentParserTests.java b/server/src/test/java/org/elasticsearch/index/mapper/DocumentParserTests.java index 11f69c738e949..9baa31a5ca270 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/DocumentParserTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/DocumentParserTests.java @@ -38,10 +38,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.util.*; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.test.StreamsUtils.copyToBytesFromClasspath; @@ -1319,74 +1316,145 @@ public void testDynamicDateDetectionEnabledWithNoSpecialCharacters() throws IOEx assertThat(dateMapper, instanceOf(DateFieldMapper.class)); } - public void testDynamicFieldsStartingAndEndingWithDot() throws Exception { - BytesReference bytes = BytesReference.bytes(XContentFactory.jsonBuilder().startObject().startArray("top.") - .startObject().startArray("foo.") - .startObject() - .field("thing", "bah") - .endObject().endArray() - .endObject().endArray() - .endObject()); + public void testFieldName() throws Exception { + checkFieldNameAndValidation("root", "branch", "leaf"); + } - client().prepareIndex("idx", "type").setSource(bytes, XContentType.JSON).get(); + public void testFieldNameBlank1() throws Exception { + checkFieldNameAndValidationFails("", "branch", "leaf", DocumentParser.pathContainsEmptyString("")); + } - bytes = BytesReference.bytes(XContentFactory.jsonBuilder().startObject().startArray("top.") - .startObject().startArray("foo.") - .startObject() - .startObject("bar.") - .startObject("aoeu") - .field("a", 1).field("b", 2) - .endObject() - .endObject() - .endObject() - .endArray().endObject().endArray() - .endObject()); + public void testFieldNameBlank2() throws Exception { + checkFieldNameAndValidationFails("root", "", "leaf", DocumentParser.pathContainsEmptyString("root.")); + } - try { - client().prepareIndex("idx", "type").setSource(bytes, XContentType.JSON).get(); - fail("should have failed to dynamically introduce a double-dot field"); - } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), - containsString("object field starting or ending with a [.] makes object resolution ambiguous: [top..foo..bar]")); - } + public void testFieldNameBlank3() throws Exception { + checkFieldNameAndValidationFails("root", "branch", "", DocumentParser.pathContainsEmptyString("root.branch.")); } - public void testDynamicFieldsEmptyName() throws Exception { - BytesReference bytes = BytesReference.bytes(XContentFactory.jsonBuilder() - .startObject().startArray("top.") - .startObject() - .startObject("aoeu") - .field("a", 1).field(" ", 2) - .endObject() - .endObject().endArray() - .endObject()); + public void testFieldNameWhitespaceOnly1() throws Exception { + checkFieldNameAndValidationFails(" ", "branch", "leaf", DocumentParser.pathContainsOnlyWhitespace(" ")); + } - IllegalArgumentException emptyFieldNameException = expectThrows(IllegalArgumentException.class, - () -> client().prepareIndex("idx", "type").setSource(bytes, XContentType.JSON).get()); + public void testFieldNameWhitespaceOnly2() throws Exception { + checkFieldNameAndValidationFails("root", " ", "leaf", DocumentParser.pathContainsOnlyWhitespace("root. ")); + } - assertThat(emptyFieldNameException.getMessage(), containsString( - "object field cannot contain only whitespace: ['top.aoeu. ']")); + public void testFieldNameWhitespaceOnly3() throws Exception { + checkFieldNameAndValidationFails("root", "branch", " ", DocumentParser.pathContainsOnlyWhitespace("root.branch. ")); } - public void testBlankFieldNames() throws Exception { - final BytesReference bytes = BytesReference.bytes(XContentFactory.jsonBuilder() - .startObject() - .field("", "foo") - .endObject()); + public void testFieldNameWhitespaceWithin1() throws Exception { + checkFieldNameAndValidation("ro ot", "branch", "leaf"); + } - MapperParsingException err = expectThrows(MapperParsingException.class, () -> - client().prepareIndex("idx", "type").setSource(bytes, XContentType.JSON).get()); - assertThat(ExceptionsHelper.detailedMessage(err), containsString("field name cannot be an empty string")); + public void testFieldNameWhitespaceWithin2() throws Exception { + checkFieldNameAndValidation("root", "bra nch", "leaf"); + } - final BytesReference bytes2 = BytesReference.bytes(XContentFactory.jsonBuilder() - .startObject() - .startObject("foo") - .field("", "bar") - .endObject() - .endObject()); + public void testFieldNameWhitespaceWithin3() throws Exception { + checkFieldNameAndValidation("root", "branch", "le af"); + } + + public void testFieldNameComponentOnlyDot1() throws Exception { + checkFieldNameAndValidationFails(".", "branch", "leaf", DocumentParser.pathStartOrEndingWithDotAmbiguous(".")); + } + + public void testFieldNameComponentOnlyDot2() throws Exception { + checkFieldNameAndValidationFails("root", ".", "leaf", DocumentParser.pathStartOrEndingWithDotAmbiguous("root..")); + } + + public void testFieldNameComponentOnlyDot3() throws Exception { + checkFieldNameAndValidationFails("root", "branch", ".", DocumentParser.pathStartOrEndingWithDotAmbiguous("root.branch..")); + } + + public void testFieldNameComponentStartDot1() throws Exception { + checkFieldNameAndValidationFails(".root", "branch", "leaf", DocumentParser.pathStartOrEndingWithDotAmbiguous(".root")); + } - err = expectThrows(MapperParsingException.class, () -> - client().prepareIndex("idx", "type").setSource(bytes2, XContentType.JSON).get()); - assertThat(ExceptionsHelper.detailedMessage(err), containsString("field name cannot be an empty string")); + public void testFieldNameComponentStartDot2() throws Exception { + checkFieldNameAndValidationFails("root", ".branch", "leaf", DocumentParser.pathStartOrEndingWithDotAmbiguous("root..branch")); + } + + public void testFieldNameComponentStartDot3() throws Exception { + checkFieldNameAndValidationFails("root", "branch", ".leaf", DocumentParser.pathStartOrEndingWithDotAmbiguous("root.branch..leaf")); + } + + public void testFieldNameComponentEndDot1() throws Exception { + checkFieldNameAndValidationFails("root.", "branch", "leaf", DocumentParser.pathStartOrEndingWithDotAmbiguous("root.")); + } + + public void testFieldNameComponentEndDot2() throws Exception { + checkFieldNameAndValidationFails("root", "branch.", "leaf", DocumentParser.pathStartOrEndingWithDotAmbiguous("root.branch.")); + } + + public void testFieldNameComponentEndDot3() throws Exception { + checkFieldNameAndValidationFails("root", "branch", "leaf.", DocumentParser.pathStartOrEndingWithDotAmbiguous("root.branch.leaf.")); + } + + private void checkFieldNameAndValidation(final String root, + final String branch, + final String leaf) throws Exception { + checkFieldNameAndValidation0(bytesReferenceArray(root, branch, leaf)); + checkFieldNameAndValidation0(bytesReferenceNull(root, branch, leaf)); + checkFieldNameAndValidation0(bytesReferenceObject(root, branch, leaf)); + } + + private void checkFieldNameAndValidationFails(final String root, + final String branch, + final String leaf, + final String exceptionMessageContains) throws Exception { + checkFieldNameAndValidationFails0(bytesReferenceArray(root, branch, leaf), exceptionMessageContains); + checkFieldNameAndValidationFails0(bytesReferenceNull(root, branch, leaf), exceptionMessageContains); + checkFieldNameAndValidationFails0(bytesReferenceObject(root, branch, leaf), exceptionMessageContains); + } + + private void checkFieldNameAndValidationFails0(final BytesReference bytes, + final String exceptionMessageContains) { + MapperParsingException thrown = expectThrows(MapperParsingException.class, () -> checkFieldNameAndValidation0(bytes)); + assertThat(bytes.utf8ToString(), ExceptionsHelper.detailedMessage(thrown), containsString(exceptionMessageContains)); + } + + private BytesReference bytesReferenceArray(final String root, + final String branch, + final String leaf) throws Exception { + return BytesReference.bytes(XContentFactory.jsonBuilder() + .startObject().startArray(root) + .startObject().startArray(branch) + .startObject() + .field(leaf, "*value*") + .endObject().endArray() + .endObject().endArray() + .endObject()) ; + } + + private BytesReference bytesReferenceNull(final String root, + final String branch, + final String leaf) throws Exception { + return BytesReference.bytes(XContentFactory.jsonBuilder() + .startObject() + .startObject(root) + .startObject(branch) + .field(leaf, (String)null) + .endObject() + .endObject() + .endObject()); + } + + private BytesReference bytesReferenceObject(final String root, + final String branch, + final String leaf) throws Exception { + return BytesReference.bytes(XContentFactory.jsonBuilder() + .startObject() + .startObject(root) + .startObject(branch) + .field(leaf, "*value*") + .endObject() + .endObject() + .endObject()); + } + + private void checkFieldNameAndValidation0(final BytesReference bytes) throws Exception { + client().prepareIndex("idx", "type").setSource(bytes, XContentType.JSON).get(); } } diff --git a/server/src/test/java/org/elasticsearch/index/mapper/FieldMapperTestCase.java b/server/src/test/java/org/elasticsearch/index/mapper/FieldMapperTestCase.java new file mode 100644 index 0000000000000..105cd6f188041 --- /dev/null +++ b/server/src/test/java/org/elasticsearch/index/mapper/FieldMapperTestCase.java @@ -0,0 +1,193 @@ +/* + * 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; + +import com.google.common.collect.Lists; +import org.apache.lucene.index.IndexableField; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.compress.CompressedXContent; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.index.IndexService; +import org.elasticsearch.index.query.QueryShardContext; +import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.test.ESSingleNodeTestCase; +import org.elasticsearch.test.InternalSettingsPlugin; +import org.junit.Assert; +import org.junit.Before; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +import static org.hamcrest.Matchers.containsString; + +public abstract class FieldMapperTestCase extends ESSingleNodeTestCase { + + public static String fieldPath(final String field, String...fields){ + final List fieldPath = Lists.newArrayList(); + fieldPath.add(field); + fieldPath.addAll(Arrays.asList(fields)); + return fieldPath.stream() + .collect(Collectors.joining(".")); + } + + protected static final String INDEX = "test"; + protected static final String TYPE = "type"; + + protected IndexService indexService; + protected DocumentMapperParser parser; + + @Before + public void setup() { + indexService = createIndex(INDEX); + parser = indexService.mapperService().documentMapperParser(); + } + + @Override + protected Collection> getPlugins() { + return pluginList(InternalSettingsPlugin.class); + } + + protected final DocumentMapper documentMapper() throws IOException { + return this.documentMapper(this.mapping()); + } + + protected final DocumentMapper documentMapper(final String mapping) throws IOException { + return parser.parse(TYPE, new CompressedXContent(mapping)); + } + + protected final void documentMapperFails(final String mapping, + final Class thrown, + final String messageContains) throws IOException { + Throwable e = expectThrows(thrown, + () -> documentMapper(mapping) + ); + log(e); + assertThat(e.getMessage(), containsString(messageContains)); + } + + protected final DocumentMapper documentMapperFromIndexService() throws IOException { + return this.indexService.mapperService().documentMapper(TYPE); + } + + protected abstract String mapping() throws IOException; + + protected final List mappingParse(final BytesReference source) throws IOException { + return this.mappingParse(this.documentMapper(), source); + } + + private List mappingParse(final DocumentMapper mapper, final BytesReference source) { + return mapper.parse(SourceToParse.source(INDEX, TYPE, "1", + source, + XContentType.JSON)) + .docs(); + } + + protected final void mappingParseFails(final BytesReference source, + final Class thrown, + final String messageContains) throws IOException { + this.mappingParseFails(this.documentMapper(), source, thrown, messageContains); + } + + protected final void mappingParseFails(final DocumentMapper mapper, + final BytesReference source, + final Class thrown, + final String messageContains) throws IOException { + Throwable e = expectThrows(thrown, + () -> mappingParse(mapper, source) + ); + log(e); + assertThat(e.getMessage() + " " + e.getCause().getMessage(), containsString(messageContains)); + } + + protected void mergeMapping(final String mapping) throws IOException { + this.mergeMapping(new CompressedXContent(mapping)); + } + + protected void mergeMapping(final CompressedXContent mapping) { + this.indexService.mapperService().merge(TYPE, + mapping, + MapperService.MergeReason.MAPPING_UPDATE); + } + + protected void mergeMappingFails(final String mapping, + final Class thrown, + final String messageContains) throws IOException { + Throwable e = expectThrows(thrown, + () -> mergeMapping(mapping) + ); + log(e); + assertThat(e.getMessage() + " " + e.getCause().getMessage(), containsString(messageContains)); + } + + protected QueryShardContext queryShardContext() { + return indexService.newQueryShardContext( + randomInt(20), null, () -> { + throw new UnsupportedOperationException(); + }, null); + } + + protected void checkDocumentCount(final int expected, final List documents) { + assertEquals(expected + " documents: " + documents, expected, documents.size()); + } + + protected MappedFieldType fieldType(final DocumentMapper mapper, final String field) { + return mapper.mappers().getMapper(field).fieldType(); + } + + protected void checkField(final ParseContext.Document document, final String field, final String value) { + final IndexableField[] fields = document.getFields(field); + + assertEquals("index fields=" + Arrays.toString(fields), 1, fields.length); + assertEquals("IndexableField[0] name=" + field, field, fields[0].name()); + assertEquals("IndexableField[0] stringValue=" + field, value, fields[0].stringValue()); + } + + protected void checkFieldMapping(final DocumentMapper documentMapper, + final String field, + final String mapping) throws IOException { + final FieldMapper mapper = documentMapper.mappers().getMapper(field); + XContentBuilder builder = XContentFactory.jsonBuilder().startObject(); + mapper.toXContent(builder, ToXContent.EMPTY_PARAMS); + builder.endObject(); + + this.checkJsonEqual("field [" + field + "] mapping", + mapping, + Strings.toString(builder)); + } + + protected final void checkJsonEqual(final String message, final String expected, final String actual) { + Assert.assertEquals(message, pretty(expected), pretty(actual)); + } + + private String pretty(final String json) { + return json.replace("'", "\\\""); // TODO really pretty + } + + private void log(Throwable t) + { + //t.printStackTrace(); + } +} diff --git a/server/src/test/java/org/elasticsearch/index/mapper/GeoPointFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/GeoPointFieldTypeTests.java index ad7195267c113..53ca7821e31b0 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/GeoPointFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/GeoPointFieldTypeTests.java @@ -21,8 +21,24 @@ import org.elasticsearch.index.mapper.GeoPointFieldMapper.GeoPointFieldType; public class GeoPointFieldTypeTests extends FieldTypeTestCase { + + protected static final String GEOPOINTFIELD = "textField1"; + @Override protected MappedFieldType createDefaultFieldType() { return new GeoPointFieldType(); } + + @Override + protected String fieldTypeName() { + return GEOPOINTFIELD; + } + + String fieldInQuery() { + return GEOPOINTFIELD; + } + + String fieldInMessage() { + return MappedFieldType.nameInMessage(GEOPOINTFIELD); + } } diff --git a/server/src/test/java/org/elasticsearch/index/mapper/GeoShapeFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/GeoShapeFieldTypeTests.java index a1c225f8a0657..f8a1db3922c47 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/GeoShapeFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/GeoShapeFieldTypeTests.java @@ -26,47 +26,45 @@ import java.io.IOException; public class GeoShapeFieldTypeTests extends FieldTypeTestCase { - @Override - protected MappedFieldType createDefaultFieldType() { - return new GeoShapeFieldMapper.GeoShapeFieldType(); - } + + protected static final String GEOSHAPEFIELD = "geoShapeField1"; @Before public void setupProperties() { addModifier(new Modifier("tree", false) { @Override public void modify(MappedFieldType ft) { - ((GeoShapeFieldMapper.GeoShapeFieldType)ft).setTree("quadtree"); + toGeoShapeFieldType(ft).setTree("quadtree"); } }); addModifier(new Modifier("strategy", false) { @Override public void modify(MappedFieldType ft) { - ((GeoShapeFieldMapper.GeoShapeFieldType)ft).setStrategyName("term"); + toGeoShapeFieldType(ft).setStrategyName("term"); } }); addModifier(new Modifier("tree_levels", false) { @Override public void modify(MappedFieldType ft) { - ((GeoShapeFieldMapper.GeoShapeFieldType)ft).setTreeLevels(10); + toGeoShapeFieldType(ft).setTreeLevels(10); } }); addModifier(new Modifier("precision", false) { @Override public void modify(MappedFieldType ft) { - ((GeoShapeFieldMapper.GeoShapeFieldType)ft).setPrecisionInMeters(20); + toGeoShapeFieldType(ft).setPrecisionInMeters(20); } }); addModifier(new Modifier("distance_error_pct", true) { @Override public void modify(MappedFieldType ft) { - ((GeoShapeFieldMapper.GeoShapeFieldType)ft).setDefaultDistanceErrorPct(0.5); + toGeoShapeFieldType(ft).setDefaultDistanceErrorPct(0.5); } }); addModifier(new Modifier("orientation", true) { @Override public void modify(MappedFieldType ft) { - ((GeoShapeFieldMapper.GeoShapeFieldType)ft).setOrientation(ShapeBuilder.Orientation.LEFT); + toGeoShapeFieldType(ft).setOrientation(ShapeBuilder.Orientation.LEFT); } }); } @@ -76,11 +74,33 @@ public void modify(MappedFieldType ft) { * gets set as a side effect when using SpatialStrategy.TERM */ public void testSetStrategyName() throws IOException { - GeoShapeFieldType fieldType = new GeoShapeFieldMapper.GeoShapeFieldType(); + GeoShapeFieldType fieldType = toGeoShapeFieldType(this.createNamedDefaultFieldType()); assertFalse(fieldType.pointsOnly()); fieldType.setStrategyName(SpatialStrategy.RECURSIVE.getStrategyName()); assertFalse(fieldType.pointsOnly()); fieldType.setStrategyName(SpatialStrategy.TERM.getStrategyName()); assertTrue(fieldType.pointsOnly()); } + + @Override + protected MappedFieldType createDefaultFieldType() { + return new GeoShapeFieldMapper.GeoShapeFieldType(); + } + + @Override + protected String fieldTypeName() { + return GEOSHAPEFIELD; + } + + String fieldInQuery() { + return GEOSHAPEFIELD; + } + + String fieldInMessage() { + return GEOSHAPEFIELD; + } + + GeoShapeFieldMapper.GeoShapeFieldType toGeoShapeFieldType(final MappedFieldType fieldType) { + return (GeoShapeFieldMapper.GeoShapeFieldType) fieldType; + } } diff --git a/server/src/test/java/org/elasticsearch/index/mapper/IpFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/IpFieldTypeTests.java index 1c0024b769ff4..ac095948602b6 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/IpFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/IpFieldTypeTests.java @@ -31,10 +31,8 @@ import org.elasticsearch.common.network.InetAddresses; public class IpFieldTypeTests extends FieldTypeTestCase { - @Override - protected MappedFieldType createDefaultFieldType() { - return new IpFieldMapper.IpFieldType(); - } + + protected static final String IPFIELD = "ipField1"; public void testValueFormat() throws Exception { MappedFieldType ft = createDefaultFieldType(); @@ -59,36 +57,34 @@ public void testValueForSearch() throws Exception { } public void testTermQuery() { - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(); String ip = "2001:db8::2:1"; - assertEquals(InetAddressPoint.newExactQuery("field", InetAddresses.forString(ip)), ft.termQuery(ip, null)); + assertEquals(InetAddressPoint.newExactQuery(this.fieldInQuery(), InetAddresses.forString(ip)), ft.termQuery(ip, null)); ip = "192.168.1.7"; - assertEquals(InetAddressPoint.newExactQuery("field", InetAddresses.forString(ip)), ft.termQuery(ip, null)); + assertEquals(InetAddressPoint.newExactQuery(this.fieldInQuery(), InetAddresses.forString(ip)), ft.termQuery(ip, null)); ip = "2001:db8::2:1"; String prefix = ip + "/64"; - assertEquals(InetAddressPoint.newPrefixQuery("field", InetAddresses.forString(ip), 64), ft.termQuery(prefix, null)); + assertEquals(InetAddressPoint.newPrefixQuery(this.fieldInQuery(), InetAddresses.forString(ip), 64), ft.termQuery(prefix, null)); ip = "192.168.1.7"; prefix = ip + "/16"; - assertEquals(InetAddressPoint.newPrefixQuery("field", InetAddresses.forString(ip), 16), ft.termQuery(prefix, null)); + assertEquals(InetAddressPoint.newPrefixQuery(this.fieldInQuery(), InetAddresses.forString(ip), 16), ft.termQuery(prefix, null)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.termQuery("::1", null)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field " + this.fieldInMessage() +" since it is not indexed.", e.getMessage()); } public void testTermsQuery() { - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(); - assertEquals(InetAddressPoint.newSetQuery("field", InetAddresses.forString("::2"), InetAddresses.forString("::5")), + assertEquals(InetAddressPoint.newSetQuery(this.fieldInQuery(), InetAddresses.forString("::2"), InetAddresses.forString("::5")), ft.termsQuery(Arrays.asList(InetAddresses.forString("::2"), InetAddresses.forString("::5")), null)); - assertEquals(InetAddressPoint.newSetQuery("field", InetAddresses.forString("::2"), InetAddresses.forString("::5")), + assertEquals(InetAddressPoint.newSetQuery(this.fieldInQuery(), InetAddresses.forString("::2"), InetAddresses.forString("::5")), ft.termsQuery(Arrays.asList("::2", "::5"), null)); // if the list includes a prefix query we fallback to a bool query @@ -99,53 +95,52 @@ public void testTermsQuery() { } public void testRangeQuery() { - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(); assertEquals( - InetAddressPoint.newRangeQuery("field", + InetAddressPoint.newRangeQuery(this.fieldInQuery(), InetAddresses.forString("::"), InetAddressPoint.MAX_VALUE), ft.rangeQuery(null, null, randomBoolean(), randomBoolean(), null, null, null, null)); assertEquals( - InetAddressPoint.newRangeQuery("field", + InetAddressPoint.newRangeQuery(this.fieldInQuery(), InetAddresses.forString("::"), InetAddresses.forString("192.168.2.0")), ft.rangeQuery(null, "192.168.2.0", randomBoolean(), true, null, null, null, null)); assertEquals( - InetAddressPoint.newRangeQuery("field", + InetAddressPoint.newRangeQuery(this.fieldInQuery(), InetAddresses.forString("::"), InetAddresses.forString("192.168.1.255")), ft.rangeQuery(null, "192.168.2.0", randomBoolean(), false, null, null, null, null)); assertEquals( - InetAddressPoint.newRangeQuery("field", + InetAddressPoint.newRangeQuery(this.fieldInQuery(), InetAddresses.forString("2001:db8::"), InetAddressPoint.MAX_VALUE), ft.rangeQuery("2001:db8::", null, true, randomBoolean(), null, null, null, null)); assertEquals( - InetAddressPoint.newRangeQuery("field", + InetAddressPoint.newRangeQuery(this.fieldInQuery(), InetAddresses.forString("2001:db8::1"), InetAddressPoint.MAX_VALUE), ft.rangeQuery("2001:db8::", null, false, randomBoolean(), null, null, null, null)); assertEquals( - InetAddressPoint.newRangeQuery("field", + InetAddressPoint.newRangeQuery(this.fieldInQuery(), InetAddresses.forString("2001:db8::"), InetAddresses.forString("2001:db8::ffff")), ft.rangeQuery("2001:db8::", "2001:db8::ffff", true, true, null, null, null, null)); assertEquals( - InetAddressPoint.newRangeQuery("field", + InetAddressPoint.newRangeQuery(this.fieldInQuery(), InetAddresses.forString("2001:db8::1"), InetAddresses.forString("2001:db8::fffe")), ft.rangeQuery("2001:db8::", "2001:db8::ffff", false, false, null, null, null, null)); assertEquals( - InetAddressPoint.newRangeQuery("field", + InetAddressPoint.newRangeQuery(this.fieldInQuery(), InetAddresses.forString("2001:db8::2"), InetAddresses.forString("2001:db8::")), // same lo/hi values but inclusive=false so this won't match anything @@ -161,14 +156,14 @@ public void testRangeQuery() { false, true, null, null, null, null)); assertEquals( - InetAddressPoint.newRangeQuery("field", + InetAddressPoint.newRangeQuery(this.fieldInQuery(), InetAddresses.forString("::"), InetAddresses.forString("::fffe:ffff:ffff")), // same lo/hi values but inclusive=false so this won't match anything ft.rangeQuery("::", "0.0.0.0", true, false, null, null, null, null)); assertEquals( - InetAddressPoint.newRangeQuery("field", + InetAddressPoint.newRangeQuery(this.fieldInQuery(), InetAddresses.forString("::1:0:0:0"), InetAddressPoint.MAX_VALUE), // same lo/hi values but inclusive=false so this won't match anything @@ -176,7 +171,7 @@ public void testRangeQuery() { assertEquals( // lower bound is ipv4, upper bound is ipv6 - InetAddressPoint.newRangeQuery("field", + InetAddressPoint.newRangeQuery(this.fieldInQuery(), InetAddresses.forString("192.168.1.7"), InetAddresses.forString("2001:db8::")), ft.rangeQuery("::ffff:c0a8:107", "2001:db8::", true, true, null, null, null, null)); @@ -184,6 +179,24 @@ public void testRangeQuery() { ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.rangeQuery("::1", "2001::", true, true, null, null, null, null)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field " + this.fieldInMessage() + " since it is not indexed.", e.getMessage()); + } + + @Override + protected MappedFieldType createDefaultFieldType() { + return new IpFieldMapper.IpFieldType(); + } + + @Override + protected String fieldTypeName() { + return IPFIELD; + } + + String fieldInQuery() { + return IPFIELD; + } + + String fieldInMessage() { + return MappedFieldType.nameInMessage(IPFIELD); } } diff --git a/server/src/test/java/org/elasticsearch/index/mapper/KeywordFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/KeywordFieldTypeTests.java index 809ceb5831004..833137a318e8e 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/KeywordFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/KeywordFieldTypeTests.java @@ -48,12 +48,14 @@ public class KeywordFieldTypeTests extends FieldTypeTestCase { + protected final String KEYWORDFIELD = "keywordField1"; + @Before public void setupProperties() { addModifier(new Modifier("normalizer", false) { @Override public void modify(MappedFieldType ft) { - ((KeywordFieldType) ft).setNormalizer(Lucene.KEYWORD_ANALYZER); + toKeywordFieldType(ft).setNormalizer(Lucene.KEYWORD_ANALYZER); } }); } @@ -64,7 +66,7 @@ protected MappedFieldType createDefaultFieldType() { } public void testIsFieldWithinQuery() throws IOException { - KeywordFieldType ft = new KeywordFieldType(); + MappedFieldType ft = this.createNamedDefaultFieldType(); // current impl ignores args and shourd always return INTERSECTS assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(null, RandomStrings.randomAsciiOfLengthBetween(random(), 0, 5), @@ -73,20 +75,18 @@ public void testIsFieldWithinQuery() throws IOException { } public void testTermQuery() { - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(); ft.setIndexOptions(IndexOptions.DOCS); - assertEquals(new TermQuery(new Term("field", "foo")), ft.termQuery("foo", null)); + assertEquals(new TermQuery(new Term(this.fieldInQuery(), "foo")), ft.termQuery("foo", null)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.termQuery("bar", null)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field " + this.fieldInMessage() + " since it is not indexed.", e.getMessage()); } public void testTermQueryWithNormalizer() { - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(); ft.setIndexOptions(IndexOptions.DOCS); Analyzer normalizer = new Analyzer() { @Override @@ -101,62 +101,75 @@ protected TokenStream normalize(String fieldName, TokenStream in) { } }; ft.setSearchAnalyzer(new NamedAnalyzer("my_normalizer", AnalyzerScope.INDEX, normalizer)); - assertEquals(new TermQuery(new Term("field", "foo bar")), ft.termQuery("fOo BaR", null)); + assertEquals(new TermQuery(new Term(this.fieldInQuery(), "foo bar")), ft.termQuery("fOo BaR", null)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.termQuery("bar", null)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field " + this.fieldInMessage() + " since it is not indexed.", e.getMessage()); } public void testTermsQuery() { - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(); ft.setIndexOptions(IndexOptions.DOCS); List terms = new ArrayList<>(); terms.add(new BytesRef("foo")); terms.add(new BytesRef("bar")); - assertEquals(new TermInSetQuery("field", terms), + assertEquals(new TermInSetQuery(this.fieldInQuery(), terms), ft.termsQuery(Arrays.asList("foo", "bar"), null)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.termsQuery(Arrays.asList("foo", "bar"), null)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field " + this.fieldInMessage() + " since it is not indexed.", e.getMessage()); } public void testRegexpQuery() { - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(); ft.setIndexOptions(IndexOptions.DOCS); - assertEquals(new RegexpQuery(new Term("field","foo.*")), + assertEquals(new RegexpQuery(new Term(this.fieldInQuery(),"foo.*")), ft.regexpQuery("foo.*", 0, 10, null, null)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.regexpQuery("foo.*", 0, 10, null, null)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field " + this.fieldInMessage() + " since it is not indexed.", e.getMessage()); } public void testFuzzyQuery() { - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(); ft.setIndexOptions(IndexOptions.DOCS); - assertEquals(new FuzzyQuery(new Term("field","foo"), 2, 1, 50, true), + assertEquals(new FuzzyQuery(new Term(this.fieldInQuery(),"foo"), 2, 1, 50, true), ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field " + this.fieldInMessage() + " since it is not indexed.", e.getMessage()); } public void testNormalizeQueries() { - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(); ft.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); - assertEquals(new TermQuery(new Term("field", new BytesRef("FOO"))), ft.termQuery("FOO", null)); + assertEquals(new TermQuery(new Term(this.fieldInQuery(), new BytesRef("FOO"))), ft.termQuery("FOO", null)); ft.setSearchAnalyzer(Lucene.STANDARD_ANALYZER); - assertEquals(new TermQuery(new Term("field", new BytesRef("foo"))), ft.termQuery("FOO", null)); + assertEquals(new TermQuery(new Term(this.fieldInQuery(), new BytesRef("foo"))), ft.termQuery("FOO", null)); + } + + @Override + protected String fieldTypeName() { + return KEYWORDFIELD; + } + + String fieldInQuery() { + return KEYWORDFIELD; + } + + String fieldInMessage() { + return MappedFieldType.nameInMessage(KEYWORDFIELD); + } + + KeywordFieldMapper.KeywordFieldType toKeywordFieldType(final MappedFieldType fieldType) { + return (KeywordFieldMapper.KeywordFieldType) fieldType; } } diff --git a/server/src/test/java/org/elasticsearch/index/mapper/MapperTesting.java b/server/src/test/java/org/elasticsearch/index/mapper/MapperTesting.java new file mode 100644 index 0000000000000..1ac932cc175b5 --- /dev/null +++ b/server/src/test/java/org/elasticsearch/index/mapper/MapperTesting.java @@ -0,0 +1,33 @@ +/* + * 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; + +public final class MapperTesting { + + public static MappedFieldType aliasFieldType(final RootObjectMapper rootObjectMapper, + final String name, + final String pathTo, + final MappedFieldType aliased) { + return new AliasFieldMapper.AliasFieldType(rootObjectMapper, name, pathTo, aliased); + } + + private MapperTesting() { + throw new UnsupportedOperationException(); + } +} diff --git a/server/src/test/java/org/elasticsearch/index/mapper/NumberFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/NumberFieldTypeTests.java index 3ffe48fe70af6..7a53c76ab5f23 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/NumberFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/NumberFieldTypeTests.java @@ -42,6 +42,7 @@ import org.elasticsearch.index.mapper.MappedFieldType.Relation; import org.elasticsearch.index.mapper.NumberFieldMapper.NumberType; import org.hamcrest.Matchers; +import org.junit.Assert; import org.junit.Before; import java.io.IOException; @@ -56,6 +57,8 @@ public class NumberFieldTypeTests extends FieldTypeTestCase { + protected static final String NUMBERFIELD = "numberField1"; + NumberType type; @Before @@ -65,6 +68,7 @@ public void pickType() { @Override protected MappedFieldType createDefaultFieldType() { + Assert.assertNotNull("type must not be null", type); return new NumberFieldMapper.NumberFieldType(type); } @@ -76,66 +80,58 @@ public void testIsFieldWithinQuery() throws IOException { } public void testIntegerTermsQueryWithDecimalPart() { - MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberType.INTEGER); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(NumberType.INTEGER); ft.setIndexOptions(IndexOptions.DOCS); - assertEquals(IntPoint.newSetQuery("field", 1), ft.termsQuery(Arrays.asList(1, 2.1), null)); - assertEquals(IntPoint.newSetQuery("field", 1), ft.termsQuery(Arrays.asList(1.0, 2.1), null)); + assertEquals(IntPoint.newSetQuery(this.fieldInQuery(), 1), ft.termsQuery(Arrays.asList(1, 2.1), null)); + assertEquals(IntPoint.newSetQuery(this.fieldInQuery(), 1), ft.termsQuery(Arrays.asList(1.0, 2.1), null)); assertTrue(ft.termsQuery(Arrays.asList(1.1, 2.1), null) instanceof MatchNoDocsQuery); } public void testLongTermsQueryWithDecimalPart() { - MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberType.LONG); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(NumberType.LONG); ft.setIndexOptions(IndexOptions.DOCS); - assertEquals(LongPoint.newSetQuery("field", 1), ft.termsQuery(Arrays.asList(1, 2.1), null)); - assertEquals(LongPoint.newSetQuery("field", 1), ft.termsQuery(Arrays.asList(1.0, 2.1), null)); + assertEquals(LongPoint.newSetQuery(this.fieldInQuery(), 1), ft.termsQuery(Arrays.asList(1, 2.1), null)); + assertEquals(LongPoint.newSetQuery(this.fieldInQuery(), 1), ft.termsQuery(Arrays.asList(1.0, 2.1), null)); assertTrue(ft.termsQuery(Arrays.asList(1.1, 2.1), null) instanceof MatchNoDocsQuery); } public void testByteTermQueryWithDecimalPart() { - MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberType.BYTE); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(NumberType.BYTE); ft.setIndexOptions(IndexOptions.DOCS); assertTrue(ft.termQuery(42.1, null) instanceof MatchNoDocsQuery); } public void testShortTermQueryWithDecimalPart() { - MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberType.SHORT); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(NumberType.SHORT); ft.setIndexOptions(IndexOptions.DOCS); assertTrue(ft.termQuery(42.1, null) instanceof MatchNoDocsQuery); } public void testIntegerTermQueryWithDecimalPart() { - MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberType.INTEGER); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(NumberType.INTEGER); ft.setIndexOptions(IndexOptions.DOCS); assertTrue(ft.termQuery(42.1, null) instanceof MatchNoDocsQuery); } public void testLongTermQueryWithDecimalPart() { - MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.LONG); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(NumberFieldMapper.NumberType.LONG); ft.setIndexOptions(IndexOptions.DOCS); assertTrue(ft.termQuery(42.1, null) instanceof MatchNoDocsQuery); } public void testTermQuery() { - MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.LONG); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(NumberFieldMapper.NumberType.LONG); ft.setIndexOptions(IndexOptions.DOCS); - assertEquals(LongPoint.newExactQuery("field", 42), ft.termQuery("42", null)); + assertEquals(LongPoint.newExactQuery(this.fieldInQuery(), 42), ft.termQuery("42", null)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.termQuery("42", null)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field " + this.fieldInMessage() + " since it is not indexed.", e.getMessage()); } public void testRangeQueryWithNegativeBounds() { - MappedFieldType ftInt = new NumberFieldMapper.NumberFieldType(NumberType.INTEGER); - ftInt.setName("field"); + MappedFieldType ftInt = this.createNamedDefaultFieldType(NumberType.INTEGER); ftInt.setIndexOptions(IndexOptions.DOCS); assertEquals(ftInt.rangeQuery(-3, -3, true, true, null, null, null, null), ftInt.rangeQuery(-3.5, -2.5, true, true, null, null, null, null)); @@ -163,8 +159,7 @@ public void testRangeQueryWithNegativeBounds() { assertEquals(ftInt.rangeQuery(-2, -1, true, true, null, null, null, null), ftInt.rangeQuery(-2.5, -0.5, false, false, null, null, null, null)); - MappedFieldType ftLong = new NumberFieldMapper.NumberFieldType(NumberType.LONG); - ftLong.setName("field"); + MappedFieldType ftLong = this.createNamedDefaultFieldType(NumberType.LONG); ftLong.setIndexOptions(IndexOptions.DOCS); assertEquals(ftLong.rangeQuery(-3, -3, true, true, null, null, null, null), ftLong.rangeQuery(-3.5, -2.5, true, true, null, null, null, null)); @@ -194,8 +189,7 @@ public void testRangeQueryWithNegativeBounds() { } public void testByteRangeQueryWithDecimalParts() { - MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberType.BYTE); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(NumberType.BYTE); ft.setIndexOptions(IndexOptions.DOCS); assertEquals(ft.rangeQuery(2, 10, true, true, null, null, null, null), ft.rangeQuery(1.1, 10, true, true, null, null, null, null)); @@ -208,8 +202,7 @@ public void testByteRangeQueryWithDecimalParts() { } public void testShortRangeQueryWithDecimalParts() { - MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberType.SHORT); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(NumberType.SHORT); ft.setIndexOptions(IndexOptions.DOCS); assertEquals(ft.rangeQuery(2, 10, true, true, null, null, null, null), ft.rangeQuery(1.1, 10, true, true, null, null, null, null)); @@ -222,8 +215,7 @@ public void testShortRangeQueryWithDecimalParts() { } public void testIntegerRangeQueryWithDecimalParts() { - MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberType.INTEGER); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(NumberType.INTEGER); ft.setIndexOptions(IndexOptions.DOCS); assertEquals(ft.rangeQuery(2, 10, true, true, null, null, null, null), ft.rangeQuery(1.1, 10, true, true, null, null, null, null)); @@ -236,8 +228,7 @@ public void testIntegerRangeQueryWithDecimalParts() { } public void testLongRangeQueryWithDecimalParts() { - MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberType.LONG); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(NumberType.LONG); ft.setIndexOptions(IndexOptions.DOCS); assertEquals(ft.rangeQuery(2, 10, true, true, null, null, null, null), ft.rangeQuery(1.1, 10, true, true, null, null, null, null)); @@ -250,18 +241,17 @@ public void testLongRangeQueryWithDecimalParts() { } public void testRangeQuery() { - MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.LONG); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(NumberFieldMapper.NumberType.LONG); ft.setIndexOptions(IndexOptions.DOCS); Query expected = new IndexOrDocValuesQuery( - LongPoint.newRangeQuery("field", 1, 3), - SortedNumericDocValuesField.newSlowRangeQuery("field", 1, 3)); + LongPoint.newRangeQuery(this.fieldInQuery(), 1, 3), + SortedNumericDocValuesField.newSlowRangeQuery(this.fieldInQuery(), 1, 3)); assertEquals(expected, ft.rangeQuery("1", "3", true, true, null, null, null, null)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.rangeQuery("1", "3", true, true, null, null, null, null)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field " + this.fieldInMessage() + " since it is not indexed.", e.getMessage()); } public void testConversions() { @@ -358,18 +348,19 @@ public void testHalfFloatRange() throws IOException { public void testNegativeZero() { assertEquals( - NumberType.DOUBLE.rangeQuery("field", null, -0d, true, true, false), - NumberType.DOUBLE.rangeQuery("field", null, +0d, true, false, false)); + NumberType.DOUBLE.rangeQuery(this.fieldInQuery(), null, -0d, true, true, false), + NumberType.DOUBLE.rangeQuery(this.fieldInQuery(), null, +0d, true, false, false)); assertEquals( - NumberType.FLOAT.rangeQuery("field", null, -0f, true, true, false), - NumberType.FLOAT.rangeQuery("field", null, +0f, true, false, false)); + NumberType.FLOAT.rangeQuery(this.fieldInQuery(), null, -0f, true, true, false), + NumberType.FLOAT.rangeQuery(this.fieldInQuery(), null, +0f, true, false, false)); assertEquals( - NumberType.HALF_FLOAT.rangeQuery("field", null, -0f, true, true, false), - NumberType.HALF_FLOAT.rangeQuery("field", null, +0f, true, false, false)); + NumberType.HALF_FLOAT.rangeQuery(this.fieldInQuery(), null, -0f, true, true, false), + NumberType.HALF_FLOAT.rangeQuery(this.fieldInQuery(), null, +0f, true, false, false)); - assertFalse(NumberType.DOUBLE.termQuery("field", -0d).equals(NumberType.DOUBLE.termQuery("field", +0d))); - assertFalse(NumberType.FLOAT.termQuery("field", -0f).equals(NumberType.FLOAT.termQuery("field", +0f))); - assertFalse(NumberType.HALF_FLOAT.termQuery("field", -0f).equals(NumberType.HALF_FLOAT.termQuery("field", +0f))); + assertFalse(NumberType.DOUBLE.termQuery(this.fieldInQuery(), -0d).equals(NumberType.DOUBLE.termQuery(this.fieldInQuery(), +0d))); + assertFalse(NumberType.FLOAT.termQuery(this.fieldInQuery(), -0f).equals(NumberType.FLOAT.termQuery(this.fieldInQuery(), +0f))); + assertFalse(NumberType.HALF_FLOAT.termQuery(this.fieldInQuery(), -0f) + .equals(NumberType.HALF_FLOAT.termQuery(this.fieldInQuery(), +0f))); } // Make sure we construct the IndexOrDocValuesQuery objects with queries that match @@ -501,22 +492,40 @@ static OutOfRangeSpec of(NumberType t, V v, String m) { public void testDisplayValue() { for (NumberFieldMapper.NumberType type : NumberFieldMapper.NumberType.values()) { - NumberFieldMapper.NumberFieldType fieldType = new NumberFieldMapper.NumberFieldType(type); + MappedFieldType fieldType = this.createNamedDefaultFieldType(type); assertNull(fieldType.valueForDisplay(null)); } assertEquals(Byte.valueOf((byte) 3), - new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.BYTE).valueForDisplay(3)); + this.createNamedDefaultFieldType(NumberFieldMapper.NumberType.BYTE).valueForDisplay(3)); assertEquals(Short.valueOf((short) 3), - new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.SHORT).valueForDisplay(3)); + this.createNamedDefaultFieldType(NumberFieldMapper.NumberType.SHORT).valueForDisplay(3)); assertEquals(Integer.valueOf(3), - new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.INTEGER).valueForDisplay(3)); + this.createNamedDefaultFieldType(NumberFieldMapper.NumberType.INTEGER).valueForDisplay(3)); assertEquals(Long.valueOf(3), - new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.LONG).valueForDisplay(3L)); + this.createNamedDefaultFieldType(NumberFieldMapper.NumberType.LONG).valueForDisplay(3L)); assertEquals(Double.valueOf(1.2), - new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.HALF_FLOAT).valueForDisplay(1.2)); + this.createNamedDefaultFieldType(NumberFieldMapper.NumberType.HALF_FLOAT).valueForDisplay(1.2)); assertEquals(Double.valueOf(1.2), - new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.FLOAT).valueForDisplay(1.2)); + this.createNamedDefaultFieldType(NumberFieldMapper.NumberType.FLOAT).valueForDisplay(1.2)); assertEquals(Double.valueOf(1.2), - new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.DOUBLE).valueForDisplay(1.2)); + this.createNamedDefaultFieldType(NumberFieldMapper.NumberType.DOUBLE).valueForDisplay(1.2)); + } + + MappedFieldType createNamedDefaultFieldType(final NumberFieldMapper.NumberType type) { + this.type = type; + return this.createNamedDefaultFieldType(); + } + + @Override + protected String fieldTypeName() { + return NUMBERFIELD; + } + + String fieldInQuery() { + return NUMBERFIELD; + } + + String fieldInMessage() { + return MappedFieldType.nameInMessage(NUMBERFIELD); } } diff --git a/server/src/test/java/org/elasticsearch/index/mapper/RangeFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/RangeFieldTypeTests.java index 0c20153675af6..81e126bfdf934 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/RangeFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/RangeFieldTypeTests.java @@ -42,6 +42,7 @@ import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.test.IndexSettingsModule; import org.joda.time.DateTime; +import org.junit.Assert; import org.junit.Before; import java.net.InetAddress; @@ -49,7 +50,8 @@ public class RangeFieldTypeTests extends FieldTypeTestCase { RangeType type; - protected static String FIELDNAME = "field"; + Version version = Version.CURRENT; + protected static final String RANGEFIELD = "rangeField1"; protected static int DISTANCE = 10; private static long nowInMillis; @@ -61,31 +63,25 @@ public void setupProperties() { addModifier(new Modifier("format", true) { @Override public void modify(MappedFieldType ft) { - ((RangeFieldMapper.RangeFieldType) ft).setDateTimeFormatter(Joda.forPattern("basic_week_date", Locale.ROOT)); + toRangeFieldType(ft).setDateTimeFormatter(Joda.forPattern("basic_week_date", Locale.ROOT)); } }); addModifier(new Modifier("locale", true) { @Override public void modify(MappedFieldType ft) { - ((RangeFieldMapper.RangeFieldType) ft).setDateTimeFormatter(Joda.forPattern("date_optional_time", Locale.CANADA)); + toRangeFieldType(ft).setDateTimeFormatter(Joda.forPattern("date_optional_time", Locale.CANADA)); } }); } } - @Override - protected RangeFieldMapper.RangeFieldType createDefaultFieldType() { - return new RangeFieldMapper.RangeFieldType(type, Version.CURRENT); - } - public void testRangeQuery() throws Exception { Settings indexSettings = Settings.builder() .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT).build(); IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(randomAlphaOfLengthBetween(1, 10), indexSettings); QueryShardContext context = new QueryShardContext(0, idxSettings, null, null, null, null, null, xContentRegistry(), writableRegistry(), null, null, () -> nowInMillis, null); - RangeFieldMapper.RangeFieldType ft = new RangeFieldMapper.RangeFieldType(type, Version.CURRENT); - ft.setName(FIELDNAME); + MappedFieldType ft = this.createNamedDefaultFieldType(type, Version.CURRENT); ft.setIndexOptions(IndexOptions.DOCS); ShapeRelation relation = RandomPicks.randomFrom(random(), ShapeRelation.values()); @@ -121,16 +117,16 @@ private Query getDateRangeQuery(ShapeRelation relation, DateTime from, DateTime Query indexQuery; BinaryDocValuesRangeQuery.QueryType queryType; if (relation == ShapeRelation.WITHIN) { - indexQuery = LongRange.newWithinQuery(FIELDNAME, lower, upper); + indexQuery = LongRange.newWithinQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN; } else if (relation == ShapeRelation.CONTAINS) { - indexQuery = LongRange.newContainsQuery(FIELDNAME, lower, upper); + indexQuery = LongRange.newContainsQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS; } else { - indexQuery = LongRange.newIntersectsQuery(FIELDNAME, lower, upper); + indexQuery = LongRange.newIntersectsQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS; } - Query dvQuery = RangeType.DATE.dvRangeQuery(FIELDNAME, queryType, from.getMillis(), + Query dvQuery = RangeType.DATE.dvRangeQuery(RANGEFIELD, queryType, from.getMillis(), to.getMillis(), includeLower, includeUpper); return new IndexOrDocValuesQuery(indexQuery, dvQuery); } @@ -141,16 +137,16 @@ private Query getIntRangeQuery(ShapeRelation relation, int from, int to, boolean Query indexQuery; BinaryDocValuesRangeQuery.QueryType queryType; if (relation == ShapeRelation.WITHIN) { - indexQuery = IntRange.newWithinQuery(FIELDNAME, lower, upper); + indexQuery = IntRange.newWithinQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN; } else if (relation == ShapeRelation.CONTAINS) { - indexQuery = IntRange.newContainsQuery(FIELDNAME, lower, upper); + indexQuery = IntRange.newContainsQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS; } else { - indexQuery = IntRange.newIntersectsQuery(FIELDNAME, lower, upper); + indexQuery = IntRange.newIntersectsQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS; } - Query dvQuery = RangeType.INTEGER.dvRangeQuery(FIELDNAME, queryType, from, to, + Query dvQuery = RangeType.INTEGER.dvRangeQuery(RANGEFIELD, queryType, from, to, includeLower, includeUpper); return new IndexOrDocValuesQuery(indexQuery, dvQuery); } @@ -161,16 +157,16 @@ private Query getLongRangeQuery(ShapeRelation relation, long from, long to, bool Query indexQuery; BinaryDocValuesRangeQuery.QueryType queryType; if (relation == ShapeRelation.WITHIN) { - indexQuery = LongRange.newWithinQuery(FIELDNAME, lower, upper); + indexQuery = LongRange.newWithinQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN; } else if (relation == ShapeRelation.CONTAINS) { - indexQuery = LongRange.newContainsQuery(FIELDNAME, lower, upper); + indexQuery = LongRange.newContainsQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS; } else { - indexQuery = LongRange.newIntersectsQuery(FIELDNAME, lower, upper); + indexQuery = LongRange.newIntersectsQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS; } - Query dvQuery = RangeType.LONG.dvRangeQuery(FIELDNAME, queryType, from, to, + Query dvQuery = RangeType.LONG.dvRangeQuery(RANGEFIELD, queryType, from, to, includeLower, includeUpper); return new IndexOrDocValuesQuery(indexQuery, dvQuery); } @@ -181,16 +177,16 @@ private Query getFloatRangeQuery(ShapeRelation relation, float from, float to, b Query indexQuery; BinaryDocValuesRangeQuery.QueryType queryType; if (relation == ShapeRelation.WITHIN) { - indexQuery = FloatRange.newWithinQuery(FIELDNAME, lower, upper); + indexQuery = FloatRange.newWithinQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN; } else if (relation == ShapeRelation.CONTAINS) { - indexQuery = FloatRange.newContainsQuery(FIELDNAME, lower, upper); + indexQuery = FloatRange.newContainsQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS; } else { - indexQuery = FloatRange.newIntersectsQuery(FIELDNAME, lower, upper); + indexQuery = FloatRange.newIntersectsQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS; } - Query dvQuery = RangeType.FLOAT.dvRangeQuery(FIELDNAME, queryType, from, to, + Query dvQuery = RangeType.FLOAT.dvRangeQuery(RANGEFIELD, queryType, from, to, includeLower, includeUpper); return new IndexOrDocValuesQuery(indexQuery, dvQuery); } @@ -202,16 +198,16 @@ private Query getDoubleRangeQuery(ShapeRelation relation, double from, double to Query indexQuery; BinaryDocValuesRangeQuery.QueryType queryType; if (relation == ShapeRelation.WITHIN) { - indexQuery = DoubleRange.newWithinQuery(FIELDNAME, lower, upper); + indexQuery = DoubleRange.newWithinQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN; } else if (relation == ShapeRelation.CONTAINS) { - indexQuery = DoubleRange.newContainsQuery(FIELDNAME, lower, upper); + indexQuery = DoubleRange.newContainsQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS; } else { - indexQuery = DoubleRange.newIntersectsQuery(FIELDNAME, lower, upper); + indexQuery = DoubleRange.newIntersectsQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS; } - Query dvQuery = RangeType.DOUBLE.dvRangeQuery(FIELDNAME, queryType, from, to, + Query dvQuery = RangeType.DOUBLE.dvRangeQuery(RANGEFIELD, queryType, from, to, includeLower, includeUpper); return new IndexOrDocValuesQuery(indexQuery, dvQuery); } @@ -223,16 +219,16 @@ private Query getInetAddressRangeQuery(ShapeRelation relation, InetAddress from, Query indexQuery; BinaryDocValuesRangeQuery.QueryType queryType; if (relation == ShapeRelation.WITHIN) { - indexQuery = InetAddressRange.newWithinQuery(FIELDNAME, lower, upper); + indexQuery = InetAddressRange.newWithinQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN; } else if (relation == ShapeRelation.CONTAINS) { - indexQuery = InetAddressRange.newContainsQuery(FIELDNAME, lower, upper); + indexQuery = InetAddressRange.newContainsQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS; } else { - indexQuery = InetAddressRange.newIntersectsQuery(FIELDNAME, lower, upper); + indexQuery = InetAddressRange.newIntersectsQuery(RANGEFIELD, lower, upper); queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS; } - Query dvQuery = RangeType.IP.dvRangeQuery(FIELDNAME, queryType, from, to, + Query dvQuery = RangeType.IP.dvRangeQuery(RANGEFIELD, queryType, from, to, includeLower, includeUpper); return new IndexOrDocValuesQuery(indexQuery, dvQuery); } @@ -284,8 +280,7 @@ public void testTermQuery() throws Exception, IllegalArgumentException { IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(randomAlphaOfLengthBetween(1, 10), indexSettings); QueryShardContext context = new QueryShardContext(0, idxSettings, null, null, null, null, null, xContentRegistry(), writableRegistry(), null, null, () -> nowInMillis, null); - RangeFieldMapper.RangeFieldType ft = new RangeFieldMapper.RangeFieldType(type, Version.CURRENT); - ft.setName(FIELDNAME); + MappedFieldType ft = this.createNamedDefaultFieldType(type, Version.CURRENT); ft.setIndexOptions(IndexOptions.DOCS); Object value = nextFrom(); @@ -295,4 +290,35 @@ public void testTermQuery() throws Exception, IllegalArgumentException { assertEquals(getExpectedRangeQuery(relation, value, value, includeLower, includeUpper), ft.termQuery(value, context)); } + + MappedFieldType createNamedDefaultFieldType(final RangeType type, final Version indexVersionCreated) { + this.type = type; + this.version = indexVersionCreated; + return this.createNamedDefaultFieldType(); + } + + @Override + protected MappedFieldType createDefaultFieldType() { + Assert.assertNotNull("type", this.type); + Assert.assertNotNull("version", this.version); + + return new RangeFieldMapper.RangeFieldType(this.type, this.version); + } + + @Override + protected String fieldTypeName() { + return RANGEFIELD; + } + + String fieldInQuery() { + return RANGEFIELD; + } + + String fieldInMessage() { + return RANGEFIELD; + } + + RangeFieldMapper.RangeFieldType toRangeFieldType(final MappedFieldType fieldType) { + return (RangeFieldMapper.RangeFieldType) fieldType; + } } diff --git a/server/src/test/java/org/elasticsearch/index/mapper/TextFieldTypeTests.java b/server/src/test/java/org/elasticsearch/index/mapper/TextFieldTypeTests.java index 895bb97e16665..f8e6e6412efaf 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/TextFieldTypeTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/TextFieldTypeTests.java @@ -22,7 +22,6 @@ import java.util.Arrays; import java.util.List; -import org.apache.lucene.document.LongPoint; import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.Term; import org.apache.lucene.search.TermInSetQuery; @@ -31,99 +30,113 @@ import org.apache.lucene.search.TermQuery; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.unit.Fuzziness; -import org.elasticsearch.index.mapper.MappedFieldType; -import org.elasticsearch.index.mapper.TextFieldMapper; import org.junit.Before; public class TextFieldTypeTests extends FieldTypeTestCase { - @Override - protected MappedFieldType createDefaultFieldType() { - return new TextFieldMapper.TextFieldType(); - } + + protected static final String TEXTFIELD = "textField1"; @Before public void setupProperties() { addModifier(new Modifier("fielddata", true) { @Override public void modify(MappedFieldType ft) { - TextFieldMapper.TextFieldType tft = (TextFieldMapper.TextFieldType)ft; + TextFieldMapper.TextFieldType tft = toTextFieldType(ft); tft.setFielddata(tft.fielddata() == false); } }); addModifier(new Modifier("fielddata_frequency_filter.min", true) { @Override public void modify(MappedFieldType ft) { - TextFieldMapper.TextFieldType tft = (TextFieldMapper.TextFieldType)ft; + TextFieldMapper.TextFieldType tft = toTextFieldType(ft); tft.setFielddataMinFrequency(3); } }); addModifier(new Modifier("fielddata_frequency_filter.max", true) { @Override public void modify(MappedFieldType ft) { - TextFieldMapper.TextFieldType tft = (TextFieldMapper.TextFieldType)ft; + TextFieldMapper.TextFieldType tft = toTextFieldType(ft); tft.setFielddataMaxFrequency(0.2); } }); addModifier(new Modifier("fielddata_frequency_filter.min_segment_size", true) { @Override public void modify(MappedFieldType ft) { - TextFieldMapper.TextFieldType tft = (TextFieldMapper.TextFieldType)ft; + TextFieldMapper.TextFieldType tft = toTextFieldType(ft); tft.setFielddataMinSegmentSize(1000); } }); } public void testTermQuery() { - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(); ft.setIndexOptions(IndexOptions.DOCS); - assertEquals(new TermQuery(new Term("field", "foo")), ft.termQuery("foo", null)); + assertEquals(new TermQuery(new Term(this.fieldInQuery(), "foo")), ft.termQuery("foo", null)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.termQuery("bar", null)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field "+ this.fieldInMessage() + " since it is not indexed.", e.getMessage()); } public void testTermsQuery() { - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(); ft.setIndexOptions(IndexOptions.DOCS); List terms = new ArrayList<>(); terms.add(new BytesRef("foo")); terms.add(new BytesRef("bar")); - assertEquals(new TermInSetQuery("field", terms), + assertEquals(new TermInSetQuery(this.fieldInQuery(), terms), ft.termsQuery(Arrays.asList("foo", "bar"), null)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.termsQuery(Arrays.asList("foo", "bar"), null)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field " + this.fieldInMessage() + " since it is not indexed.", e.getMessage()); } public void testRegexpQuery() { - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(); ft.setIndexOptions(IndexOptions.DOCS); - assertEquals(new RegexpQuery(new Term("field","foo.*")), + assertEquals(new RegexpQuery(new Term(this.fieldInQuery(),"foo.*")), ft.regexpQuery("foo.*", 0, 10, null, null)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.regexpQuery("foo.*", 0, 10, null, null)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field " + this.fieldInMessage() + " since it is not indexed.", e.getMessage()); } public void testFuzzyQuery() { - MappedFieldType ft = createDefaultFieldType(); - ft.setName("field"); + MappedFieldType ft = this.createNamedDefaultFieldType(); ft.setIndexOptions(IndexOptions.DOCS); - assertEquals(new FuzzyQuery(new Term("field","foo"), 2, 1, 50, true), + assertEquals(new FuzzyQuery(new Term(this.fieldInQuery(),"foo"), 2, 1, 50, true), ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true)); ft.setIndexOptions(IndexOptions.NONE); IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true)); - assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); + assertEquals("Cannot search on field " + this.fieldInMessage() + " since it is not indexed.", e.getMessage()); + } + + @Override + protected MappedFieldType createDefaultFieldType() { + return new TextFieldMapper.TextFieldType(); + } + + @Override + protected String fieldTypeName() { + return TEXTFIELD; + } + + String fieldInQuery() { + return TEXTFIELD; + } + + String fieldInMessage() { + return MappedFieldType.nameInMessage(TEXTFIELD); + } + + TextFieldMapper.TextFieldType toTextFieldType(final MappedFieldType fieldType) { + return (TextFieldMapper.TextFieldType) fieldType; } } diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/support/ValuesSourceConfigTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/support/ValuesSourceConfigTests.java index ae65bc9f32c9a..f4f599a13d307 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/support/ValuesSourceConfigTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/support/ValuesSourceConfigTests.java @@ -27,6 +27,9 @@ import org.elasticsearch.index.IndexService; import org.elasticsearch.index.engine.Engine.Searcher; import org.elasticsearch.index.fielddata.SortedBinaryDocValues; +import org.elasticsearch.index.mapper.AliasFieldMapper; +import org.elasticsearch.index.mapper.BooleanFieldMapper; +import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.test.ESSingleNodeTestCase; @@ -218,6 +221,9 @@ public void testEmptyBoolean() throws Exception { ValuesSourceConfig config = ValuesSourceConfig.resolve( context, null, "bool", null, null, null, null); + + checkFieldContext(config, "bool", "bool", BooleanFieldMapper.BooleanFieldType.class); + ValuesSource.Numeric valuesSource = config.toValuesSource(context); LeafReaderContext ctx = searcher.reader().leaves().get(0); SortedNumericDocValues values = valuesSource.longValues(ctx); @@ -225,6 +231,9 @@ public void testEmptyBoolean() throws Exception { config = ValuesSourceConfig.resolve( context, null, "bool", null, true, null, null); + + checkFieldContext(config, "bool", "bool", BooleanFieldMapper.BooleanFieldType.class); + valuesSource = config.toValuesSource(context); values = valuesSource.longValues(ctx); assertTrue(values.advanceExact(0)); @@ -258,4 +267,49 @@ public void testUnmappedBoolean() throws Exception { assertEquals(1, values.nextValue()); } } + + public void testAliasToBoolean() throws Exception { + IndexService indexService = createIndex("index", Settings.EMPTY, "type", + "bool", "type=boolean", + "alias", "type=alias,path=bool"); + client().prepareIndex("index", "type", "1") + .setSource() + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .get(); + + try (Searcher searcher = indexService.getShard(0).acquireSearcher("test")) { + QueryShardContext context = indexService.newQueryShardContext(0, searcher.reader(), () -> 42L, null); + + ValuesSourceConfig config = ValuesSourceConfig.resolve( + context, null, "alias", null, null, null, null); + + checkFieldContext(config, "alias", "bool", AliasFieldMapper.AliasFieldType.class); + + ValuesSource.Numeric valuesSource = config.toValuesSource(context); + LeafReaderContext ctx = searcher.reader().leaves().get(0); + SortedNumericDocValues values = valuesSource.longValues(ctx); + assertFalse(values.advanceExact(0)); + + config = ValuesSourceConfig.resolve( + context, null, "alias", null, true, null, null); + + checkFieldContext(config, "alias", "bool", AliasFieldMapper.AliasFieldType.class); + + valuesSource = config.toValuesSource(context); + values = valuesSource.longValues(ctx); + assertTrue(values.advanceExact(0)); + assertEquals(1, values.docValueCount()); + assertEquals(1, values.nextValue()); + } + } + + private void checkFieldContext(final ValuesSourceConfig config, + final String field, + final String nameForIndex, + final Class type){ + final FieldContext fieldContext = config.fieldContext(); + assertEquals("FieldContext.field", field, fieldContext.field()); + assertEquals("FieldContext.fieldType.nameForIndex", nameForIndex, fieldContext.fieldType().nameForIndex()); + assertEquals("FieldContext.fieldType", type, fieldContext.fieldType().getClass()); + } } diff --git a/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlighterSearchIT.java b/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlighterSearchIT.java index 7f61655a09273..4a914c337fe14 100644 --- a/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlighterSearchIT.java +++ b/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlighterSearchIT.java @@ -32,6 +32,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.index.mapper.AliasFieldMapper; import org.elasticsearch.index.query.AbstractQueryBuilder; import org.elasticsearch.index.query.IdsQueryBuilder; import org.elasticsearch.index.query.MatchQueryBuilder; @@ -100,9 +101,19 @@ import static org.hamcrest.Matchers.startsWith; public class HighlighterSearchIT extends ESIntegTestCase { + public static final int TITLE_AND_ATTACHMENT_DOCUMENT_COUNT = 5; // TODO as we move analyzers out of the core we need to move some of these into HighlighterWithAnalyzersTests private static final String[] ALL_TYPES = new String[] {"plain", "fvh", "unified"}; + private static final String TITLE = "title"; + private static final String TITLE_ALIAS = "titleAlias"; + private static final String ATTACHMENTS = "attachments"; + private static final String BODY = "body"; + private static final String ATTACHMENTS_BODY = ATTACHMENTS + "." + BODY; + private static final String ATTACHMENTS_BODY_ALIAS = "bodyAttachmentsAlias"; + private static final String INDEX = (HighlighterSearchIT.class.getSimpleName() + "Index").toLowerCase(Locale.getDefault()); + private static final String INDEX_DOCUMENT_TYPE = HighlighterSearchIT.class.getSimpleName() + "Type"; + @Override protected Collection> nodePlugins() { return Collections.singletonList(InternalSettingsPlugin.class); @@ -111,7 +122,7 @@ protected Collection> nodePlugins() { public void testHighlightingWithStoredKeyword() throws IOException { XContentBuilder mappings = jsonBuilder(); mappings.startObject(); - mappings.startObject("type") + mappings.startObject(INDEX_DOCUMENT_TYPE) .startObject("properties") .startObject("text") .field("type", "keyword") @@ -119,9 +130,9 @@ public void testHighlightingWithStoredKeyword() throws IOException { .endObject() .endObject().endObject(); mappings.endObject(); - assertAcked(prepareCreate("test") - .addMapping("type", mappings)); - client().prepareIndex("test", "type", "1") + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, mappings)); + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1") .setSource(jsonBuilder().startObject().field("text", "foo").endObject()) .get(); refresh(); @@ -134,7 +145,7 @@ public void testHighlightingWithWildcardName() throws IOException { // test the kibana case with * as fieldname that will try highlight all fields including meta fields XContentBuilder mappings = jsonBuilder(); mappings.startObject(); - mappings.startObject("type") + mappings.startObject(INDEX_DOCUMENT_TYPE) .startObject("properties") .startObject("text") .field("type", "text") @@ -144,9 +155,9 @@ public void testHighlightingWithWildcardName() throws IOException { .endObject() .endObject().endObject(); mappings.endObject(); - assertAcked(prepareCreate("test") - .addMapping("type", mappings)); - client().prepareIndex("test", "type", "1") + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, mappings)); + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1") .setSource(jsonBuilder().startObject().field("text", "text").endObject()) .get(); refresh(); @@ -160,7 +171,7 @@ public void testHighlightingWithWildcardName() throws IOException { public void testHighlightingWhenFieldsAreNotStoredThereIsNoSource() throws IOException { XContentBuilder mappings = jsonBuilder(); mappings.startObject(); - mappings.startObject("type") + mappings.startObject(INDEX_DOCUMENT_TYPE) .startObject("_source") .field("enabled", false) .endObject() @@ -179,9 +190,9 @@ public void testHighlightingWhenFieldsAreNotStoredThereIsNoSource() throws IOExc .endObject() .endObject().endObject(); mappings.endObject(); - assertAcked(prepareCreate("test") - .addMapping("type", mappings)); - client().prepareIndex("test", "type", "1") + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, mappings)); + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1") .setSource(jsonBuilder().startObject().field("unstored_text", "text").field("text", "text").endObject()) .get(); refresh(); @@ -198,13 +209,13 @@ public void testHighlightingWhenFieldsAreNotStoredThereIsNoSource() throws IOExc // see #3486 public void testHighTermFrequencyDoc() throws IOException { - assertAcked(prepareCreate("test") - .addMapping("test", "name", "type=text,term_vector=with_positions_offsets,store=" + randomBoolean())); + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, "name", "type=text,term_vector=with_positions_offsets,store=" + randomBoolean())); StringBuilder builder = new StringBuilder(); for (int i = 0; i < 6000; i++) { builder.append("abc").append(" "); } - client().prepareIndex("test", "test", "1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1") .setSource("name", builder.toString()) .get(); refresh(); @@ -214,12 +225,12 @@ public void testHighTermFrequencyDoc() throws IOException { } public void testEnsureNoNegativeOffsets() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, "no_long_term", "type=text,term_vector=with_positions_offsets", "long_term", "type=text,term_vector=with_positions_offsets")); - client().prepareIndex("test", "type1", "1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1") .setSource("no_long_term", "This is a test where foo is highlighed and should be highlighted", "long_term", "This is a test thisisaverylongwordandmakessurethisfails where foo is highlighed " + "and should be highlighted") @@ -245,194 +256,252 @@ public void testEnsureNoNegativeOffsets() throws Exception { assertHighlight(search, 0, "no_long_term", 0, 1, equalTo("a test where foo is highlighed and")); } - public void testSourceLookupHighlightingUsingPlainHighlighter() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties") - // we don't store title and don't use term vector, now lets see if it works... - .startObject("title") - .field("type", "text") - .field("store", false) - .field("term_vector", "no") - .endObject() - .startObject("attachments").startObject("properties") - .startObject("body") - .field("type", "text") - .field("store", false) - .field("term_vector", "no") - .endObject().endObject().endObject() - .endObject().endObject().endObject())); + public void testSourceLookupHighlightingUsingPlainHighlighter1() throws Exception { + doTestSourceLookupHighlightingUsingPlainHighlighterTitle(TITLE); + } - IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[5]; - for (int i = 0; i < indexRequestBuilders.length; i++) { - indexRequestBuilders[i] = client().prepareIndex("test", "type1", Integer.toString(i)) - .setSource(XContentFactory.jsonBuilder().startObject() - .field("title", "This is a test on the highlighting bug present in elasticsearch") - .startArray("attachments") - .startObject().field("body", "attachment 1").endObject() - .startObject().field("body", "attachment 2").endObject() - .endArray().endObject()); - } - indexRandom(true, indexRequestBuilders); + public void testSourceLookupHighlightingUsingPlainHighlighter1_alias() throws Exception { + doTestSourceLookupHighlightingUsingPlainHighlighterTitle(TITLE_ALIAS); + } - SearchResponse search = client().prepareSearch() - .setQuery(matchQuery("title", "bug")) - .highlighter(new HighlightBuilder().field("title", -1, 0)) - .get(); + private void doTestSourceLookupHighlightingUsingPlainHighlighterTitle(final String highlightField) throws Exception { + this.defineMappingTitleAndAttachments("term_vector", "no"); + this.indexTitleAndAttachmentDocuments(); - for (int i = 0; i < indexRequestBuilders.length; i++) { - assertHighlight(search, i, "title", 0, equalTo("This is a test on the highlighting bug present in elasticsearch")); + final SearchResponse search = this.search(TITLE, + "bug", + new HighlightBuilder().field(highlightField, -1, 0)); + + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + assertHighlight(search, + i, + highlightField, + 0, + equalTo("This is a test on the highlighting bug present in elasticsearch.")); } + } - search = client().prepareSearch() - .setQuery(matchQuery("attachments.body", "attachment")) - .highlighter(new HighlightBuilder().field("attachments.body", -1, 0)) - .get(); + public void testSourceLookupHighlightingUsingPlainHighlighter2() throws Exception { + doTestSourceLookupHighlightingUsingPlainHighlighterBodyAttachments(ATTACHMENTS_BODY); + } - for (int i = 0; i < indexRequestBuilders.length; i++) { - assertHighlight(search, i, "attachments.body", 0, equalTo("attachment 1")); - assertHighlight(search, i, "attachments.body", 1, equalTo("attachment 2")); + public void testSourceLookupHighlightingUsingPlainHighlighter2_alias() throws Exception { + doTestSourceLookupHighlightingUsingPlainHighlighterBodyAttachments(ATTACHMENTS_BODY_ALIAS); + } + + private void doTestSourceLookupHighlightingUsingPlainHighlighterBodyAttachments(final String highlightField) throws Exception { + this.defineMappingTitleAndAttachments("term_vector", "no"); + this.indexTitleAndAttachmentDocuments(); + + final SearchResponse search = this.search(ATTACHMENTS_BODY, + "attachment", + new HighlightBuilder().field(highlightField, -1, 0)); + + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + assertHighlight(search, i, highlightField, 0, equalTo("attachment 1")); + assertHighlight(search, i, highlightField, 1, equalTo("attachment 2")); } + } + public void testSourceLookupHighlightingUsingFastVectorHighlighter1() throws Exception { + doTestSourceLookupHighlightingUsingFastVectorHighlighterTitle(TITLE); } - public void testSourceLookupHighlightingUsingFastVectorHighlighter() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties") - // we don't store title, now lets see if it works... - .startObject("title") - .field("type", "text") - .field("store", false) - .field("term_vector", "with_positions_offsets") - .endObject() - .startObject("attachments") - .startObject("properties") - .startObject("body") - .field("type", "text") - .field("store", false) - .field("term_vector", "with_positions_offsets") - .endObject() - .endObject() - .endObject() - .endObject().endObject().endObject())); + public void testSourceLookupHighlightingUsingFastVectorHighlighter1_alias() throws Exception { + doTestSourceLookupHighlightingUsingFastVectorHighlighterTitle(TITLE); + } - IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[5]; - for (int i = 0; i < indexRequestBuilders.length; i++) { - indexRequestBuilders[i] = client().prepareIndex("test", "type1", Integer.toString(i)) - .setSource(XContentFactory.jsonBuilder().startObject() - .field("title", "This is a test on the highlighting bug present in elasticsearch") - .startArray("attachments") - .startObject().field("body", "attachment 1").endObject() - .startObject().field("body", "attachment 2").endObject() - .endArray().endObject()); - } - indexRandom(true, indexRequestBuilders); + private void doTestSourceLookupHighlightingUsingFastVectorHighlighterTitle(final String highlightField) throws Exception { + this.defineMappingTitleAndAttachments("term_vector", "with_positions_offsets"); + this.indexTitleAndAttachmentDocuments(); - SearchResponse search = client().prepareSearch() - .setQuery(matchQuery("title", "bug")) - .highlighter(new HighlightBuilder().field("title", -1, 0)) - .get(); + final SearchResponse search = search(TITLE, + "bug", + new HighlightBuilder().field(highlightField, -1, 0)); - for (int i = 0; i < indexRequestBuilders.length; i++) { - assertHighlight(search, i, "title", 0, equalTo("This is a test on the highlighting bug present in elasticsearch")); + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + assertHighlight(search, + i, + highlightField, + 0, + equalTo("This is a test on the highlighting bug present in elasticsearch.")); } + } - search = client().prepareSearch() - .setQuery(matchQuery("attachments.body", "attachment")) - .highlighter(new HighlightBuilder().field("attachments.body", -1, 2)) - .execute().get(); + public void testSourceLookupHighlightingUsingFastVectorHighlighter2() throws Exception { + doTestSourceLookupHighlightingUsingFastVectorHighlighterBodyAttachments(ATTACHMENTS_BODY); + } - for (int i = 0; i < 5; i++) { - assertHighlight(search, i, "attachments.body", 0, equalTo("attachment 1")); - assertHighlight(search, i, "attachments.body", 1, equalTo("attachment 2")); - } + public void testSourceLookupHighlightingUsingFastVectorHighlighter2_alias() throws Exception { + doTestSourceLookupHighlightingUsingFastVectorHighlighterBodyAttachments(ATTACHMENTS_BODY_ALIAS); } - public void testSourceLookupHighlightingUsingPostingsHighlighter() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties") - // we don't store title, now lets see if it works... - .startObject("title") - .field("type", "text") - .field("store", false) - .field("index_options", "offsets") - .endObject() - .startObject("attachments") - .startObject("properties") - .startObject("body") - .field("type", "text") - .field("store", false) - .field("index_options", "offsets") - .endObject() - .endObject() - .endObject() - .endObject().endObject().endObject())); + private void doTestSourceLookupHighlightingUsingFastVectorHighlighterBodyAttachments(final String highlightField) throws Exception { + this.defineMappingTitleAndAttachments("term_vector", "with_positions_offsets"); + this.indexTitleAndAttachmentDocuments(); - IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[5]; - for (int i = 0; i < indexRequestBuilders.length; i++) { - indexRequestBuilders[i] = client().prepareIndex("test", "type1", Integer.toString(i)) - .setSource(XContentFactory.jsonBuilder().startObject() - .array("title", "This is a test on the highlighting bug present in elasticsearch. Hopefully it works.", - "This is the second bug to perform highlighting on.") - .startArray("attachments") - .startObject().field("body", "attachment for this test").endObject() - .startObject().field("body", "attachment 2").endObject() - .endArray().endObject()); + final SearchResponse search = search(ATTACHMENTS_BODY, + "attachment", + new HighlightBuilder().field(highlightField, -1, 2)); + + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + assertHighlight(search, i, highlightField, 0, equalTo("attachment 1")); + assertHighlight(search, i, highlightField, 1, equalTo("attachment 2")); } - indexRandom(true, indexRequestBuilders); + } - SearchResponse search = client().prepareSearch() - .setQuery(matchQuery("title", "bug")) - //asking for the whole field to be highlighted - .highlighter(new HighlightBuilder().field("title", -1, 0)).get(); + public void testSourceLookupHighlightingUsingPostingsHighlighter1() throws Exception { + doTestSourceLookupHighlightingUsingPostingsHighlighterTitle(TITLE); + } - for (int i = 0; i < indexRequestBuilders.length; i++) { - assertHighlight(search, i, "title", 0, - equalTo("This is a test on the highlighting bug present in elasticsearch. Hopefully it works.")); - assertHighlight(search, i, "title", 1, 2, equalTo("This is the second bug to perform highlighting on.")); + public void testSourceLookupHighlightingUsingPostingsHighlighter1_alias() throws Exception { + doTestSourceLookupHighlightingUsingPostingsHighlighterTitle(TITLE_ALIAS); + } + + private void doTestSourceLookupHighlightingUsingPostingsHighlighterTitle(final String highlightField) throws Exception { + this.defineMappingTitleAndAttachments("index_options", "offsets"); + this.indexTitleAndAttachmentDocuments(); + + final SearchResponse search = search(TITLE, + "bug", + new HighlightBuilder().field(highlightField, -1, 0)); + + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + assertHighlight(search, i, highlightField, 0, + equalTo("This is a test on the highlighting bug present in elasticsearch.")); + assertHighlight(search, + i, + highlightField, + 1, + 2, + equalTo("This is the second bug to perform highlighting on.")); } + } - search = client().prepareSearch() - .setQuery(matchQuery("title", "bug")) - //sentences will be generated out of each value - .highlighter(new HighlightBuilder().field("title")).get(); + public void testSourceLookupHighlightingUsingPostingsHighlighter2() throws Exception { + doTestSourceLookupHighlightingUsingPostingsHighlighterTitle2(TITLE); + } - for (int i = 0; i < indexRequestBuilders.length; i++) { - assertHighlight(search, i, "title", 0, - equalTo("This is a test on the highlighting bug present in elasticsearch. Hopefully it works.")); - assertHighlight(search, i, "title", 1, 2, + public void testSourceLookupHighlightingUsingPostingsHighlighter2_alias() throws Exception { + doTestSourceLookupHighlightingUsingPostingsHighlighterTitle2(TITLE); + } + + private void doTestSourceLookupHighlightingUsingPostingsHighlighterTitle2(final String highlightField) throws Exception { + this.defineMappingTitleAndAttachments("index_options", "offsets"); + this.indexTitleAndAttachmentDocuments(); + + //sentences will be generated out of each value + final SearchResponse search = search(TITLE, + "bug", + new HighlightBuilder().field(highlightField)); + + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + assertHighlight(search, i, highlightField, 0, + equalTo("This is a test on the highlighting bug present in elasticsearch.")); + assertHighlight(search, i, highlightField, 1, 2, equalTo("This is the second bug to perform highlighting on.")); } + } - search = client().prepareSearch() - .setQuery(matchQuery("attachments.body", "attachment")) - .highlighter(new HighlightBuilder().field("attachments.body", -1, 2)) + public void testSourceLookupHighlightingUsingPostingsHighlighter3() throws Exception { + doTestSourceLookupHighlightingUsingPostingsHighlighterAttachmentsBody(ATTACHMENTS_BODY); + } + + public void testSourceLookupHighlightingUsingPostingsHighlighter3_alias() throws Exception { + doTestSourceLookupHighlightingUsingPostingsHighlighterAttachmentsBody(ATTACHMENTS_BODY_ALIAS); + } + + private void doTestSourceLookupHighlightingUsingPostingsHighlighterAttachmentsBody(final String highlightField) throws Exception { + this.defineMappingTitleAndAttachments("index_options", "offsets"); + this.indexTitleAndAttachmentDocuments(); + + final SearchResponse search = client().prepareSearch() + .setQuery(matchQuery(ATTACHMENTS_BODY, "attachment")) + .highlighter(new HighlightBuilder().field(highlightField, -1, 2)) .get(); + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + assertHighlight(search, i, highlightField, 0, equalTo("attachment 1")); + assertHighlight(search, i, highlightField, 1, 2, equalTo("attachment 2")); + } + } + + private void defineMappingTitleAndAttachments(final String field, final String value) throws Exception { + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, jsonBuilder() + .startObject() + .startObject(INDEX_DOCUMENT_TYPE) + .startObject("properties") + .startObject(TITLE) + .field("type", "text") + .field("store", false) + .field(field, value) + .endObject() + .startObject(ATTACHMENTS) + .startObject("properties") + .startObject(BODY) + .field("type", "text") + .field("store", false) + .field(field, value) + .endObject() + .endObject() + .endObject() + .startObject(TITLE_ALIAS) + .field("type", AliasFieldMapper.CONTENT_TYPE) + .field(AliasFieldMapper.TypeParser.PATH, TITLE) + .endObject() + .startObject(ATTACHMENTS_BODY_ALIAS) + .field("type", AliasFieldMapper.CONTENT_TYPE) + .field(AliasFieldMapper.TypeParser.PATH, ATTACHMENTS_BODY) + .endObject() + .endObject() + .endObject() + .endObject())); + } + + private void indexTitleAndAttachmentDocuments() throws Exception { + IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[TITLE_AND_ATTACHMENT_DOCUMENT_COUNT]; for (int i = 0; i < indexRequestBuilders.length; i++) { - assertHighlight(search, i, "attachments.body", 0, equalTo("attachment for this test")); - assertHighlight(search, i, "attachments.body", 1, 2, equalTo("attachment 2")); + indexRequestBuilders[i] = client().prepareIndex(INDEX, + INDEX_DOCUMENT_TYPE, + Integer.toString(i)) + .setSource(XContentFactory.jsonBuilder().startObject() + .array(TITLE, "This is a test on the highlighting bug present in elasticsearch.", + "This is the second bug to perform highlighting on.") + .startArray(ATTACHMENTS) + .startObject().field(BODY, "attachment 1").endObject() + .startObject().field(BODY, "attachment 2").endObject() + .endArray().endObject()); } + indexRandom(true, indexRequestBuilders); + } + + private SearchResponse search(final String field, final String value, final HighlightBuilder highlight) { + return client().prepareSearch() + .setQuery(matchQuery(field, value)) + .highlighter(highlight) + .get(); } public void testHighlightIssue1994() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", - "title", "type=text,store=false", + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, + TITLE, "type=text,store=false", "titleTV", "type=text,store=false,term_vector=with_positions_offsets")); String[] titles = new String[] {"This is a test on the highlighting bug present in elasticsearch", "The bug is bugging us"}; - indexRandom(false, client().prepareIndex("test", "type1", "1").setSource("title", titles, "titleTV", titles)); + indexRandom(false, client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1").setSource(TITLE, titles, "titleTV", titles)); - indexRandom(true, client().prepareIndex("test", "type1", "2") + indexRandom(true, client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "2") .setSource("titleTV", new String[]{"some text to highlight", "highlight other text"})); SearchResponse search = client().prepareSearch() - .setQuery(matchQuery("title", "bug")) - .highlighter(new HighlightBuilder().field("title", -1, 2).field("titleTV", -1, 2).requireFieldMatch(false)) + .setQuery(matchQuery(TITLE, "bug")) + .highlighter(new HighlightBuilder().field(TITLE, -1, 2).field("titleTV", -1, 2).requireFieldMatch(false)) .get(); - assertHighlight(search, 0, "title", 0, equalTo("This is a test on the highlighting bug present in elasticsearch")); - assertHighlight(search, 0, "title", 1, 2, equalTo("The bug is bugging us")); + assertHighlight(search, 0, TITLE, 0, equalTo("This is a test on the highlighting bug present in elasticsearch")); + assertHighlight(search, 0, TITLE, 1, 2, equalTo("The bug is bugging us")); assertHighlight(search, 0, "titleTV", 0, equalTo("This is a test on the highlighting bug present in elasticsearch")); assertHighlight(search, 0, "titleTV", 1, 2, equalTo("The bug is bugging us")); @@ -446,10 +515,10 @@ public void testHighlightIssue1994() throws Exception { } public void testGlobalHighlightingSettingsOverriddenAtFieldLevel() { - createIndex("test"); + createIndex(INDEX); ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", new String[]{"this is a test", "this is the second test"}, "field2", new String[]{"this is another test", "yet another test"}).get(); refresh(); @@ -462,7 +531,7 @@ public void testGlobalHighlightingSettingsOverriddenAtFieldLevel() { .field(new HighlightBuilder.Field("field2").preTags("").postTags("") .fragmentSize(50).requireFieldMatch(false))); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field1", 0, 2, equalTo("test")); assertHighlight(searchResponse, 0, "field1", 1, 2, equalTo("test")); @@ -471,14 +540,14 @@ public void testGlobalHighlightingSettingsOverriddenAtFieldLevel() { // Issue #5175 public void testHighlightingOnWildcardFields() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, "field-postings", "type=text,index_options=offsets", "field-fvh", "type=text,term_vector=with_positions_offsets", "field-plain", "type=text")); ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field-postings", "This is the first test sentence. Here is the second one.", "field-fvh", "This is the test with term_vectors", "field-plain", "This is the test for the plain highlighter").get(); @@ -490,7 +559,7 @@ public void testHighlightingOnWildcardFields() throws Exception { .query(termQuery("field-postings", "test")) .highlighter(highlight().field("field*").preTags("").postTags("").requireFieldMatch(false)); - SearchResponse searchResponse = client().search(searchRequest("test").source(source)).actionGet(); + SearchResponse searchResponse = client().search(searchRequest(INDEX).source(source)).actionGet(); assertHighlight(searchResponse, 0, "field-postings", 0, 1, equalTo("This is the first test sentence. Here is the second one.")); @@ -499,8 +568,8 @@ public void testHighlightingOnWildcardFields() throws Exception { } public void testForceSourceWithSourceDisabled() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", jsonBuilder().startObject().startObject("type1") + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE) .startObject("_source").field("enabled", false).endObject() .startObject("properties") .startObject("field1").field("type", "text").field("store", true).field("index_options", "offsets") @@ -510,41 +579,43 @@ public void testForceSourceWithSourceDisabled() throws Exception { ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "The quick brown fox jumps over the lazy dog", "field2", "second field content").get(); refresh(); //works using stored field - SearchResponse searchResponse = client().prepareSearch("test") + SearchResponse searchResponse = client().prepareSearch(INDEX) .setQuery(termQuery("field1", "quick")) .highlighter(new HighlightBuilder().field(new Field("field1").preTags("").postTags(""))) .get(); assertHighlight(searchResponse, 0, "field1", 0, 1, equalTo("The quick brown fox jumps over the lazy dog")); - assertFailures(client().prepareSearch("test") + assertFailures(client().prepareSearch(INDEX) .setQuery(termQuery("field1", "quick")) .highlighter( new HighlightBuilder().field(new Field("field1").preTags("").postTags("").forceSource(true))), RestStatus.BAD_REQUEST, - containsString("source is forced for fields [field1] but type [type1] has disabled _source")); + containsString("source is forced for fields [field1] but type [" + INDEX_DOCUMENT_TYPE + "] has disabled _source")); SearchSourceBuilder searchSource = SearchSourceBuilder.searchSource().query(termQuery("field1", "quick")) .highlighter(highlight().forceSource(true).field("field1")); - assertFailures(client().prepareSearch("test").setSource(searchSource), + assertFailures(client().prepareSearch(INDEX).setSource(searchSource), RestStatus.BAD_REQUEST, - containsString("source is forced for fields [field1] but type [type1] has disabled _source")); + containsString("source is forced for fields [field1] but type [" + INDEX_DOCUMENT_TYPE + "] has disabled _source")); searchSource = SearchSourceBuilder.searchSource().query(termQuery("field1", "quick")) .highlighter(highlight().forceSource(true).field("field*")); - assertFailures(client().prepareSearch("test").setSource(searchSource), + assertFailures(client().prepareSearch(INDEX).setSource(searchSource), RestStatus.BAD_REQUEST, - matches("source is forced for fields \\[field\\d, field\\d\\] but type \\[type1\\] has disabled _source")); + matches("source is forced for fields \\[field\\d, field\\d\\] but type \\[" + + INDEX_DOCUMENT_TYPE + + "\\] has disabled _source")); } public void testPlainHighlighter() throws Exception { ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "this is a test", "field2", "The quick brown fox jumps over the lazy dog").get(); refresh(); @@ -553,17 +624,17 @@ public void testPlainHighlighter() throws Exception { .query(termQuery("field1", "test")) .highlighter(highlight().field("field1").order("score").preTags("").postTags("")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field1", 0, 1, equalTo("this is a test")); } public void testFastVectorHighlighter() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1TermVectorMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1TermVectorMapping())); ensureGreen(); - indexRandom(true, client().prepareIndex("test", "type1") + indexRandom(true, client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "this is a test", "field2", "The quick brown fox jumps over the lazy dog")); logger.info("--> highlighting and searching on field1"); @@ -571,7 +642,7 @@ public void testFastVectorHighlighter() throws Exception { .query(termQuery("field1", "test")) .highlighter(highlight().field("field1", 100, 0).order("score").preTags("").postTags("")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field1", 0, 1, equalTo("this is a test")); @@ -580,7 +651,7 @@ public void testFastVectorHighlighter() throws Exception { .query(matchQuery("field2", "quick")) .highlighter(highlight().field("field2", 30, 1).boundaryChars(new char[] {' '})); - searchResponse = client().prepareSearch("test").setSource(source).get(); + searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over")); @@ -589,16 +660,16 @@ public void testFastVectorHighlighter() throws Exception { .query(matchQuery("field2", "quick")) .highlighter(highlight().field(new Field("field2").fragmentSize(30).numOfFragments(1).boundaryChars(new char[] {' '}))); - searchResponse = client().prepareSearch("test").setSource(source).get(); + searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over")); } public void testHighlighterWithSentenceBoundaryScanner() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1TermVectorMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1TermVectorMapping())); ensureGreen(); - indexRandom(true, client().prepareIndex("test", "type1") + indexRandom(true, client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "A sentence with few words. Another sentence with even more words.")); for (String type : new String[] {"unified", "fvh"}) { @@ -610,7 +681,7 @@ public void testHighlighterWithSentenceBoundaryScanner() throws Exception { .highlighterType(type) .preTags("").postTags("") .boundaryScannerType(BoundaryScannerType.SENTENCE)); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field1", 0, 2, anyOf( equalTo("A sentence with few words"), @@ -625,10 +696,10 @@ public void testHighlighterWithSentenceBoundaryScanner() throws Exception { } public void testHighlighterWithSentenceBoundaryScannerAndLocale() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1TermVectorMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1TermVectorMapping())); ensureGreen(); - indexRandom(true, client().prepareIndex("test", "type1") + indexRandom(true, client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "A sentence with few words. Another sentence with even more words.")); for (String type : new String[] {"fvh", "unified"}) { @@ -642,7 +713,7 @@ public void testHighlighterWithSentenceBoundaryScannerAndLocale() throws Excepti .boundaryScannerType(BoundaryScannerType.SENTENCE) .boundaryScannerLocale(Locale.ENGLISH.toLanguageTag())); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field1", 0, 2, anyOf( equalTo("A sentence with few words"), @@ -657,10 +728,10 @@ public void testHighlighterWithSentenceBoundaryScannerAndLocale() throws Excepti } public void testHighlighterWithWordBoundaryScanner() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1TermVectorMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1TermVectorMapping())); ensureGreen(); - indexRandom(true, client().prepareIndex("test", "type1") + indexRandom(true, client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "some quick and hairy brown:fox jumped over the lazy dog")); logger.info("--> highlighting and searching on 'field' with word boundary_scanner"); @@ -673,7 +744,7 @@ public void testHighlighterWithWordBoundaryScanner() throws Exception { .preTags("").postTags("") .boundaryScannerType(BoundaryScannerType.WORD)); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field1", 0, 1, anyOf( equalTo("some quick and hairy brown"), @@ -683,10 +754,10 @@ public void testHighlighterWithWordBoundaryScanner() throws Exception { } public void testHighlighterWithWordBoundaryScannerAndLocale() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1TermVectorMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1TermVectorMapping())); ensureGreen(); - indexRandom(true, client().prepareIndex("test", "type1") + indexRandom(true, client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "some quick and hairy brown:fox jumped over the lazy dog")); for (String type : new String[] {"unified", "fvh"}) { @@ -699,7 +770,7 @@ public void testHighlighterWithWordBoundaryScannerAndLocale() throws Exception { .boundaryScannerType(BoundaryScannerType.WORD) .boundaryScannerLocale(Locale.ENGLISH.toLanguageTag())); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field1", 0, 1, anyOf( equalTo("some quick and hairy brown"), @@ -713,13 +784,13 @@ public void testHighlighterWithWordBoundaryScannerAndLocale() throws Exception { * phraseLimit is not set. Its default is now reasonably low. */ public void testFVHManyMatches() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1TermVectorMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1TermVectorMapping())); ensureGreen(); // Index one megabyte of "t " over and over and over again String pattern = "t "; String value = new String(new char[1024 * 256 / pattern.length()]).replace("\0", pattern); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", value).get(); refresh(); @@ -727,7 +798,7 @@ public void testFVHManyMatches() throws Exception { SearchSourceBuilder source = searchSource() .query(termQuery("field1", "t")) .highlighter(highlight().highlighterType("fvh").field("field1", 20, 1).order("score").preTags("").postTags("")); - SearchResponse defaultPhraseLimit = client().search(searchRequest("test").source(source)).actionGet(); + SearchResponse defaultPhraseLimit = client().search(searchRequest(INDEX).source(source)).actionGet(); assertHighlight(defaultPhraseLimit, 0, "field1", 0, 1, containsString("t")); logger.info("--> highlighting and searching on field1 with large phrase limit"); @@ -735,7 +806,7 @@ public void testFVHManyMatches() throws Exception { .query(termQuery("field1", "t")) .highlighter(highlight().highlighterType("fvh").field("field1", 20, 1).order("score").preTags("").postTags("") .phraseLimit(30000)); - SearchResponse largePhraseLimit = client().search(searchRequest("test").source(source)).actionGet(); + SearchResponse largePhraseLimit = client().search(searchRequest(INDEX).source(source)).actionGet(); assertHighlight(largePhraseLimit, 0, "field1", 0, 1, containsString("t")); /* @@ -757,8 +828,8 @@ public void testMatchedFieldsFvhNoRequireFieldMatch() throws Exception { } private void checkMatchedFieldsCase(boolean requireFieldMatch) throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1") + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, XContentFactory.jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE) .startObject("properties") .startObject("foo") .field("type", "text") @@ -789,19 +860,19 @@ private void checkMatchedFieldsCase(boolean requireFieldMatch) throws Exception .endObject().endObject().endObject())); ensureGreen(); - index("test", "type1", "1", + index(INDEX, INDEX_DOCUMENT_TYPE, "1", "foo", "running with scissors"); - index("test", "type1", "2", + index(INDEX, INDEX_DOCUMENT_TYPE, "2", "foo", "cat cat junk junk junk junk junk junk junk cats junk junk", "bar", "cat cat junk junk junk junk junk junk junk cats junk junk"); - index("test", "type1", "3", + index(INDEX, INDEX_DOCUMENT_TYPE, "3", "foo", "weird", "bar", "result"); refresh(); Field fooField = new Field("foo").numOfFragments(1).order("score").fragmentSize(25) .highlighterType("fvh").requireFieldMatch(requireFieldMatch); - SearchRequestBuilder req = client().prepareSearch("test").highlighter(new HighlightBuilder().field(fooField)); + SearchRequestBuilder req = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(fooField)); // First check highlighting without any matched fields set SearchResponse resp = req.setQuery(queryStringQuery("running scissors").field("foo")).get(); @@ -816,7 +887,7 @@ private void checkMatchedFieldsCase(boolean requireFieldMatch) throws Exception fooField = new Field("foo").numOfFragments(1).order("score").fragmentSize(25).highlighterType("fvh") .requireFieldMatch(requireFieldMatch); fooField.matchedFields("foo", "foo.plain"); - req = client().prepareSearch("test").highlighter(new HighlightBuilder().field(fooField)); + req = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(fooField)); resp = req.setQuery(queryStringQuery("running scissors").field("foo")).get(); assertHighlight(resp, 0, "foo", 0, equalTo("running with scissors")); @@ -829,7 +900,7 @@ private void checkMatchedFieldsCase(boolean requireFieldMatch) throws Exception fooField = new Field("foo").numOfFragments(1).order("score").fragmentSize(25).highlighterType("fvh") .requireFieldMatch(requireFieldMatch); fooField.matchedFields("foo.plain"); - req = client().prepareSearch("test").highlighter(new HighlightBuilder().field(fooField)); + req = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(fooField)); resp = req.setQuery(queryStringQuery("foo.plain:running scissors").field("foo")).get(); assertHighlight(resp, 0, "foo", 0, equalTo("running with scissors")); @@ -837,7 +908,7 @@ private void checkMatchedFieldsCase(boolean requireFieldMatch) throws Exception fooField = new Field("foo").numOfFragments(1).order("score").fragmentSize(25).highlighterType("fvh") .requireFieldMatch(requireFieldMatch); fooField.matchedFields("foo", "foo.plain"); - req = client().prepareSearch("test").highlighter(new HighlightBuilder().field(fooField)); + req = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(fooField)); resp = req.setQuery(queryStringQuery("foo.plain:running^5 scissors").field("foo")).get(); assertHighlight(resp, 0, "foo", 0, equalTo("running with scissors")); @@ -858,12 +929,12 @@ private void checkMatchedFieldsCase(boolean requireFieldMatch) throws Exception assertHighlight(resp, 0, "foo", 0, equalTo("junk junk cats junk junk")); // which can also be written by searching on the subfield - resp = req.setQuery(queryStringQuery("cats").field("foo").field("foo.plain", 5)).get(); + resp = req.setQuery(queryStringQuery("cats").field("foo").field("foo.plain", TITLE_AND_ATTACHMENT_DOCUMENT_COUNT)).get(); assertHighlight(resp, 0, "foo", 0, equalTo("junk junk cats junk junk")); // Speaking of two fields, you can have two fields, only one of which has matchedFields enabled - QueryBuilder twoFieldsQuery = queryStringQuery("cats").field("foo").field("foo.plain", 5) - .field("bar").field("bar.plain", 5); + QueryBuilder twoFieldsQuery = queryStringQuery("cats").field("foo").field("foo.plain", TITLE_AND_ATTACHMENT_DOCUMENT_COUNT) + .field("bar").field("bar.plain", TITLE_AND_ATTACHMENT_DOCUMENT_COUNT); Field barField = new Field("bar").numOfFragments(1).order("score").fragmentSize(25).highlighterType("fvh") .requireFieldMatch(requireFieldMatch); resp = req.setQuery(twoFieldsQuery).highlighter(new HighlightBuilder().field(fooField).field(barField)).get(); @@ -912,13 +983,17 @@ private void checkMatchedFieldsCase(boolean requireFieldMatch) throws Exception } public void testFastVectorHighlighterManyDocs() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1TermVectorMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1TermVectorMapping())); ensureGreen(); int COUNT = between(20, 100); IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[COUNT]; for (int i = 0; i < COUNT; i++) { - indexRequestBuilders[i] = client().prepareIndex("test", "type1", Integer.toString(i)).setSource("field1", "test " + i); + indexRequestBuilders[i] = client() + .prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, + Integer.toString(i)) + .setSource("field1", + "test " + i); } logger.info("--> indexing docs"); indexRandom(true, indexRequestBuilders); @@ -937,7 +1012,7 @@ public void testFastVectorHighlighterManyDocs() throws Exception { } public XContentBuilder type1TermVectorMapping() throws IOException { - return XContentFactory.jsonBuilder().startObject().startObject("type1") + return XContentFactory.jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE) .startObject("properties") .startObject("field1").field("type", "text").field("term_vector", "with_positions_offsets").endObject() .startObject("field2").field("type", "text").field("term_vector", "with_positions_offsets").endObject() @@ -946,96 +1021,96 @@ public XContentBuilder type1TermVectorMapping() throws IOException { } public void testSameContent() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", "title", "type=text,store=true,term_vector=with_positions_offsets")); + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, TITLE, "type=text,store=true,term_vector=with_positions_offsets")); - IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[5]; - for (int i = 0; i < 5; i++) { - indexRequestBuilders[i] = client().prepareIndex("test", "type1", Integer.toString(i)) - .setSource("title", "This is a test on the highlighting bug present in elasticsearch"); + IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[TITLE_AND_ATTACHMENT_DOCUMENT_COUNT]; + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + indexRequestBuilders[i] = client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, Integer.toString(i)) + .setSource(TITLE, "This is a test on the highlighting bug present in elasticsearch"); } indexRandom(true, indexRequestBuilders); SearchResponse search = client().prepareSearch() - .setQuery(matchQuery("title", "bug")) - .highlighter(new HighlightBuilder().field("title", -1, 0)) + .setQuery(matchQuery(TITLE, "bug")) + .highlighter(new HighlightBuilder().field(TITLE, -1, 0)) .get(); - for (int i = 0; i < 5; i++) { - assertHighlight(search, i, "title", 0, 1, equalTo("This is a test on the highlighting bug " + + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + assertHighlight(search, i, TITLE, 0, 1, equalTo("This is a test on the highlighting bug " + "present in elasticsearch")); } } public void testFastVectorHighlighterOffsetParameter() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", "title", "type=text,store=true,term_vector=with_positions_offsets").get()); + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, TITLE, "type=text,store=true,term_vector=with_positions_offsets").get()); - IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[5]; - for (int i = 0; i < 5; i++) { - indexRequestBuilders[i] = client().prepareIndex("test", "type1", Integer.toString(i)) - .setSource("title", "This is a test on the highlighting bug present in elasticsearch"); + IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[TITLE_AND_ATTACHMENT_DOCUMENT_COUNT]; + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + indexRequestBuilders[i] = client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, Integer.toString(i)) + .setSource(TITLE, "This is a test on the highlighting bug present in elasticsearch"); } indexRandom(true, indexRequestBuilders); SearchResponse search = client().prepareSearch() - .setQuery(matchQuery("title", "bug")) - .highlighter(new HighlightBuilder().field("title", 30, 1, 10).highlighterType("fvh")) + .setQuery(matchQuery(TITLE, "bug")) + .highlighter(new HighlightBuilder().field(TITLE, 30, 1, 10).highlighterType("fvh")) .get(); - for (int i = 0; i < 5; i++) { + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { // LUCENE 3.1 UPGRADE: Caused adding the space at the end... - assertHighlight(search, i, "title", 0, 1, equalTo("highlighting bug present in elasticsearch")); + assertHighlight(search, i, TITLE, 0, 1, equalTo("highlighting bug present in elasticsearch")); } } public void testEscapeHtml() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", "title", "type=text,store=true")); + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, TITLE, "type=text,store=true")); - IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[5]; + IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[TITLE_AND_ATTACHMENT_DOCUMENT_COUNT]; for (int i = 0; i < indexRequestBuilders.length; i++) { - indexRequestBuilders[i] = client().prepareIndex("test", "type1", Integer.toString(i)) - .setSource("title", "This is a html escaping highlighting test for *&? elasticsearch"); + indexRequestBuilders[i] = client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, Integer.toString(i)) + .setSource(TITLE, "This is a html escaping highlighting test for *&? elasticsearch"); } indexRandom(true, indexRequestBuilders); SearchResponse search = client().prepareSearch() - .setQuery(matchQuery("title", "test")) - .highlighter(new HighlightBuilder().encoder("html").field("title", 50, 1, 10)) + .setQuery(matchQuery(TITLE, "test")) + .highlighter(new HighlightBuilder().encoder("html").field(TITLE, 50, 1, 10)) .get(); for (int i = 0; i < indexRequestBuilders.length; i++) { - assertHighlight(search, i, "title", 0, 1, + assertHighlight(search, i, TITLE, 0, 1, startsWith("This is a html escaping highlighting test for *&?")); } } public void testEscapeHtmlVector() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", "title", "type=text,store=true,term_vector=with_positions_offsets")); + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, TITLE, "type=text,store=true,term_vector=with_positions_offsets")); - IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[5]; - for (int i = 0; i < 5; i++) { - indexRequestBuilders[i] = client().prepareIndex("test", "type1", Integer.toString(i)) - .setSource("title", "This is a html escaping highlighting test for *&? elasticsearch"); + IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[TITLE_AND_ATTACHMENT_DOCUMENT_COUNT]; + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + indexRequestBuilders[i] = client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, Integer.toString(i)) + .setSource(TITLE, "This is a html escaping highlighting test for *&? elasticsearch"); } indexRandom(true, indexRequestBuilders); SearchResponse search = client().prepareSearch() - .setQuery(matchQuery("title", "test")) - .highlighter(new HighlightBuilder().encoder("html").field("title", 30, 1, 10).highlighterType("plain")) + .setQuery(matchQuery(TITLE, "test")) + .highlighter(new HighlightBuilder().encoder("html").field(TITLE, 30, 1, 10).highlighterType("plain")) .get(); - for (int i = 0; i < 5; i++) { - assertHighlight(search, i, "title", 0, 1, equalTo(" highlighting test for *&? elasticsearch")); + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + assertHighlight(search, i, TITLE, 0, 1, equalTo(" highlighting test for *&? elasticsearch")); } } public void testMultiMapperVectorWithStore() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties") - .startObject("title") + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE).startObject("properties") + .startObject(TITLE) .field("type", "text") .field("store", true) .field("term_vector", "with_positions_offsets") @@ -1050,16 +1125,16 @@ public void testMultiMapperVectorWithStore() throws Exception { .endObject() .endObject().endObject().endObject().endObject())); ensureGreen(); - client().prepareIndex("test", "type1", "1").setSource("title", "this is a test").get(); + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1").setSource(TITLE, "this is a test").get(); refresh(); // simple search on body with standard analyzer with a simple field query SearchResponse search = client().prepareSearch() - .setQuery(matchQuery("title", "this is a test")) - .highlighter(new HighlightBuilder().encoder("html").field("title", 50, 1)) + .setQuery(matchQuery(TITLE, "this is a test")) + .highlighter(new HighlightBuilder().encoder("html").field(TITLE, 50, 1)) .get(); - assertHighlight(search, 0, "title", 0, 1, equalTo("this is a test")); + assertHighlight(search, 0, TITLE, 0, 1, equalTo("this is a test")); // search on title.key and highlight on title search = client().prepareSearch() @@ -1071,9 +1146,9 @@ public void testMultiMapperVectorWithStore() throws Exception { } public void testMultiMapperVectorFromSource() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties") - .startObject("title") + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE).startObject("properties") + .startObject(TITLE) .field("type", "text") .field("store", false) .field("term_vector", "with_positions_offsets") @@ -1089,16 +1164,16 @@ public void testMultiMapperVectorFromSource() throws Exception { .endObject().endObject().endObject().endObject())); ensureGreen(); - client().prepareIndex("test", "type1", "1").setSource("title", "this is a test").get(); + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1").setSource(TITLE, "this is a test").get(); refresh(); // simple search on body with standard analyzer with a simple field query SearchResponse search = client().prepareSearch() - .setQuery(matchQuery("title", "this is a test")) - .highlighter(new HighlightBuilder().encoder("html").field("title", 50, 1)) + .setQuery(matchQuery(TITLE, "this is a test")) + .highlighter(new HighlightBuilder().encoder("html").field(TITLE, 50, 1)) .get(); - assertHighlight(search, 0, "title", 0, 1, equalTo("this is a test")); + assertHighlight(search, 0, TITLE, 0, 1, equalTo("this is a test")); // search on title.key and highlight on title.key search = client().prepareSearch() @@ -1110,9 +1185,9 @@ public void testMultiMapperVectorFromSource() throws Exception { } public void testMultiMapperNoVectorWithStore() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties") - .startObject("title") + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE).startObject("properties") + .startObject(TITLE) .field("type", "text") .field("store", true) .field("term_vector", "no") @@ -1129,17 +1204,17 @@ public void testMultiMapperNoVectorWithStore() throws Exception { .endObject().endObject().endObject())); ensureGreen(); - client().prepareIndex("test", "type1", "1").setSource("title", "this is a test").get(); + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1").setSource(TITLE, "this is a test").get(); refresh(); // simple search on body with standard analyzer with a simple field query SearchResponse search = client().prepareSearch() - .setQuery(matchQuery("title", "this is a test")) - .highlighter(new HighlightBuilder().encoder("html").field("title", 50, 1)) + .setQuery(matchQuery(TITLE, "this is a test")) + .highlighter(new HighlightBuilder().encoder("html").field(TITLE, 50, 1)) .get(); - assertHighlight(search, 0, "title", 0, 1, equalTo("this is a test")); + assertHighlight(search, 0, TITLE, 0, 1, equalTo("this is a test")); // search on title.key and highlight on title search = client().prepareSearch() @@ -1151,9 +1226,9 @@ public void testMultiMapperNoVectorWithStore() throws Exception { } public void testMultiMapperNoVectorFromSource() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties") - .startObject("title") + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE).startObject("properties") + .startObject(TITLE) .field("type", "text") .field("store", false) .field("term_vector", "no") @@ -1169,16 +1244,16 @@ public void testMultiMapperNoVectorFromSource() throws Exception { .endObject() .endObject().endObject().endObject())); ensureGreen(); - client().prepareIndex("test", "type1", "1").setSource("title", "this is a test").get(); + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1").setSource(TITLE, "this is a test").get(); refresh(); // simple search on body with standard analyzer with a simple field query SearchResponse search = client().prepareSearch() - .setQuery(matchQuery("title", "this is a test")) - .highlighter(new HighlightBuilder().encoder("html").field("title", 50, 1)) + .setQuery(matchQuery(TITLE, "this is a test")) + .highlighter(new HighlightBuilder().encoder("html").field(TITLE, 50, 1)) .get(); - assertHighlight(search, 0, "title", 0, 1, equalTo("this is a test")); + assertHighlight(search, 0, TITLE, 0, 1, equalTo("this is a test")); // search on title.key and highlight on title.key search = client().prepareSearch() @@ -1190,94 +1265,94 @@ public void testMultiMapperNoVectorFromSource() throws Exception { } public void testFastVectorHighlighterShouldFailIfNoTermVectors() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", "title", "type=text,store=true,term_vector=no")); + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, TITLE, "type=text,store=true,term_vector=no")); ensureGreen(); - IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[5]; - for (int i = 0; i < 5; i++) { - indexRequestBuilders[i] = client().prepareIndex("test", "type1", Integer.toString(i)) - .setSource("title", "This is a test for the enabling fast vector highlighter"); + IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[TITLE_AND_ATTACHMENT_DOCUMENT_COUNT]; + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + indexRequestBuilders[i] = client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, Integer.toString(i)) + .setSource(TITLE, "This is a test for the enabling fast vector highlighter"); } indexRandom(true, indexRequestBuilders); SearchResponse search = client().prepareSearch() - .setQuery(matchPhraseQuery("title", "this is a test")) - .highlighter(new HighlightBuilder().field("title", 50, 1, 10)) + .setQuery(matchPhraseQuery(TITLE, "this is a test")) + .highlighter(new HighlightBuilder().field(TITLE, 50, 1, 10)) .get(); assertNoFailures(search); assertFailures(client().prepareSearch() - .setQuery(matchPhraseQuery("title", "this is a test")) - .highlighter(new HighlightBuilder().field("title", 50, 1, 10).highlighterType("fvh")), + .setQuery(matchPhraseQuery(TITLE, "this is a test")) + .highlighter(new HighlightBuilder().field(TITLE, 50, 1, 10).highlighterType("fvh")), RestStatus.BAD_REQUEST, containsString("the field [title] should be indexed with term vector with position offsets to be " + "used with fast vector highlighter")); //should not fail if there is a wildcard assertNoFailures(client().prepareSearch() - .setQuery(matchPhraseQuery("title", "this is a test")) + .setQuery(matchPhraseQuery(TITLE, "this is a test")) .highlighter(new HighlightBuilder().field("tit*", 50, 1, 10).highlighterType("fvh")).get()); } public void testDisableFastVectorHighlighter() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", "title", "type=text,store=true,term_vector=with_positions_offsets,analyzer=classic")); + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, TITLE, "type=text,store=true,term_vector=with_positions_offsets,analyzer=classic")); ensureGreen(); - IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[5]; + IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[TITLE_AND_ATTACHMENT_DOCUMENT_COUNT]; for (int i = 0; i < indexRequestBuilders.length; i++) { - indexRequestBuilders[i] = client().prepareIndex("test", "type1", Integer.toString(i)) - .setSource("title", "This is a test for the workaround for the fast vector highlighting SOLR-3724"); + indexRequestBuilders[i] = client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, Integer.toString(i)) + .setSource(TITLE, "This is a test for the workaround for the fast vector highlighting SOLR-3724"); } indexRandom(true, indexRequestBuilders); SearchResponse search = client().prepareSearch() - .setQuery(matchPhraseQuery("title", "test for the workaround")) - .highlighter(new HighlightBuilder().field("title", 50, 1, 10).highlighterType("fvh")) + .setQuery(matchPhraseQuery(TITLE, "test for the workaround")) + .highlighter(new HighlightBuilder().field(TITLE, 50, 1, 10).highlighterType("fvh")) .get(); for (int i = 0; i < indexRequestBuilders.length; i++) { // Because of SOLR-3724 nothing is highlighted when FVH is used - assertNotHighlighted(search, i, "title"); + assertNotHighlighted(search, i, TITLE); } // Using plain highlighter instead of FVH search = client().prepareSearch() - .setQuery(matchPhraseQuery("title", "test for the workaround")) - .highlighter(new HighlightBuilder().field("title", 50, 1, 10).highlighterType("plain")) + .setQuery(matchPhraseQuery(TITLE, "test for the workaround")) + .highlighter(new HighlightBuilder().field(TITLE, 50, 1, 10).highlighterType("plain")) .get(); for (int i = 0; i < indexRequestBuilders.length; i++) { - assertHighlight(search, i, "title", 0, 1, + assertHighlight(search, i, TITLE, 0, 1, equalTo("This is a test for the workaround for the fast vector highlighting SOLR-3724")); } // Using plain highlighter instead of FVH on the field level search = client().prepareSearch() - .setQuery(matchPhraseQuery("title", "test for the workaround")) + .setQuery(matchPhraseQuery(TITLE, "test for the workaround")) .highlighter( - new HighlightBuilder().field(new HighlightBuilder.Field("title").highlighterType("plain")).highlighterType( + new HighlightBuilder().field(new HighlightBuilder.Field(TITLE).highlighterType("plain")).highlighterType( "plain")) .get(); for (int i = 0; i < indexRequestBuilders.length; i++) { - assertHighlight(search, i, "title", 0, 1, + assertHighlight(search, i, TITLE, 0, 1, equalTo("This is a test for the workaround for the fast vector highlighting SOLR-3724")); } } public void testFSHHighlightAllMvFragments() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", "tags", "type=text,term_vector=with_positions_offsets")); + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, "tags", "type=text,term_vector=with_positions_offsets")); ensureGreen(); - client().prepareIndex("test", "type1", "1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1") .setSource("tags", new String[] { "this is a really long tag i would like to highlight", "here is another one that is very long and has the tag token near the end"}).get(); refresh(); - SearchResponse response = client().prepareSearch("test") + SearchResponse response = client().prepareSearch(INDEX) .setQuery(QueryBuilders.matchQuery("tags", "tag")) .highlighter(new HighlightBuilder().field("tags", -1, 0).highlighterType("fvh")).get(); @@ -1287,9 +1362,9 @@ public void testFSHHighlightAllMvFragments() throws Exception { } public void testBoostingQuery() { - createIndex("test"); + createIndex(INDEX); ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "this is a test", "field2", "The quick brown fox jumps over the lazy dog").get(); refresh(); @@ -1298,15 +1373,15 @@ public void testBoostingQuery() { .query(boostingQuery(termQuery("field2", "brown"), termQuery("field2", "foobar")).negativeBoost(0.5f)) .highlighter(highlight().field("field2").order("score").preTags("").postTags("")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy dog")); } public void testBoostingQueryTermVector() throws IOException { - assertAcked(prepareCreate("test").addMapping("type1", type1TermVectorMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1TermVectorMapping())); ensureGreen(); - client().prepareIndex("test", "type1").setSource( + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE).setSource( "field1", "this is a test", "field2", "The quick brown fox jumps over the lazy dog").get(); refresh(); @@ -1316,16 +1391,16 @@ public void testBoostingQueryTermVector() throws IOException { .query(boostingQuery(termQuery("field2", "brown"), termQuery("field2", "foobar")).negativeBoost(0.5f)) .highlighter(highlight().field("field2").order("score").preTags("").postTags("")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy dog")); } public void testCommonTermsQuery() { - createIndex("test"); + createIndex(INDEX); ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "this is a test", "field2", "The quick brown fox jumps over the lazy dog") .get(); refresh(); @@ -1335,15 +1410,15 @@ public void testCommonTermsQuery() { .query(commonTermsQuery("field2", "quick brown").cutoffFrequency(100)) .highlighter(highlight().field("field2").order("score").preTags("").postTags("")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy dog")); } public void testCommonTermsTermVector() throws IOException { - assertAcked(prepareCreate("test").addMapping("type1", type1TermVectorMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1TermVectorMapping())); ensureGreen(); - client().prepareIndex("test", "type1").setSource( + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE).setSource( "field1", "this is a test", "field2", "The quick brown fox jumps over the lazy dog").get(); refresh(); @@ -1351,7 +1426,7 @@ public void testCommonTermsTermVector() throws IOException { SearchSourceBuilder source = searchSource().query(commonTermsQuery("field2", "quick brown").cutoffFrequency(100)) .highlighter(highlight().field("field2").order("score").preTags("").postTags("")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy dog")); } @@ -1364,14 +1439,17 @@ public void testPhrasePrefix() throws IOException { .put("index.analysis.filter.synonym.type", "synonym") .putList("index.analysis.filter.synonym.synonyms", "quick => fast"); - assertAcked(prepareCreate("first_test_index").setSettings(builder.build()).addMapping("type1", type1TermVectorMapping())); + assertAcked(prepareCreate("first_test_index") + .setSettings(builder.build()) + .addMapping(INDEX_DOCUMENT_TYPE, + type1TermVectorMapping())); ensureGreen(); - client().prepareIndex("first_test_index", "type1", "0").setSource( + client().prepareIndex("first_test_index", INDEX_DOCUMENT_TYPE, "0").setSource( "field0", "The quick brown fox jumps over the lazy dog", "field1", "The quick brown fox jumps over the lazy dog").get(); - client().prepareIndex("first_test_index", "type1", "1").setSource("field1", + client().prepareIndex("first_test_index", INDEX_DOCUMENT_TYPE, "1").setSource("field1", "The quick browse button is a fancy thing, right bro?").get(); refresh(); logger.info("--> highlighting and searching on field0"); @@ -1468,16 +1546,16 @@ public void testPhrasePrefix() throws IOException { } public void testPlainHighlightDifferentFragmenter() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", "tags", "type=text")); + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, "tags", "type=text")); ensureGreen(); - client().prepareIndex("test", "type1", "1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1") .setSource(jsonBuilder().startObject().array("tags", "this is a really long tag i would like to highlight", "here is another one that is very long tag and has the tag token near the end").endObject()).get(); refresh(); - SearchResponse response = client().prepareSearch("test") + SearchResponse response = client().prepareSearch(INDEX) .setQuery(QueryBuilders.matchPhraseQuery("tags", "long tag")) .highlighter( new HighlightBuilder().field(new HighlightBuilder.Field("tags") @@ -1488,7 +1566,7 @@ public void testPlainHighlightDifferentFragmenter() throws Exception { assertHighlight(response, 0, "tags", 1, 2, equalTo("here is another one that is very long tag and has the tag token near the end")); - response = client().prepareSearch("test") + response = client().prepareSearch(INDEX) .setQuery(QueryBuilders.matchPhraseQuery("tags", "long tag")) .highlighter( new HighlightBuilder().field(new Field("tags").highlighterType("plain").fragmentSize(-1).numOfFragments(2) @@ -1499,7 +1577,7 @@ public void testPlainHighlightDifferentFragmenter() throws Exception { assertHighlight(response, 0, "tags", 1, 2, equalTo("here is another one that is very long tag and has the tag token near the end")); - assertFailures(client().prepareSearch("test") + assertFailures(client().prepareSearch(INDEX) .setQuery(QueryBuilders.matchPhraseQuery("tags", "long tag")) .highlighter( new HighlightBuilder().field(new Field("tags").highlighterType("plain").fragmentSize(-1).numOfFragments(2) @@ -1509,13 +1587,13 @@ public void testPlainHighlightDifferentFragmenter() throws Exception { } public void testPlainHighlighterMultipleFields() { - createIndex("test"); + createIndex(INDEX); ensureGreen(); - index("test", "type1", "1", "field1", "The quick brown fox", "field2", "The slow brown fox"); + index(INDEX, INDEX_DOCUMENT_TYPE, "1", "field1", "The quick brown fox", "field2", "The slow brown fox"); refresh(); - SearchResponse response = client().prepareSearch("test") + SearchResponse response = client().prepareSearch(INDEX) .setQuery(QueryBuilders.matchQuery("field1", "fox")) .highlighter( new HighlightBuilder().field( @@ -1527,15 +1605,15 @@ public void testPlainHighlighterMultipleFields() { } public void testFastVectorHighlighterMultipleFields() { - assertAcked(prepareCreate("test").addMapping("type1", + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, "field1", "type=text,term_vector=with_positions_offsets", "field2", "type=text,term_vector=with_positions_offsets")); ensureGreen(); - index("test", "type1", "1", "field1", "The quick brown fox", "field2", "The slow brown fox"); + index(INDEX, INDEX_DOCUMENT_TYPE, "1", "field1", "The quick brown fox", "field2", "The slow brown fox"); refresh(); - SearchResponse response = client().prepareSearch("test") + SearchResponse response = client().prepareSearch(INDEX) .setQuery(QueryBuilders.matchQuery("field1", "fox")) .highlighter( new HighlightBuilder().field( @@ -1547,17 +1625,17 @@ public void testFastVectorHighlighterMultipleFields() { } public void testMissingStoredField() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", "highlight_field", "type=text,store=true")); + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, "highlight_field", "type=text,store=true")); ensureGreen(); - client().prepareIndex("test", "type1", "1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1") .setSource(jsonBuilder().startObject() .field("field", "highlight") .endObject()).get(); refresh(); // This query used to fail when the field to highlight was absent - SearchResponse response = client().prepareSearch("test") + SearchResponse response = client().prepareSearch(INDEX) .setQuery(QueryBuilders.matchQuery("field", "highlight")) .highlighter( new HighlightBuilder().field(new HighlightBuilder.Field("highlight_field").fragmentSize(-1).numOfFragments(1) @@ -1567,8 +1645,8 @@ public void testMissingStoredField() throws Exception { // Issue #3211 public void testNumericHighlighting() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("test", + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, "text", "type=text", "byte", "type=byte", "short", "type=short", @@ -1578,11 +1656,11 @@ public void testNumericHighlighting() throws Exception { "double", "type=double")); ensureGreen(); - client().prepareIndex("test", "test", "1").setSource("text", "elasticsearch test", + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1").setSource("text", "elasticsearch test", "byte", 25, "short", 42, "int", 100, "long", -1, "float", 3.2f, "double", 42.42).get(); refresh(); - SearchResponse response = client().prepareSearch("test") + SearchResponse response = client().prepareSearch(INDEX) .setQuery(QueryBuilders.matchQuery("text", "test")) .highlighter( new HighlightBuilder().field("text").field("byte").field("short").field("int").field("long").field("float") @@ -1595,19 +1673,19 @@ public void testNumericHighlighting() throws Exception { // Issue #3200 public void testResetTwice() throws Exception { - assertAcked(prepareCreate("test") + assertAcked(prepareCreate(INDEX) .setSettings(Settings.builder() .put(indexSettings()) .put("analysis.analyzer.my_analyzer.type", "pattern") .put("analysis.analyzer.my_analyzer.pattern", "\\s+") .build()) - .addMapping("type", "text", "type=text,analyzer=my_analyzer")); + .addMapping(INDEX_DOCUMENT_TYPE, "text", "type=text,analyzer=my_analyzer")); ensureGreen(); - client().prepareIndex("test", "type", "1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1") .setSource("text", "elasticsearch test").get(); refresh(); - SearchResponse response = client().prepareSearch("test") + SearchResponse response = client().prepareSearch(INDEX) .setQuery(QueryBuilders.matchQuery("text", "test")) .highlighter(new HighlightBuilder().field("text")).execute().actionGet(); // PatternAnalyzer will throw an exception if it is resetted twice @@ -1615,17 +1693,17 @@ public void testResetTwice() throws Exception { } public void testHighlightUsesHighlightQuery() throws IOException { - assertAcked(prepareCreate("test").addMapping("type1", "text", + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, "text", "type=text," + randomStoreField() + "term_vector=with_positions_offsets,index_options=offsets")); ensureGreen(); - index("test", "type1", "1", "text", "Testing the highlight query feature"); + index(INDEX, INDEX_DOCUMENT_TYPE, "1", "text", "Testing the highlight query feature"); refresh(); for (String type : ALL_TYPES) { HighlightBuilder.Field field = new HighlightBuilder.Field("text"); HighlightBuilder highlightBuilder = new HighlightBuilder().field(field).highlighterType(type); - SearchRequestBuilder search = client().prepareSearch("test").setQuery(QueryBuilders.matchQuery("text", "testing")) + SearchRequestBuilder search = client().prepareSearch(INDEX).setQuery(QueryBuilders.matchQuery("text", "testing")) .highlighter(highlightBuilder); Matcher searchQueryMatcher = equalTo("Testing the highlight query feature"); @@ -1636,7 +1714,7 @@ public void testHighlightUsesHighlightQuery() throws IOException { Matcher hlQueryMatcher = equalTo("Testing the highlight query feature"); field.highlightQuery(matchQuery("text", "query")); highlightBuilder = new HighlightBuilder().field(field); - search = client().prepareSearch("test").setQuery(QueryBuilders.matchQuery("text", "testing")).highlighter(highlightBuilder); + search = client().prepareSearch(INDEX).setQuery(QueryBuilders.matchQuery("text", "testing")).highlighter(highlightBuilder); response = search.get(); assertHighlight(response, 0, "text", 0, hlQueryMatcher); @@ -1656,12 +1734,12 @@ private static String randomStoreField() { } public void testHighlightNoMatchSize() throws IOException { - assertAcked(prepareCreate("test").addMapping("type1", "text", + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, "text", "type=text," + randomStoreField() + "term_vector=with_positions_offsets,index_options=offsets")); ensureGreen(); String text = "I am pretty long so some of me should get cut off. Second sentence"; - index("test", "type1", "1", "text", text); + index(INDEX, INDEX_DOCUMENT_TYPE, "1", "text", text); refresh(); // When you don't set noMatchSize you don't get any results if there isn't anything to highlight. @@ -1669,107 +1747,107 @@ public void testHighlightNoMatchSize() throws IOException { .fragmentSize(21) .numOfFragments(1) .highlighterType("plain"); - SearchResponse response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + SearchResponse response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); field.highlighterType("fvh"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); field.highlighterType("unified"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); // When noMatchSize is set to 0 you also shouldn't get any field.highlighterType("plain").noMatchSize(0); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); field.highlighterType("fvh"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); field.highlighterType("unified"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); // When noMatchSize is between 0 and the size of the string field.highlighterType("plain").noMatchSize(21); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo("I am pretty long so")); // The FVH also works but the fragment is longer than the plain highlighter because of boundary_max_scan field.highlighterType("fvh"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo("I am pretty long so some")); // Unified hl also works but the fragment is longer than the plain highlighter because of the boundary is the word field.highlighterType("unified"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo("I am pretty long so some")); // We can also ask for a fragment longer than the input string and get the whole string field.highlighterType("plain").noMatchSize(text.length() * 2); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo(text)); field.highlighterType("fvh"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo(text)); field.highlighterType("unified"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo(text)); // We can also ask for a fragment exactly the size of the input field and get the whole field field.highlighterType("plain").noMatchSize(text.length()); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo(text)); field.highlighterType("fvh"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo(text)); // unified hl returns the first sentence as the noMatchSize does not cross sentence boundary. field.highlighterType("unified"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo(text)); // You can set noMatchSize globally in the highlighter as well field.highlighterType("plain").noMatchSize(null); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field).noMatchSize(21)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field).noMatchSize(21)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo("I am pretty long so")); field.highlighterType("fvh"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field).noMatchSize(21)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field).noMatchSize(21)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo("I am pretty long so some")); field.highlighterType("unified"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field).noMatchSize(21)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field).noMatchSize(21)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo("I am pretty long so some")); // We don't break if noMatchSize is less than zero though field.highlighterType("plain").noMatchSize(randomIntBetween(Integer.MIN_VALUE, -1)); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); field.highlighterType("fvh"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); field.highlighterType("unified"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); } public void testHighlightNoMatchSizeWithMultivaluedFields() throws IOException { - assertAcked(prepareCreate("test").addMapping("type1", + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, "text", "type=text," + randomStoreField() + "term_vector=with_positions_offsets,index_options=offsets")); ensureGreen(); String text1 = "I am pretty long so some of me should get cut off. We'll see how that goes."; String text2 = "I am short"; - index("test", "type1", "1", "text", new String[] {text1, text2}); + index(INDEX, INDEX_DOCUMENT_TYPE, "1", "text", new String[] {text1, text2}); refresh(); // The no match fragment should come from the first value of a multi-valued field @@ -1778,82 +1856,82 @@ public void testHighlightNoMatchSizeWithMultivaluedFields() throws IOException { .numOfFragments(1) .highlighterType("plain") .noMatchSize(21); - SearchResponse response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + SearchResponse response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo("I am pretty long so")); field.highlighterType("fvh"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo("I am pretty long so some")); field.highlighterType("unified"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo("I am pretty long so some")); // And noMatchSize returns nothing when the first entry is empty string! - index("test", "type1", "2", "text", new String[] {"", text2}); + index(INDEX, INDEX_DOCUMENT_TYPE, "2", "text", new String[] {"", text2}); refresh(); - IdsQueryBuilder idsQueryBuilder = QueryBuilders.idsQuery("type1").addIds("2"); + IdsQueryBuilder idsQueryBuilder = QueryBuilders.idsQuery(INDEX_DOCUMENT_TYPE).addIds("2"); field.highlighterType("plain"); - response = client().prepareSearch("test") + response = client().prepareSearch(INDEX) .setQuery(idsQueryBuilder) .highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); field.highlighterType("fvh"); - response = client().prepareSearch("test") + response = client().prepareSearch(INDEX) .setQuery(idsQueryBuilder) .highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); // except for the unified highlighter which starts from the first string with actual content field.highlighterType("unified"); - response = client().prepareSearch("test") + response = client().prepareSearch(INDEX) .setQuery(idsQueryBuilder) .highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo("I am short")); // But if the field was actually empty then you should get no highlighting field - index("test", "type1", "3", "text", new String[] {}); + index(INDEX, INDEX_DOCUMENT_TYPE, "3", "text", new String[] {}); refresh(); - idsQueryBuilder = QueryBuilders.idsQuery("type1").addIds("3"); + idsQueryBuilder = QueryBuilders.idsQuery(INDEX_DOCUMENT_TYPE).addIds("3"); field.highlighterType("plain"); - response = client().prepareSearch("test") + response = client().prepareSearch(INDEX) .setQuery(idsQueryBuilder) .highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); field.highlighterType("fvh"); - response = client().prepareSearch("test") + response = client().prepareSearch(INDEX) .setQuery(idsQueryBuilder) .highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); field.highlighterType("unified"); - response = client().prepareSearch("test") + response = client().prepareSearch(INDEX) .setQuery(idsQueryBuilder) .highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); // Same for if the field doesn't even exist on the document - index("test", "type1", "4"); + index(INDEX, INDEX_DOCUMENT_TYPE, "4"); refresh(); - idsQueryBuilder = QueryBuilders.idsQuery("type1").addIds("4"); + idsQueryBuilder = QueryBuilders.idsQuery(INDEX_DOCUMENT_TYPE).addIds("4"); field.highlighterType("plain"); - response = client().prepareSearch("test") + response = client().prepareSearch(INDEX) .setQuery(idsQueryBuilder) .highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); field.highlighterType("fvh"); - response = client().prepareSearch("test") + response = client().prepareSearch(INDEX) .setQuery(idsQueryBuilder) .highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); field.highlighterType("unified"); - response = client().prepareSearch("test") + response = client().prepareSearch(INDEX) .setQuery(idsQueryBuilder) .highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "postings"); @@ -1862,27 +1940,27 @@ public void testHighlightNoMatchSizeWithMultivaluedFields() throws IOException { field = new HighlightBuilder.Field("unmapped") .highlighterType("plain") .noMatchSize(21); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); field.highlighterType("fvh"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); field.highlighterType("unified"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertNotHighlighted(response, 0, "text"); } public void testHighlightNoMatchSizeNumberOfFragments() throws IOException { - assertAcked(prepareCreate("test").addMapping("type1", + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, "text", "type=text," + randomStoreField() + "term_vector=with_positions_offsets,index_options=offsets")); ensureGreen(); String text1 = "This is the first sentence. This is the second sentence." + HighlightUtils.PARAGRAPH_SEPARATOR; String text2 = "This is the third sentence. This is the fourth sentence."; String text3 = "This is the fifth sentence"; - index("test", "type1", "1", "text", new String[] {text1, text2, text3}); + index(INDEX, INDEX_DOCUMENT_TYPE, "1", "text", new String[] {text1, text2, text3}); refresh(); // The no match fragment should come from the first value of a multi-valued field @@ -1891,17 +1969,17 @@ public void testHighlightNoMatchSizeNumberOfFragments() throws IOException { .numOfFragments(0) .highlighterType("plain") .noMatchSize(20); - SearchResponse response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + SearchResponse response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo("This is the first")); field.highlighterType("fvh"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo("This is the first sentence")); field.highlighterType("unified"); - response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 1, equalTo("This is the first sentence")); @@ -1909,21 +1987,21 @@ public void testHighlightNoMatchSizeNumberOfFragments() throws IOException { //if there's a match we only return the values with matches (whole value as number_of_fragments == 0) MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("text", "third fifth"); field.highlighterType("plain"); - response = client().prepareSearch("test").setQuery(queryBuilder).highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).setQuery(queryBuilder).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 2, equalTo("This is the third sentence. This is the fourth sentence.")); assertHighlight(response, 0, "text", 1, 2, equalTo("This is the fifth sentence")); field.highlighterType("fvh"); - response = client().prepareSearch("test").setQuery(queryBuilder).highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).setQuery(queryBuilder).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 2, equalTo("This is the third sentence. This is the fourth sentence.")); assertHighlight(response, 0, "text", 1, 2, equalTo("This is the fifth sentence")); field.highlighterType("unified"); - response = client().prepareSearch("test").setQuery(queryBuilder).highlighter(new HighlightBuilder().field(field)).get(); + response = client().prepareSearch(INDEX).setQuery(queryBuilder).highlighter(new HighlightBuilder().field(field)).get(); assertHighlight(response, 0, "text", 0, 2, equalTo("This is the third sentence. This is the fourth sentence.")); assertHighlight(response, 0, "text", 1, 2, @@ -1931,10 +2009,10 @@ public void testHighlightNoMatchSizeNumberOfFragments() throws IOException { } public void testPostingsHighlighter() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "this is a test", "field2", "The quick brown fox jumps over the lazy quick dog").get(); refresh(); @@ -1942,7 +2020,7 @@ public void testPostingsHighlighter() throws Exception { SearchSourceBuilder source = searchSource() .query(termQuery("field1", "test")) .highlighter(highlight().field("field1").preTags("").postTags("")); - SearchResponse searchResponse = client().search(searchRequest("test").source(source)).actionGet(); + SearchResponse searchResponse = client().search(searchRequest(INDEX).source(source)).actionGet(); assertHighlight(searchResponse, 0, "field1", 0, 1, equalTo("this is a test")); @@ -1951,7 +2029,7 @@ public void testPostingsHighlighter() throws Exception { .query(termQuery("field1", "test")) .highlighter(highlight().field("field1").preTags("").postTags("")); - searchResponse = client().search(searchRequest("test").source(source)).actionGet(); + searchResponse = client().search(searchRequest(INDEX).source(source)).actionGet(); assertHighlight(searchResponse, 0, "field1", 0, 1, equalTo("this is a test")); @@ -1960,7 +2038,7 @@ public void testPostingsHighlighter() throws Exception { .query(termQuery("field2", "quick")) .highlighter(highlight().field("field2").order("score").preTags("").postTags("")); - searchResponse = client().search(searchRequest("test").source(source)).actionGet(); + searchResponse = client().search(searchRequest(INDEX).source(source)).actionGet(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy quick dog")); @@ -1970,7 +2048,7 @@ public void testPostingsHighlighter() throws Exception { .query(matchPhraseQuery("field2", "quick brown")) .highlighter(highlight().field("field2").preTags("").postTags("")); - searchResponse = client().search(searchRequest("test").source(source)).actionGet(); + searchResponse = client().search(searchRequest(INDEX).source(source)).actionGet(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy quick dog")); @@ -1982,22 +2060,22 @@ public void testPostingsHighlighter() throws Exception { .highlighter(highlight() .field("field2").preTags("").postTags("").highlighterType("plain").requireFieldMatch(false)); - searchResponse = client().search(searchRequest("test").source(source)).actionGet(); + searchResponse = client().search(searchRequest(INDEX).source(source)).actionGet(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy quick dog")); } public void testPostingsHighlighterMultipleFields() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping()).get()); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping()).get()); ensureGreen(); - index("test", "type1", "1", + index(INDEX, INDEX_DOCUMENT_TYPE, "1", "field1", "The quick brown fox. Second sentence.", "field2", "The slow brown fox. Second sentence."); refresh(); - SearchResponse response = client().prepareSearch("test") + SearchResponse response = client().prepareSearch(INDEX) .setQuery(QueryBuilders.matchQuery("field1", "fox")) .highlighter( new HighlightBuilder().field(new Field("field1").preTags("<1>").postTags("") @@ -2008,10 +2086,10 @@ public void testPostingsHighlighterMultipleFields() throws Exception { } public void testPostingsHighlighterNumberOfFragments() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1", "1").setSource( + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1").setSource( "field1", "The quick brown fox jumps over the lazy dog. The lazy red fox jumps over the quick dog. " + "The quick brown dog jumps over the lazy fox.", "field2", "The quick brown fox jumps over the lazy dog. The lazy red fox jumps over the quick dog. " @@ -2023,9 +2101,9 @@ public void testPostingsHighlighterNumberOfFragments() throws Exception { SearchSourceBuilder source = searchSource() .query(termQuery("field1", "fox")) .highlighter(highlight() - .field(new Field("field1").numOfFragments(5).preTags("").postTags(""))); + .field(new Field("field1").numOfFragments(TITLE_AND_ATTACHMENT_DOCUMENT_COUNT).preTags("").postTags(""))); - SearchResponse searchResponse = client().search(searchRequest("test").source(source)).actionGet(); + SearchResponse searchResponse = client().search(searchRequest(INDEX).source(source)).actionGet(); assertThat(searchResponse.getHits().getHits().length, equalTo(1)); assertHighlight(searchResponse, 0, "field1", 0, 2, @@ -2034,7 +2112,7 @@ public void testPostingsHighlighterNumberOfFragments() throws Exception { assertHighlight(searchResponse, 0, "field1", 1, 2, equalTo("The quick brown dog jumps over the lazy fox.")); - client().prepareIndex("test", "type1", "2") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "2") .setSource("field1", new String[]{ "The quick brown fox jumps over the lazy dog. Second sentence not finished", "The lazy red fox jumps over the quick dog.", @@ -2046,7 +2124,7 @@ public void testPostingsHighlighterNumberOfFragments() throws Exception { .highlighter(highlight() .field(new Field("field1").numOfFragments(0).preTags("").postTags(""))); - searchResponse = client().search(searchRequest("test").source(source)).actionGet(); + searchResponse = client().search(searchRequest(INDEX).source(source)).actionGet(); assertHitCount(searchResponse, 2L); for (SearchHit searchHit : searchResponse.getHits()) { @@ -2069,7 +2147,7 @@ public void testPostingsHighlighterNumberOfFragments() throws Exception { } public void testMultiMatchQueryHighlight() throws IOException { - XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("type1") + XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE) .startObject("properties") .startObject("field1") .field("type", "text") @@ -2083,9 +2161,9 @@ public void testMultiMatchQueryHighlight() throws IOException { .endObject() .endObject() .endObject().endObject(); - assertAcked(prepareCreate("test").addMapping("type1", mapping)); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, mapping)); ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "The quick brown fox jumps over", "field2", "The quick brown fox jumps over").get(); refresh(); @@ -2102,7 +2180,7 @@ public void testMultiMatchQueryHighlight() throws IOException { .highlighterType(highlighterType) .field(new Field("field1").requireFieldMatch(true).preTags("").postTags(""))); logger.info("Running multi-match type: [{}] highlight with type: [{}]", matchQueryType, highlighterType); - SearchResponse searchResponse = client().search(searchRequest("test").source(source)).actionGet(); + SearchResponse searchResponse = client().search(searchRequest(INDEX).source(source)).actionGet(); assertHitCount(searchResponse, 1L); assertHighlight(searchResponse, 0, "field1", 0, anyOf(equalTo("The quick brown fox jumps over"), @@ -2111,10 +2189,10 @@ public void testMultiMatchQueryHighlight() throws IOException { } public void testPostingsHighlighterOrderByScore() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", new String[]{ "This sentence contains one match, not that short. This sentence contains two sentence matches. " + "This one contains no matches.", @@ -2129,7 +2207,7 @@ public void testPostingsHighlighterOrderByScore() throws Exception { .query(termQuery("field1", "sentence")) .highlighter(highlight().field("field1").order("score")); - SearchResponse searchResponse = client().search(searchRequest("test").source(source)).actionGet(); + SearchResponse searchResponse = client().search(searchRequest(INDEX).source(source)).actionGet(); Map highlightFieldMap = searchResponse.getHits().getAt(0).getHighlightFields(); assertThat(highlightFieldMap.size(), equalTo(1)); @@ -2147,30 +2225,30 @@ public void testPostingsHighlighterOrderByScore() throws Exception { } public void testPostingsHighlighterEscapeHtml() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", "title", "type=text," + randomStoreField() + "index_options=offsets")); + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, TITLE, "type=text," + randomStoreField() + "index_options=offsets")); - IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[5]; - for (int i = 0; i < 5; i++) { - indexRequestBuilders[i] = client().prepareIndex("test", "type1", Integer.toString(i)) - .setSource("title", "This is a html escaping highlighting test for *&? elasticsearch"); + IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[TITLE_AND_ATTACHMENT_DOCUMENT_COUNT]; + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + indexRequestBuilders[i] = client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, Integer.toString(i)) + .setSource(TITLE, "This is a html escaping highlighting test for *&? elasticsearch"); } indexRandom(true, indexRequestBuilders); SearchResponse searchResponse = client().prepareSearch() - .setQuery(matchQuery("title", "test")) - .highlighter(new HighlightBuilder().field("title").encoder("html")).get(); + .setQuery(matchQuery(TITLE, "test")) + .highlighter(new HighlightBuilder().field(TITLE).encoder("html")).get(); for (int i = 0; i < indexRequestBuilders.length; i++) { - assertHighlight(searchResponse, i, "title", 0, 1, + assertHighlight(searchResponse, i, TITLE, 0, 1, equalTo("This is a html escaping highlighting test for *&? elasticsearch")); } } public void testPostingsHighlighterMultiMapperWithStore() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties") - .startObject("title") + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE).startObject("properties") + .startObject(TITLE) .field("type", "text") .field("store", true) .field("index_options", "offsets") @@ -2185,19 +2263,19 @@ public void testPostingsHighlighterMultiMapperWithStore() throws Exception { .endObject() .endObject().endObject().endObject().endObject())); ensureGreen(); - client().prepareIndex("test", "type1", "1").setSource("title", "this is a test . Second sentence.").get(); + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1").setSource(TITLE, "this is a test . Second sentence.").get(); refresh(); // simple search on body with standard analyzer with a simple field query SearchResponse searchResponse = client().prepareSearch() //lets make sure we analyze the query and we highlight the resulting terms - .setQuery(matchQuery("title", "This is a Test")) - .highlighter(new HighlightBuilder().field("title")).get(); + .setQuery(matchQuery(TITLE, "This is a Test")) + .highlighter(new HighlightBuilder().field(TITLE)).get(); assertHitCount(searchResponse, 1L); SearchHit hit = searchResponse.getHits().getAt(0); //stopwords are not highlighted since not indexed - assertHighlight(hit, "title", 0, 1, equalTo("this is a test . Second sentence.")); + assertHighlight(hit, TITLE, 0, 1, equalTo("this is a test . Second sentence.")); // search on title.key and highlight on title searchResponse = client().prepareSearch() @@ -2211,9 +2289,9 @@ public void testPostingsHighlighterMultiMapperWithStore() throws Exception { } public void testPostingsHighlighterMultiMapperFromSource() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties") - .startObject("title") + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE).startObject("properties") + .startObject(TITLE) .field("type", "text") .field("store", false) .field("index_options", "offsets") @@ -2229,16 +2307,16 @@ public void testPostingsHighlighterMultiMapperFromSource() throws Exception { .endObject().endObject().endObject().endObject())); ensureGreen(); - client().prepareIndex("test", "type1", "1").setSource("title", "this is a test").get(); + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1").setSource(TITLE, "this is a test").get(); refresh(); // simple search on body with standard analyzer with a simple field query SearchResponse searchResponse = client().prepareSearch() - .setQuery(matchQuery("title", "this is a test")) - .highlighter(new HighlightBuilder().field("title")) + .setQuery(matchQuery(TITLE, "this is a test")) + .highlighter(new HighlightBuilder().field(TITLE)) .get(); - assertHighlight(searchResponse, 0, "title", 0, 1, equalTo("this is a test")); + assertHighlight(searchResponse, 0, TITLE, 0, 1, equalTo("this is a test")); // search on title.key and highlight on title.key searchResponse = client().prepareSearch() @@ -2249,30 +2327,30 @@ public void testPostingsHighlighterMultiMapperFromSource() throws Exception { } public void testPostingsHighlighterShouldFailIfNoOffsets() throws Exception { - assertAcked(prepareCreate("test") - .addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties") - .startObject("title").field("type", "text").field("store", true).field("index_options", "docs").endObject() + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE).startObject("properties") + .startObject(TITLE).field("type", "text").field("store", true).field("index_options", "docs").endObject() .endObject().endObject().endObject())); ensureGreen(); - IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[5]; + IndexRequestBuilder[] indexRequestBuilders = new IndexRequestBuilder[TITLE_AND_ATTACHMENT_DOCUMENT_COUNT]; for (int i = 0; i < indexRequestBuilders.length; i++) { - indexRequestBuilders[i] = client().prepareIndex("test", "type1", Integer.toString(i)) - .setSource("title", "This is a test for the postings highlighter"); + indexRequestBuilders[i] = client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, Integer.toString(i)) + .setSource(TITLE, "This is a test for the postings highlighter"); } indexRandom(true, indexRequestBuilders); SearchResponse search = client().prepareSearch() - .setQuery(matchQuery("title", "this is a test")) - .highlighter(new HighlightBuilder().field("title")) + .setQuery(matchQuery(TITLE, "this is a test")) + .highlighter(new HighlightBuilder().field(TITLE)) .get(); assertNoFailures(search); } public void testPostingsHighlighterBoostingQuery() throws IOException { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "this is a test", "field2", "The quick brown fox jumps over the lazy dog! Second sentence.").get(); refresh(); @@ -2280,24 +2358,24 @@ public void testPostingsHighlighterBoostingQuery() throws IOException { SearchSourceBuilder source = searchSource() .query(boostingQuery(termQuery("field2", "brown"), termQuery("field2", "foobar")).negativeBoost(0.5f)) .highlighter(highlight().field("field2").preTags("").postTags("")); - SearchResponse searchResponse = client().search(searchRequest("test").source(source)).actionGet(); + SearchResponse searchResponse = client().search(searchRequest(INDEX).source(source)).actionGet(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy dog! Second sentence.")); } public void testPostingsHighlighterCommonTermsQuery() throws IOException { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "this is a test", "field2", "The quick brown fox jumps over the lazy dog! Second sentence.").get(); refresh(); logger.info("--> highlighting and searching on field1"); SearchSourceBuilder source = searchSource().query(commonTermsQuery("field2", "quick brown").cutoffFrequency(100)) .highlighter(highlight().field("field2").preTags("").postTags("")); - SearchResponse searchResponse = client().search(searchRequest("test").source(source)).actionGet(); + SearchResponse searchResponse = client().search(searchRequest(INDEX).source(source)).actionGet(); assertHitCount(searchResponse, 1L); assertHighlight(searchResponse, 0, "field2", 0, 1, @@ -2305,7 +2383,7 @@ public void testPostingsHighlighterCommonTermsQuery() throws IOException { } private static XContentBuilder type1PostingsffsetsMapping() throws IOException { - return XContentFactory.jsonBuilder().startObject().startObject("type1") + return XContentFactory.jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE) .startObject("properties") .startObject("field1").field("type", "text").field("index_options", "offsets").endObject() .startObject("field2").field("type", "text").field("index_options", "offsets").endObject() @@ -2314,74 +2392,74 @@ private static XContentBuilder type1PostingsffsetsMapping() throws IOException { } public void testPostingsHighlighterPrefixQuery() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "this is a test", "field2", "The quick brown fox jumps over the lazy dog! Second sentence.").get(); refresh(); logger.info("--> highlighting and searching on field2"); SearchSourceBuilder source = searchSource().query(prefixQuery("field2", "qui")) .highlighter(highlight().field("field2")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy dog! Second sentence.")); } public void testPostingsHighlighterFuzzyQuery() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "this is a test", "field2", "The quick brown fox jumps over the lazy dog! Second sentence.").get(); refresh(); logger.info("--> highlighting and searching on field2"); SearchSourceBuilder source = searchSource().query(fuzzyQuery("field2", "quck")) .highlighter(highlight().field("field2")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy dog! Second sentence.")); } public void testPostingsHighlighterRegexpQuery() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "this is a test", "field2", "The quick brown fox jumps over the lazy dog! Second sentence.").get(); refresh(); logger.info("--> highlighting and searching on field2"); SearchSourceBuilder source = searchSource().query(regexpQuery("field2", "qu[a-l]+k")) .highlighter(highlight().field("field2")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy dog! Second sentence.")); } public void testPostingsHighlighterWildcardQuery() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "this is a test", "field2", "The quick brown fox jumps over the lazy dog! Second sentence.").get(); refresh(); logger.info("--> highlighting and searching on field2"); SearchSourceBuilder source = searchSource().query(wildcardQuery("field2", "qui*")) .highlighter(highlight().field("field2")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy dog! Second sentence.")); source = searchSource().query(wildcardQuery("field2", "qu*k")) .highlighter(highlight().field("field2")); - searchResponse = client().prepareSearch("test").setSource(source).get(); + searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHitCount(searchResponse, 1L); assertHighlight(searchResponse, 0, "field2", 0, 1, @@ -2389,55 +2467,55 @@ public void testPostingsHighlighterWildcardQuery() throws Exception { } public void testPostingsHighlighterTermRangeQuery() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1").setSource("field1", "this is a test", "field2", "aaab").get(); + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE).setSource("field1", "this is a test", "field2", "aaab").get(); refresh(); logger.info("--> highlighting and searching on field2"); SearchSourceBuilder source = searchSource().query(rangeQuery("field2").gte("aaaa").lt("zzzz")) .highlighter(highlight().field("field2")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("aaab")); } public void testPostingsHighlighterQueryString() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE) .setSource("field1", "this is a test", "field2", "The quick brown fox jumps over the lazy dog! Second sentence.").get(); refresh(); logger.info("--> highlighting and searching on field2"); SearchSourceBuilder source = searchSource().query(queryStringQuery("qui*").defaultField("field2")) .highlighter(highlight().field("field2")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy dog! Second sentence.")); } public void testPostingsHighlighterRegexpQueryWithinConstantScoreQuery() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1").setSource("field1", "The photography word will get highlighted").get(); + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE).setSource("field1", "The photography word will get highlighted").get(); refresh(); logger.info("--> highlighting and searching on field1"); SearchSourceBuilder source = searchSource().query(constantScoreQuery(regexpQuery("field1", "pho[a-z]+"))) .highlighter(highlight().field("field1")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field1", 0, 1, equalTo("The photography word will get highlighted")); } public void testPostingsHighlighterMultiTermQueryMultipleLevels() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1").setSource("field1", "The photography word will get highlighted").get(); + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE).setSource("field1", "The photography word will get highlighted").get(); refresh(); logger.info("--> highlighting and searching on field1"); @@ -2446,30 +2524,30 @@ public void testPostingsHighlighterMultiTermQueryMultipleLevels() throws Excepti .should(matchQuery("field1", "test")) .should(constantScoreQuery(queryStringQuery("field1:photo*")))) .highlighter(highlight().field("field1")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field1", 0, 1, equalTo("The photography word will get highlighted")); } public void testPostingsHighlighterPrefixQueryWithinBooleanQuery() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1").setSource("field1", "The photography word will get highlighted").get(); + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE).setSource("field1", "The photography word will get highlighted").get(); refresh(); logger.info("--> highlighting and searching on field1"); SearchSourceBuilder source = searchSource() .query(boolQuery().must(prefixQuery("field1", "photo")).should(matchQuery("field1", "test").minimumShouldMatch("0"))) .highlighter(highlight().field("field1")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field1", 0, 1, equalTo("The photography word will get highlighted")); } public void testPostingsHighlighterQueryStringWithinFilteredQuery() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); - client().prepareIndex("test", "type1").setSource("field1", "The photography word will get highlighted").get(); + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE).setSource("field1", "The photography word will get highlighted").get(); refresh(); logger.info("--> highlighting and searching on field1"); @@ -2477,12 +2555,12 @@ public void testPostingsHighlighterQueryStringWithinFilteredQuery() throws Excep .must(queryStringQuery("field1:photo*")) .mustNot(existsQuery("field_null"))) .highlighter(highlight().field("field1")); - SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get(); + SearchResponse searchResponse = client().prepareSearch(INDEX).setSource(source).get(); assertHighlight(searchResponse, 0, "field1", 0, 1, equalTo("The photography word will get highlighted")); } public void testPostingsHighlighterManyDocs() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1PostingsffsetsMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1PostingsffsetsMapping())); ensureGreen(); int COUNT = between(20, 100); @@ -2492,10 +2570,12 @@ public void testPostingsHighlighterManyDocs() throws Exception { for (int i = 0; i < COUNT; i++) { //generating text with word to highlight in a different position //(https://github.com/elastic/elasticsearch/issues/4103) - String prefix = randomAlphaOfLengthBetween(5, 30); + String prefix = randomAlphaOfLengthBetween(TITLE_AND_ATTACHMENT_DOCUMENT_COUNT, 30); prefixes.put(String.valueOf(i), prefix); - indexRequestBuilders[i] = client().prepareIndex("test", "type1", Integer.toString(i)).setSource("field1", "Sentence " + prefix - + " test. Sentence two."); + indexRequestBuilders[i] = client() + .prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, + Integer.toString(i)) + .setSource("field1", "Sentence " + prefix + " test. Sentence two."); } logger.info("--> indexing docs"); indexRandom(true, indexRequestBuilders); @@ -2516,44 +2596,49 @@ public void testPostingsHighlighterManyDocs() throws Exception { } public void testDoesNotHighlightTypeName() throws Exception { - XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("typename").startObject("properties") + XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE).startObject("properties") .startObject("foo").field("type", "text") .field("index_options", "offsets") .field("term_vector", "with_positions_offsets") .endObject().endObject().endObject().endObject(); - assertAcked(prepareCreate("test").addMapping("typename", mapping)); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, mapping)); ensureGreen(); - indexRandom(true, client().prepareIndex("test", "typename").setSource("foo", "test typename")); + indexRandom(true, client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE).setSource("foo", "test typename")); for (String highlighter : ALL_TYPES) { - SearchResponse response = client().prepareSearch("test").setTypes("typename").setQuery(matchQuery("foo", "test")) + SearchResponse response = client().prepareSearch(INDEX).setTypes(INDEX_DOCUMENT_TYPE).setQuery(matchQuery("foo", "test")) .highlighter(new HighlightBuilder().field("foo").highlighterType(highlighter).requireFieldMatch(false)).get(); assertHighlight(response, 0, "foo", 0, 1, equalTo("test typename")); } } public void testDoesNotHighlightAliasFilters() throws Exception { - XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("typename").startObject("properties") + XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE).startObject("properties") .startObject("foo").field("type", "text") .field("index_options", "offsets") .field("term_vector", "with_positions_offsets") .endObject().endObject().endObject().endObject(); - assertAcked(prepareCreate("test").addMapping("typename", mapping)); - assertAcked(client().admin().indices().prepareAliases().addAlias("test", "filtered_alias", matchQuery("foo", "japanese"))); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, mapping)); + assertAcked(client().admin().indices().prepareAliases().addAlias(INDEX, "filtered_alias", matchQuery("foo", "japanese"))); ensureGreen(); - indexRandom(true, client().prepareIndex("test", "typename").setSource("foo", "test japanese")); + indexRandom(true, client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE).setSource("foo", "test japanese")); for (String highlighter : ALL_TYPES) { - SearchResponse response = client().prepareSearch("filtered_alias").setTypes("typename").setQuery(matchQuery("foo", "test")) - .highlighter(new HighlightBuilder().field("foo").highlighterType(highlighter).requireFieldMatch(false)).get(); + SearchResponse response = client().prepareSearch("filtered_alias") + .setTypes(INDEX_DOCUMENT_TYPE) + .setQuery(matchQuery("foo", "test")) + .highlighter(new HighlightBuilder().field("foo") + .highlighterType(highlighter) + .requireFieldMatch(false)) + .get(); assertHighlight(response, 0, "foo", 0, 1, equalTo("test japanese")); } } public void testFastVectorHighlighterPhraseBoost() throws Exception { - assertAcked(prepareCreate("test").addMapping("type1", type1TermVectorMapping())); + assertAcked(prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, type1TermVectorMapping())); phraseBoostTestCase("fvh"); } @@ -2573,7 +2658,7 @@ private void phraseBoostTestCase(String highlighterType) { for (int i = 0; i<10; i++) { text.append("junk junk junk junk junk junk junk junk junk junk junk junk junk junk junk junk junk junk junk junk\n"); } - index("test", "type1", "1", "field1", text.toString()); + index(INDEX, INDEX_DOCUMENT_TYPE, "1", "field1", text.toString()); refresh(); // Match queries @@ -2606,7 +2691,7 @@ private void phraseBoostTestCase(String highlighterType) { phraseBoostTestCaseForClauses(String highlighterType, float boost, QueryBuilder terms, P phrase) { Matcher highlightedMatcher = Matchers.either(containsString("highlight words together")).or( containsString("highlight words together")); - SearchRequestBuilder search = client().prepareSearch("test").highlighter( + SearchRequestBuilder search = client().prepareSearch(INDEX).highlighter( new HighlightBuilder().field("field1", 100, 1).order("score").highlighterType(highlighterType).requireFieldMatch(true)); // Try with a bool query @@ -2628,7 +2713,7 @@ public void testGeoFieldHighlightingWithDifferentHighlighters() throws IOExcepti // see https://github.com/elastic/elasticsearch/issues/17537 XContentBuilder mappings = jsonBuilder(); mappings.startObject(); - mappings.startObject("type") + mappings.startObject(INDEX_DOCUMENT_TYPE) .startObject("properties") .startObject("geo_point") .field("type", "geo_point") @@ -2641,10 +2726,10 @@ public void testGeoFieldHighlightingWithDifferentHighlighters() throws IOExcepti .endObject() .endObject(); mappings.endObject(); - assertAcked(prepareCreate("test") - .addMapping("type", mappings)); + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, mappings)); - client().prepareIndex("test", "type", "1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1") .setSource(jsonBuilder().startObject().field("text", "Arbitrary text field which will should not cause a failure").endObject()) .get(); refresh(); @@ -2676,11 +2761,11 @@ public void testGeoFieldHighlightingWhenQueryGetsRewritten() throws IOException .endObject() .endObject(); mappings.endObject(); - assertAcked(prepareCreate("test") + assertAcked(prepareCreate(INDEX) .addMapping("jobs", mappings)); ensureYellow(); - client().prepareIndex("test", "jobs", "1") + client().prepareIndex(INDEX, "jobs", "1") .setSource(jsonBuilder().startObject().field("jd", "some आवश्यकता है- आर्य समाज अनाथालय, 68 सिविल लाइन्स, बरेली को एक पुरूष" + " रस text") .field("loc", "12.934059,77.610741").endObject()) @@ -2700,7 +2785,7 @@ public void testKeywordFieldHighlighting() throws IOException { // check that keyword highlighting works XContentBuilder mappings = jsonBuilder(); mappings.startObject(); - mappings.startObject("type") + mappings.startObject(INDEX_DOCUMENT_TYPE) .startObject("properties") .startObject("keyword_field") .field("type", "keyword") @@ -2708,10 +2793,10 @@ public void testKeywordFieldHighlighting() throws IOException { .endObject() .endObject(); mappings.endObject(); - assertAcked(prepareCreate("test") - .addMapping("type", mappings)); + assertAcked(prepareCreate(INDEX) + .addMapping(INDEX_DOCUMENT_TYPE, mappings)); - client().prepareIndex("test", "type", "1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1") .setSource(jsonBuilder().startObject().field("keyword_field", "some text").endObject()) .get(); refresh(); @@ -2725,7 +2810,7 @@ public void testKeywordFieldHighlighting() throws IOException { } public void testACopyFieldWithNestedQuery() throws Exception { - String mapping = Strings.toString(jsonBuilder().startObject().startObject("type").startObject("properties") + String mapping = Strings.toString(jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE).startObject("properties") .startObject("foo") .field("type", "nested") .startObject("properties") @@ -2741,9 +2826,9 @@ public void testACopyFieldWithNestedQuery() throws Exception { .field("store", true) .endObject() .endObject().endObject().endObject()); - prepareCreate("test").addMapping("type", mapping, XContentType.JSON).get(); + prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, mapping, XContentType.JSON).get(); - client().prepareIndex("test", "type", "1").setSource(jsonBuilder().startObject().startArray("foo") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1").setSource(jsonBuilder().startObject().startArray("foo") .startObject().field("text", "brown").endObject() .startObject().field("text", "cow").endObject() .endArray().endObject()) @@ -2764,7 +2849,7 @@ public void testACopyFieldWithNestedQuery() throws Exception { } public void testFunctionScoreQueryHighlight() throws Exception { - client().prepareIndex("test", "type", "1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1") .setSource(jsonBuilder().startObject().field("text", "brown").endObject()) .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) .get(); @@ -2781,7 +2866,7 @@ public void testFunctionScoreQueryHighlight() throws Exception { } public void testFiltersFunctionScoreQueryHighlight() throws Exception { - client().prepareIndex("test", "type", "1") + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1") .setSource(jsonBuilder().startObject().field("text", "brown").field("enable", "yes").endObject()) .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) .get(); @@ -2809,13 +2894,13 @@ public void testSynonyms() throws IOException { .put("index.analysis.filter.synonym.type", "synonym") .putList("index.analysis.filter.synonym.synonyms", "fast,quick"); - assertAcked(prepareCreate("test").setSettings(builder.build()) - .addMapping("type1", "field1", + assertAcked(prepareCreate(INDEX).setSettings(builder.build()) + .addMapping(INDEX_DOCUMENT_TYPE, "field1", "type=text,term_vector=with_positions_offsets,search_analyzer=synonym," + "analyzer=english,index_options=offsets")); ensureGreen(); - client().prepareIndex("test", "type1", "0").setSource( + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "0").setSource( "field1", "The quick brown fox jumps over the lazy dog").get(); refresh(); for (String highlighterType : ALL_TYPES) { @@ -2829,31 +2914,31 @@ public void testSynonyms() throws IOException { .preTags("") .postTags("") .highlighterType(highlighterType)); - SearchResponse searchResponse = client().search(searchRequest("test").source(source)).actionGet(); + SearchResponse searchResponse = client().search(searchRequest(INDEX).source(source)).actionGet(); assertHighlight(searchResponse, 0, "field1", 0, 1, equalTo("The quick brown fox jumps over the lazy dog")); source = searchSource() .query(matchQuery("field1", "fast brown fox").operator(Operator.AND)) .highlighter(highlight().field("field1").order("score").preTags("").postTags("")); - searchResponse = client().search(searchRequest("test").source(source)).actionGet(); + searchResponse = client().search(searchRequest(INDEX).source(source)).actionGet(); assertHighlight(searchResponse, 0, "field1", 0, 1, equalTo("The quick brown fox jumps over the lazy dog")); } } public void testHighlightQueryRewriteDatesWithNow() throws Exception { - assertAcked(client().admin().indices().prepareCreate("index-1").addMapping("type", "d", "type=date", + assertAcked(client().admin().indices().prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, "d", "type=date", "field", "type=text,store=true,term_vector=with_positions_offsets") .setSettings(Settings.builder().put("index.number_of_replicas", 0).put("index.number_of_shards", 2)) .get()); DateTime now = new DateTime(ISOChronology.getInstanceUTC()); - indexRandom(true, client().prepareIndex("index-1", "type", "1").setSource("d", now, "field", "hello world"), - client().prepareIndex("index-1", "type", "2").setSource("d", now.minusDays(1), "field", "hello"), - client().prepareIndex("index-1", "type", "3").setSource("d", now.minusDays(2), "field", "world")); - ensureSearchable("index-1"); - for (int i = 0; i < 5; i++) { - final SearchResponse r1 = client().prepareSearch("index-1") + indexRandom(true, client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1").setSource("d", now, "field", "hello world"), + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "2").setSource("d", now.minusDays(1), "field", "hello"), + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "3").setSource("d", now.minusDays(2), "field", "world")); + ensureSearchable(INDEX); + for (int i = 0; i < TITLE_AND_ATTACHMENT_DOCUMENT_COUNT; i++) { + final SearchResponse r1 = client().prepareSearch(INDEX) .addSort("d", SortOrder.DESC) .setTrackScores(true) .highlighter(highlight() @@ -2873,7 +2958,7 @@ public void testHighlightQueryRewriteDatesWithNow() throws Exception { } public void testWithNestedQuery() throws Exception { - String mapping = Strings.toString(jsonBuilder().startObject().startObject("type").startObject("properties") + String mapping = Strings.toString(jsonBuilder().startObject().startObject(INDEX_DOCUMENT_TYPE).startObject("properties") .startObject("text") .field("type", "text") .field("index_options", "offsets") @@ -2888,9 +2973,9 @@ public void testWithNestedQuery() throws Exception { .endObject() .endObject() .endObject().endObject().endObject()); - prepareCreate("test").addMapping("type", mapping, XContentType.JSON).get(); + prepareCreate(INDEX).addMapping(INDEX_DOCUMENT_TYPE, mapping, XContentType.JSON).get(); - client().prepareIndex("test", "type", "1").setSource(jsonBuilder().startObject() + client().prepareIndex(INDEX, INDEX_DOCUMENT_TYPE, "1").setSource(jsonBuilder().startObject() .startArray("foo") .startObject().field("text", "brown").endObject() .startObject().field("text", "cow").endObject() @@ -2953,12 +3038,12 @@ public void testWithNormalizer() throws Exception { .put(indexSettings()) .putList("index.analysis.normalizer.my_normalizer.filter", "lowercase"); - assertAcked(prepareCreate("test").setSettings(builder.build()) + assertAcked(prepareCreate(INDEX).setSettings(builder.build()) .addMapping("doc", "keyword", "type=keyword,normalizer=my_normalizer")); ensureGreen(); - client().prepareIndex("test", "doc", "0") + client().prepareIndex(INDEX, "doc", "0") .setSource("keyword", "Hello World") .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) .get(); diff --git a/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/PlainHighlighterTests.java b/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/PlainHighlighterTests.java index 18ba716f70cb2..feb649a8674b8 100644 --- a/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/PlainHighlighterTests.java +++ b/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/PlainHighlighterTests.java @@ -38,4 +38,9 @@ public void testHighlightPhrase() throws Exception { String[] frags = highlighter.getBestFragments(new MockAnalyzer(random()), "field", "bar foo bar foo", 10); assertArrayEquals(new String[] {"bar foo bar foo"}, frags); } + + public void testField() throws Exception { + //public HighlightField highlight(HighlighterContext highlighterContext) { + + } } diff --git a/server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java b/server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java index 163b9391a1b98..035b01f3699a4 100644 --- a/server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java @@ -32,6 +32,7 @@ import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested; import org.elasticsearch.index.mapper.KeywordFieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; +import org.elasticsearch.index.mapper.MapperTesting; import org.elasticsearch.index.mapper.TypeFieldMapper; import org.elasticsearch.index.query.MatchNoneQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; @@ -55,9 +56,12 @@ public class FieldSortBuilderTests extends AbstractSortTestCase