Dense vector field type minor fixes (#62631)

The dense vector field is not aggregatable although it produces fielddata through its BinaryDocValuesField. It should pass up hasDocValues set to true to its parent class in its constructor, and return isAggregatable false. Same for the sparse vector field (only in 7.x).

This may not have consequences today, but it will be important once we try to share the same exists query implementation throughout all of the mappers with #57607.
This commit is contained in:
Luca Cavanna 2020-09-22 10:40:51 +02:00 committed by GitHub
parent 593511e5c9
commit 9ae29713fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 168 additions and 67 deletions

View File

@ -23,7 +23,7 @@ import java.util.Collections;
public class RankFeatureFieldTypeTests extends FieldTypeTestCase { public class RankFeatureFieldTypeTests extends FieldTypeTestCase {
public void testIsAggregatable() { public void testIsNotAggregatable() {
MappedFieldType fieldType = new RankFeatureFieldMapper.RankFeatureFieldType("field", Collections.emptyMap(), true); MappedFieldType fieldType = new RankFeatureFieldMapper.RankFeatureFieldType("field", Collections.emptyMap(), true);
assertFalse(fieldType.isAggregatable()); assertFalse(fieldType.isAggregatable());
} }

View File

@ -23,7 +23,7 @@ import java.util.Collections;
public class RankFeaturesFieldTypeTests extends FieldTypeTestCase { public class RankFeaturesFieldTypeTests extends FieldTypeTestCase {
public void testIsAggregatable() { public void testIsNotAggregatable() {
MappedFieldType fieldType = new RankFeaturesFieldMapper.RankFeaturesFieldType("field", Collections.emptyMap()); MappedFieldType fieldType = new RankFeaturesFieldMapper.RankFeaturesFieldType("field", Collections.emptyMap());
assertFalse(fieldType.isAggregatable()); assertFalse(fieldType.isAggregatable());
} }

View File

@ -40,7 +40,6 @@ import java.util.Collections;
public class ScaledFloatFieldTypeTests extends FieldTypeTestCase { public class ScaledFloatFieldTypeTests extends FieldTypeTestCase {
public void testTermQuery() { public void testTermQuery() {
ScaledFloatFieldMapper.ScaledFloatFieldType ft ScaledFloatFieldMapper.ScaledFloatFieldType ft
= new ScaledFloatFieldMapper.ScaledFloatFieldType("scaled_float", 0.1 + randomDouble() * 100); = new ScaledFloatFieldMapper.ScaledFloatFieldType("scaled_float", 0.1 + randomDouble() * 100);

View File

@ -49,7 +49,7 @@ public class SearchAsYouTypeFieldTypeTests extends FieldTypeTestCase {
UNSEARCHABLE.freeze(); UNSEARCHABLE.freeze();
} }
protected SearchAsYouTypeFieldType createFieldType() { private static SearchAsYouTypeFieldType createFieldType() {
final SearchAsYouTypeFieldType fieldType = new SearchAsYouTypeFieldType(NAME, Defaults.FIELD_TYPE, null, final SearchAsYouTypeFieldType fieldType = new SearchAsYouTypeFieldType(NAME, Defaults.FIELD_TYPE, null,
Lucene.STANDARD_ANALYZER, Lucene.STANDARD_ANALYZER, Collections.emptyMap()); Lucene.STANDARD_ANALYZER, Lucene.STANDARD_ANALYZER, Collections.emptyMap());
fieldType.setPrefixField(new PrefixFieldType(NAME, TextSearchInfo.SIMPLE_MATCH_ONLY, Defaults.MIN_GRAM, Defaults.MAX_GRAM)); fieldType.setPrefixField(new PrefixFieldType(NAME, TextSearchInfo.SIMPLE_MATCH_ONLY, Defaults.MIN_GRAM, Defaults.MAX_GRAM));

View File

@ -42,8 +42,12 @@ public class CollationFieldTypeTests extends FieldTypeTestCase{
private static final Collator DEFAULT_COLLATOR = Collator.getInstance(ULocale.ROOT).freeze(); private static final Collator DEFAULT_COLLATOR = Collator.getInstance(ULocale.ROOT).freeze();
private static CollationFieldType createFieldType() {
return new CollationFieldType("field", DEFAULT_COLLATOR);
}
public void testIsFieldWithinQuery() throws IOException { public void testIsFieldWithinQuery() throws IOException {
CollationFieldType ft = new CollationFieldType("field", DEFAULT_COLLATOR); CollationFieldType ft = createFieldType();
// current impl ignores args and shourd always return INTERSECTS // current impl ignores args and shourd always return INTERSECTS
assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(null, assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(null,
RandomStrings.randomAsciiOfLengthBetween(random(), 0, 5), RandomStrings.randomAsciiOfLengthBetween(random(), 0, 5),
@ -89,38 +93,37 @@ public class CollationFieldTypeTests extends FieldTypeTestCase{
} }
public void testRegexpQuery() { public void testRegexpQuery() {
MappedFieldType ft = new CollationFieldType("field", DEFAULT_COLLATOR); MappedFieldType ft = createFieldType();
UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class, UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class,
() -> ft.regexpQuery("foo.*", 0, 0, 10, null, randomMockShardContext())); () -> ft.regexpQuery("foo.*", 0, 0, 10, null, randomMockShardContext()));
assertEquals("[regexp] queries are not supported on [icu_collation_keyword] fields.", e.getMessage()); assertEquals("[regexp] queries are not supported on [icu_collation_keyword] fields.", e.getMessage());
} }
public void testFuzzyQuery() { public void testFuzzyQuery() {
MappedFieldType ft = new CollationFieldType("field", DEFAULT_COLLATOR); MappedFieldType ft = createFieldType();
UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class, UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class,
() -> ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, randomMockShardContext())); () -> ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, randomMockShardContext()));
assertEquals("[fuzzy] queries are not supported on [icu_collation_keyword] fields.", e.getMessage()); assertEquals("[fuzzy] queries are not supported on [icu_collation_keyword] fields.", e.getMessage());
} }
public void testPrefixQuery() { public void testPrefixQuery() {
MappedFieldType ft = new CollationFieldType("field", DEFAULT_COLLATOR); MappedFieldType ft = createFieldType();
UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class, UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class,
() -> ft.prefixQuery("prefix", null, randomMockShardContext())); () -> ft.prefixQuery("prefix", null, randomMockShardContext()));
assertEquals("[prefix] queries are not supported on [icu_collation_keyword] fields.", e.getMessage()); assertEquals("[prefix] queries are not supported on [icu_collation_keyword] fields.", e.getMessage());
} }
public void testWildcardQuery() { public void testWildcardQuery() {
MappedFieldType ft = new CollationFieldType("field", DEFAULT_COLLATOR); MappedFieldType ft = createFieldType();
UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class, UnsupportedOperationException e = expectThrows(UnsupportedOperationException.class,
() -> ft.wildcardQuery("foo*", null, randomMockShardContext())); () -> ft.wildcardQuery("foo*", null, randomMockShardContext()));
assertEquals("[wildcard] queries are not supported on [icu_collation_keyword] fields.", e.getMessage()); assertEquals("[wildcard] queries are not supported on [icu_collation_keyword] fields.", e.getMessage());
} }
public void testRangeQuery() { public void testRangeQuery() {
Collator collator = DEFAULT_COLLATOR; MappedFieldType ft = createFieldType();
MappedFieldType ft = new CollationFieldType("field", collator); RawCollationKey aKey = DEFAULT_COLLATOR.getRawCollationKey("a", null);
RawCollationKey aKey = collator.getRawCollationKey("a", null); RawCollationKey bKey = DEFAULT_COLLATOR.getRawCollationKey("b", null);
RawCollationKey bKey = collator.getRawCollationKey("b", null);
TermRangeQuery expected = new TermRangeQuery("field", new BytesRef(aKey.bytes, 0, aKey.size), TermRangeQuery expected = new TermRangeQuery("field", new BytesRef(aKey.bytes, 0, aKey.size),
new BytesRef(bKey.bytes, 0, bKey.size), false, false); new BytesRef(bKey.bytes, 0, bKey.size), false, false);
@ -132,7 +135,7 @@ public class CollationFieldTypeTests extends FieldTypeTestCase{
assertEquals("[range] queries on [text] or [keyword] fields cannot be executed when " + assertEquals("[range] queries on [text] or [keyword] fields cannot be executed when " +
"'search.allow_expensive_queries' is set to false.", ee.getMessage()); "'search.allow_expensive_queries' is set to false.", ee.getMessage());
MappedFieldType unsearchable = new CollationFieldType("field", false, true, collator, Collections.emptyMap()); MappedFieldType unsearchable = new CollationFieldType("field", false, true, DEFAULT_COLLATOR, Collections.emptyMap());
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
() -> unsearchable.rangeQuery("a", "b", false, false, null, null, null, MOCK_QSC)); () -> unsearchable.rangeQuery("a", "b", false, false, null, null, null, MOCK_QSC));
assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage());

View File

@ -20,7 +20,6 @@
package org.elasticsearch.index.mapper; package org.elasticsearch.index.mapper;
import com.carrotsearch.randomizedtesting.generators.RandomPicks; import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import org.apache.lucene.document.Document; import org.apache.lucene.document.Document;
import org.apache.lucene.document.DoublePoint; import org.apache.lucene.document.DoublePoint;
import org.apache.lucene.document.FloatPoint; import org.apache.lucene.document.FloatPoint;

View File

@ -54,7 +54,6 @@ import static org.hamcrest.Matchers.instanceOf;
public class RangeFieldTypeTests extends FieldTypeTestCase { public class RangeFieldTypeTests extends FieldTypeTestCase {
RangeType type; RangeType type;
protected static String FIELDNAME = "field";
protected static int DISTANCE = 10; protected static int DISTANCE = 10;
private static long nowInMillis; private static long nowInMillis;
@ -64,16 +63,16 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
nowInMillis = randomNonNegativeLong(); nowInMillis = randomNonNegativeLong();
} }
protected RangeFieldType createDefaultFieldType(String name) { private RangeFieldType createDefaultFieldType() {
if (type == RangeType.DATE) { if (type == RangeType.DATE) {
return new RangeFieldType(name, true, true, RangeFieldMapper.Defaults.DATE_FORMATTER, Collections.emptyMap()); return new RangeFieldType("field", true, true, RangeFieldMapper.Defaults.DATE_FORMATTER, Collections.emptyMap());
} }
return new RangeFieldType(name, type, true, true, Collections.emptyMap()); return new RangeFieldType("field", type, true, true, Collections.emptyMap());
} }
public void testRangeQuery() throws Exception { public void testRangeQuery() throws Exception {
QueryShardContext context = createContext(); QueryShardContext context = createContext();
RangeFieldType ft = createDefaultFieldType(FIELDNAME); RangeFieldType ft = createDefaultFieldType();
ShapeRelation relation = randomFrom(ShapeRelation.values()); ShapeRelation relation = randomFrom(ShapeRelation.values());
boolean includeLower = randomBoolean(); boolean includeLower = randomBoolean();
@ -95,10 +94,10 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
public void testRangeQueryIntersectsAdjacentValues() throws Exception { public void testRangeQueryIntersectsAdjacentValues() throws Exception {
QueryShardContext context = createContext(); QueryShardContext context = createContext();
ShapeRelation relation = randomFrom(ShapeRelation.values()); ShapeRelation relation = randomFrom(ShapeRelation.values());
RangeFieldType ft = createDefaultFieldType(FIELDNAME); RangeFieldType ft = createDefaultFieldType();
Object from = null; Object from;
Object to = null; Object to;
switch (type) { switch (type) {
case LONG: { case LONG: {
long fromValue = randomLong(); long fromValue = randomLong();
@ -152,7 +151,7 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
*/ */
public void testFromLargerToErrors() throws Exception { public void testFromLargerToErrors() throws Exception {
QueryShardContext context = createContext(); QueryShardContext context = createContext();
RangeFieldType ft = createDefaultFieldType(FIELDNAME); RangeFieldType ft = createDefaultFieldType();
final Object from; final Object from;
final Object to; final Object to;
@ -217,7 +216,7 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
public void testDateRangeQueryUsingMappingFormat() { public void testDateRangeQueryUsingMappingFormat() {
QueryShardContext context = createContext(); QueryShardContext context = createContext();
RangeFieldType strict RangeFieldType strict
= new RangeFieldType(FIELDNAME, true, false, RangeFieldMapper.Defaults.DATE_FORMATTER, Collections.emptyMap()); = new RangeFieldType("field", true, false, RangeFieldMapper.Defaults.DATE_FORMATTER, Collections.emptyMap());
// don't use DISJOINT here because it doesn't work on date fields which we want to compare bounds with // don't use DISJOINT here because it doesn't work on date fields which we want to compare bounds with
ShapeRelation relation = randomValueOtherThan(ShapeRelation.DISJOINT,() -> randomFrom(ShapeRelation.values())); ShapeRelation relation = randomValueOtherThan(ShapeRelation.DISJOINT,() -> randomFrom(ShapeRelation.values()));
@ -236,13 +235,13 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
assertEquals(1465975790000L, formatter.parseMillis(from)); assertEquals(1465975790000L, formatter.parseMillis(from));
assertEquals(1466062190000L, formatter.parseMillis(to)); assertEquals(1466062190000L, formatter.parseMillis(to));
RangeFieldType fieldType = new RangeFieldType(FIELDNAME, true, true, formatter, Collections.emptyMap()); RangeFieldType fieldType = new RangeFieldType("field", true, true, formatter, Collections.emptyMap());
final Query query = fieldType.rangeQuery(from, to, true, true, relation, null, fieldType.dateMathParser(), context); final Query query = fieldType.rangeQuery(from, to, true, true, relation, null, fieldType.dateMathParser(), context);
assertEquals("field:<ranges:[1465975790000 : 1466062190999]>", query.toString()); assertEquals("field:<ranges:[1465975790000 : 1466062190999]>", query.toString());
// compare lower and upper bounds with what we would get on a `date` field // compare lower and upper bounds with what we would get on a `date` field
DateFieldType dateFieldType DateFieldType dateFieldType
= new DateFieldType(FIELDNAME, true, true, formatter, DateFieldMapper.Resolution.MILLISECONDS, Collections.emptyMap()); = new DateFieldType("field", true, true, formatter, DateFieldMapper.Resolution.MILLISECONDS, Collections.emptyMap());
final Query queryOnDateField = dateFieldType.rangeQuery(from, to, true, true, relation, null, fieldType.dateMathParser(), context); final Query queryOnDateField = dateFieldType.rangeQuery(from, to, true, true, relation, null, fieldType.dateMathParser(), context);
assertEquals("field:[1465975790000 TO 1466062190999]", queryOnDateField.toString()); assertEquals("field:[1465975790000 TO 1466062190999]", queryOnDateField.toString());
} }
@ -259,7 +258,7 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
long lower = randomLongBetween(formatter.parseMillis("2000-01-01T00:00"), formatter.parseMillis("2010-01-01T00:00")); long lower = randomLongBetween(formatter.parseMillis("2000-01-01T00:00"), formatter.parseMillis("2010-01-01T00:00"));
long upper = randomLongBetween(formatter.parseMillis("2011-01-01T00:00"), formatter.parseMillis("2020-01-01T00:00")); long upper = randomLongBetween(formatter.parseMillis("2011-01-01T00:00"), formatter.parseMillis("2020-01-01T00:00"));
RangeFieldType fieldType = new RangeFieldType(FIELDNAME, true, false, formatter, Collections.emptyMap()); RangeFieldType fieldType = new RangeFieldType("field", true, false, formatter, Collections.emptyMap());
String lowerAsString = formatter.formatMillis(lower); String lowerAsString = formatter.formatMillis(lower);
String upperAsString = formatter.formatMillis(upper); String upperAsString = formatter.formatMillis(upper);
// also add date math rounding to days occasionally // also add date math rounding to days occasionally
@ -286,7 +285,7 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
} }
// check that using this bounds we get similar query when constructing equivalent query on date_range field // check that using this bounds we get similar query when constructing equivalent query on date_range field
Query range = LongRange.newIntersectsQuery(FIELDNAME, new long[] { lowerBoundLong }, new long[] { upperBoundLong }); Query range = LongRange.newIntersectsQuery("field", new long[] { lowerBoundLong }, new long[] { upperBoundLong });
assertEquals(range, query); assertEquals(range, query);
} }
@ -313,16 +312,16 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
Query indexQuery; Query indexQuery;
BinaryDocValuesRangeQuery.QueryType queryType; BinaryDocValuesRangeQuery.QueryType queryType;
if (relation == ShapeRelation.WITHIN) { if (relation == ShapeRelation.WITHIN) {
indexQuery = LongRange.newWithinQuery(FIELDNAME, lower, upper); indexQuery = LongRange.newWithinQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN; queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN;
} else if (relation == ShapeRelation.CONTAINS) { } else if (relation == ShapeRelation.CONTAINS) {
indexQuery = LongRange.newContainsQuery(FIELDNAME, lower, upper); indexQuery = LongRange.newContainsQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS; queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS;
} else { } else {
indexQuery = LongRange.newIntersectsQuery(FIELDNAME, lower, upper); indexQuery = LongRange.newIntersectsQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS; queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS;
} }
Query dvQuery = RangeType.DATE.dvRangeQuery(FIELDNAME, queryType, from.getMillis(), Query dvQuery = RangeType.DATE.dvRangeQuery("field", queryType, from.getMillis(),
to.getMillis(), includeLower, includeUpper); to.getMillis(), includeLower, includeUpper);
return new IndexOrDocValuesQuery(indexQuery, dvQuery); return new IndexOrDocValuesQuery(indexQuery, dvQuery);
} }
@ -333,16 +332,16 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
Query indexQuery; Query indexQuery;
BinaryDocValuesRangeQuery.QueryType queryType; BinaryDocValuesRangeQuery.QueryType queryType;
if (relation == ShapeRelation.WITHIN) { if (relation == ShapeRelation.WITHIN) {
indexQuery = IntRange.newWithinQuery(FIELDNAME, lower, upper); indexQuery = IntRange.newWithinQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN; queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN;
} else if (relation == ShapeRelation.CONTAINS) { } else if (relation == ShapeRelation.CONTAINS) {
indexQuery = IntRange.newContainsQuery(FIELDNAME, lower, upper); indexQuery = IntRange.newContainsQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS; queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS;
} else { } else {
indexQuery = IntRange.newIntersectsQuery(FIELDNAME, lower, upper); indexQuery = IntRange.newIntersectsQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS; queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS;
} }
Query dvQuery = RangeType.INTEGER.dvRangeQuery(FIELDNAME, queryType, from, to, Query dvQuery = RangeType.INTEGER.dvRangeQuery("field", queryType, from, to,
includeLower, includeUpper); includeLower, includeUpper);
return new IndexOrDocValuesQuery(indexQuery, dvQuery); return new IndexOrDocValuesQuery(indexQuery, dvQuery);
} }
@ -353,16 +352,16 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
Query indexQuery; Query indexQuery;
BinaryDocValuesRangeQuery.QueryType queryType; BinaryDocValuesRangeQuery.QueryType queryType;
if (relation == ShapeRelation.WITHIN) { if (relation == ShapeRelation.WITHIN) {
indexQuery = LongRange.newWithinQuery(FIELDNAME, lower, upper); indexQuery = LongRange.newWithinQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN; queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN;
} else if (relation == ShapeRelation.CONTAINS) { } else if (relation == ShapeRelation.CONTAINS) {
indexQuery = LongRange.newContainsQuery(FIELDNAME, lower, upper); indexQuery = LongRange.newContainsQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS; queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS;
} else { } else {
indexQuery = LongRange.newIntersectsQuery(FIELDNAME, lower, upper); indexQuery = LongRange.newIntersectsQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS; queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS;
} }
Query dvQuery = RangeType.LONG.dvRangeQuery(FIELDNAME, queryType, from, to, Query dvQuery = RangeType.LONG.dvRangeQuery("field", queryType, from, to,
includeLower, includeUpper); includeLower, includeUpper);
return new IndexOrDocValuesQuery(indexQuery, dvQuery); return new IndexOrDocValuesQuery(indexQuery, dvQuery);
} }
@ -373,16 +372,16 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
Query indexQuery; Query indexQuery;
BinaryDocValuesRangeQuery.QueryType queryType; BinaryDocValuesRangeQuery.QueryType queryType;
if (relation == ShapeRelation.WITHIN) { if (relation == ShapeRelation.WITHIN) {
indexQuery = FloatRange.newWithinQuery(FIELDNAME, lower, upper); indexQuery = FloatRange.newWithinQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN; queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN;
} else if (relation == ShapeRelation.CONTAINS) { } else if (relation == ShapeRelation.CONTAINS) {
indexQuery = FloatRange.newContainsQuery(FIELDNAME, lower, upper); indexQuery = FloatRange.newContainsQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS; queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS;
} else { } else {
indexQuery = FloatRange.newIntersectsQuery(FIELDNAME, lower, upper); indexQuery = FloatRange.newIntersectsQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS; queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS;
} }
Query dvQuery = RangeType.FLOAT.dvRangeQuery(FIELDNAME, queryType, from, to, Query dvQuery = RangeType.FLOAT.dvRangeQuery("field", queryType, from, to,
includeLower, includeUpper); includeLower, includeUpper);
return new IndexOrDocValuesQuery(indexQuery, dvQuery); return new IndexOrDocValuesQuery(indexQuery, dvQuery);
} }
@ -394,16 +393,16 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
Query indexQuery; Query indexQuery;
BinaryDocValuesRangeQuery.QueryType queryType; BinaryDocValuesRangeQuery.QueryType queryType;
if (relation == ShapeRelation.WITHIN) { if (relation == ShapeRelation.WITHIN) {
indexQuery = DoubleRange.newWithinQuery(FIELDNAME, lower, upper); indexQuery = DoubleRange.newWithinQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN; queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN;
} else if (relation == ShapeRelation.CONTAINS) { } else if (relation == ShapeRelation.CONTAINS) {
indexQuery = DoubleRange.newContainsQuery(FIELDNAME, lower, upper); indexQuery = DoubleRange.newContainsQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS; queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS;
} else { } else {
indexQuery = DoubleRange.newIntersectsQuery(FIELDNAME, lower, upper); indexQuery = DoubleRange.newIntersectsQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS; queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS;
} }
Query dvQuery = RangeType.DOUBLE.dvRangeQuery(FIELDNAME, queryType, from, to, Query dvQuery = RangeType.DOUBLE.dvRangeQuery("field", queryType, from, to,
includeLower, includeUpper); includeLower, includeUpper);
return new IndexOrDocValuesQuery(indexQuery, dvQuery); return new IndexOrDocValuesQuery(indexQuery, dvQuery);
} }
@ -415,16 +414,16 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
Query indexQuery; Query indexQuery;
BinaryDocValuesRangeQuery.QueryType queryType; BinaryDocValuesRangeQuery.QueryType queryType;
if (relation == ShapeRelation.WITHIN) { if (relation == ShapeRelation.WITHIN) {
indexQuery = InetAddressRange.newWithinQuery(FIELDNAME, lower, upper); indexQuery = InetAddressRange.newWithinQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN; queryType = BinaryDocValuesRangeQuery.QueryType.WITHIN;
} else if (relation == ShapeRelation.CONTAINS) { } else if (relation == ShapeRelation.CONTAINS) {
indexQuery = InetAddressRange.newContainsQuery(FIELDNAME, lower, upper); indexQuery = InetAddressRange.newContainsQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS; queryType = BinaryDocValuesRangeQuery.QueryType.CONTAINS;
} else { } else {
indexQuery = InetAddressRange.newIntersectsQuery(FIELDNAME, lower, upper); indexQuery = InetAddressRange.newIntersectsQuery("field", lower, upper);
queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS; queryType = BinaryDocValuesRangeQuery.QueryType.INTERSECTS;
} }
Query dvQuery = RangeType.IP.dvRangeQuery(FIELDNAME, queryType, from, to, Query dvQuery = RangeType.IP.dvRangeQuery("field", queryType, from, to,
includeLower, includeUpper); includeLower, includeUpper);
return new IndexOrDocValuesQuery(indexQuery, dvQuery); return new IndexOrDocValuesQuery(indexQuery, dvQuery);
} }
@ -472,7 +471,7 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {
public void testTermQuery() throws Exception { public void testTermQuery() throws Exception {
// See https://github.com/elastic/elasticsearch/issues/25950 // See https://github.com/elastic/elasticsearch/issues/25950
QueryShardContext context = createContext(); QueryShardContext context = createContext();
RangeFieldType ft = createDefaultFieldType(FIELDNAME); RangeFieldType ft = createDefaultFieldType();
Object value = nextFrom(); Object value = nextFrom();
ShapeRelation relation = ShapeRelation.INTERSECTS; ShapeRelation relation = ShapeRelation.INTERSECTS;

View File

@ -49,8 +49,19 @@ import static org.hamcrest.Matchers.equalTo;
public class TextFieldTypeTests extends FieldTypeTestCase { public class TextFieldTypeTests extends FieldTypeTestCase {
private static TextFieldType createFieldType() {
return new TextFieldType("field");
}
public void testIsAggregatableDependsOnFieldData() {
TextFieldType ft = createFieldType();
assertFalse(ft.isAggregatable());
ft.setFielddata(true);
assertTrue(ft.isAggregatable());
}
public void testTermQuery() { public void testTermQuery() {
MappedFieldType ft = new TextFieldType("field"); MappedFieldType ft = createFieldType();
assertEquals(new TermQuery(new Term("field", "foo")), ft.termQuery("foo", null)); assertEquals(new TermQuery(new Term("field", "foo")), ft.termQuery("foo", null));
MappedFieldType unsearchable = new TextFieldType("field", false, Collections.emptyMap()); MappedFieldType unsearchable = new TextFieldType("field", false, Collections.emptyMap());
@ -60,7 +71,7 @@ public class TextFieldTypeTests extends FieldTypeTestCase {
} }
public void testTermsQuery() { public void testTermsQuery() {
MappedFieldType ft = new TextFieldType("field"); MappedFieldType ft = createFieldType();
List<BytesRef> terms = new ArrayList<>(); List<BytesRef> terms = new ArrayList<>();
terms.add(new BytesRef("foo")); terms.add(new BytesRef("foo"));
terms.add(new BytesRef("bar")); terms.add(new BytesRef("bar"));
@ -74,7 +85,7 @@ public class TextFieldTypeTests extends FieldTypeTestCase {
} }
public void testRangeQuery() { public void testRangeQuery() {
MappedFieldType ft = new TextFieldType("field"); MappedFieldType ft = createFieldType();
assertEquals(new TermRangeQuery("field", BytesRefs.toBytesRef("foo"), BytesRefs.toBytesRef("bar"), true, false), assertEquals(new TermRangeQuery("field", BytesRefs.toBytesRef("foo"), BytesRefs.toBytesRef("bar"), true, false),
ft.rangeQuery("foo", "bar", true, false, null, null, null, MOCK_QSC)); ft.rangeQuery("foo", "bar", true, false, null, null, null, MOCK_QSC));
@ -85,7 +96,7 @@ public class TextFieldTypeTests extends FieldTypeTestCase {
} }
public void testRegexpQuery() { public void testRegexpQuery() {
MappedFieldType ft = new TextFieldType("field"); MappedFieldType ft = createFieldType();
assertEquals(new RegexpQuery(new Term("field","foo.*")), assertEquals(new RegexpQuery(new Term("field","foo.*")),
ft.regexpQuery("foo.*", 0, 0, 10, null, MOCK_QSC)); ft.regexpQuery("foo.*", 0, 0, 10, null, MOCK_QSC));
@ -101,7 +112,7 @@ public class TextFieldTypeTests extends FieldTypeTestCase {
} }
public void testFuzzyQuery() { public void testFuzzyQuery() {
MappedFieldType ft = new TextFieldType("field"); MappedFieldType ft = createFieldType();
assertEquals(new FuzzyQuery(new Term("field","foo"), 2, 1, 50, true), assertEquals(new FuzzyQuery(new Term("field","foo"), 2, 1, 50, true),
ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, MOCK_QSC)); ft.fuzzyQuery("foo", Fuzziness.fromEdits(2), 1, 50, true, MOCK_QSC));
@ -118,7 +129,7 @@ public class TextFieldTypeTests extends FieldTypeTestCase {
} }
public void testIndexPrefixes() { public void testIndexPrefixes() {
TextFieldType ft = new TextFieldType("field"); TextFieldType ft = createFieldType();
ft.setPrefixFieldType(new TextFieldMapper.PrefixFieldType(ft, "field._index_prefix", 2, 10, true)); ft.setPrefixFieldType(new TextFieldMapper.PrefixFieldType(ft, "field._index_prefix", 2, 10, true));
Query q = ft.prefixQuery("goin", CONSTANT_SCORE_REWRITE, randomMockShardContext()); Query q = ft.prefixQuery("goin", CONSTANT_SCORE_REWRITE, randomMockShardContext());

View File

@ -39,5 +39,4 @@ public abstract class FieldTypeTestCase extends ESTestCase {
when(queryShardContext.allowExpensiveQueries()).thenReturn(allowExpensiveQueries); when(queryShardContext.allowExpensiveQueries()).thenReturn(allowExpensiveQueries);
return queryShardContext; return queryShardContext;
} }
} }

View File

@ -25,7 +25,7 @@ import java.util.List;
public class KeyedFlatObjectFieldTypeTests extends FieldTypeTestCase { public class KeyedFlatObjectFieldTypeTests extends FieldTypeTestCase {
protected KeyedFlatObjectFieldType createFieldType() { private static KeyedFlatObjectFieldType createFieldType() {
return new KeyedFlatObjectFieldType("field", true, true, "key", false, Collections.emptyMap()); return new KeyedFlatObjectFieldType("field", true, true, "key", false, Collections.emptyMap());
} }

View File

@ -25,7 +25,7 @@ import java.util.Collections;
public class RootFlatObjectFieldTypeTests extends FieldTypeTestCase { public class RootFlatObjectFieldTypeTests extends FieldTypeTestCase {
protected RootFlatObjectFieldType createDefaultFieldType() { private static RootFlatObjectFieldType createDefaultFieldType() {
return new RootFlatObjectFieldType("field", true, true, Collections.emptyMap(), false); return new RootFlatObjectFieldType("field", true, true, Collections.emptyMap(), false);
} }

View File

@ -105,7 +105,7 @@ public class DenseVectorFieldMapper extends FieldMapper {
private final int dims; private final int dims;
public DenseVectorFieldType(String name, int dims, Map<String, String> meta) { public DenseVectorFieldType(String name, int dims, Map<String, String> meta) {
super(name, false, false, TextSearchInfo.NONE, meta); super(name, false, true, TextSearchInfo.NONE, meta);
this.dims = dims; this.dims = dims;
} }
@ -129,6 +129,11 @@ public class DenseVectorFieldMapper extends FieldMapper {
return new DocValuesFieldExistsQuery(name()); return new DocValuesFieldExistsQuery(name());
} }
@Override
public boolean isAggregatable() {
return false;
}
@Override @Override
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier<SearchLookup> searchLookup) { public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName, Supplier<SearchLookup> searchLookup) {
return new VectorIndexFieldData.Builder(name(), true, CoreValuesSourceType.BYTES); return new VectorIndexFieldData.Builder(name(), true, CoreValuesSourceType.BYTES);
@ -230,7 +235,7 @@ public class DenseVectorFieldMapper extends FieldMapper {
@Override @Override
protected boolean docValuesByDefault() { protected boolean docValuesByDefault() {
return false; return true;
} }
@Override @Override

View File

@ -90,7 +90,7 @@ public class SparseVectorFieldMapper extends FieldMapper {
public static final class SparseVectorFieldType extends MappedFieldType { public static final class SparseVectorFieldType extends MappedFieldType {
public SparseVectorFieldType(String name, Map<String, String> meta) { public SparseVectorFieldType(String name, Map<String, String> meta) {
super(name, false, false, TextSearchInfo.NONE, meta); super(name, false, true, TextSearchInfo.NONE, meta);
} }
@Override @Override
@ -114,6 +114,11 @@ public class SparseVectorFieldMapper extends FieldMapper {
return new VectorIndexFieldData.Builder(name(), false, CoreValuesSourceType.BYTES); return new VectorIndexFieldData.Builder(name(), false, CoreValuesSourceType.BYTES);
} }
@Override
public boolean isAggregatable() {
return false;
}
@Override @Override
public Query termQuery(Object value, QueryShardContext context) { public Query termQuery(Object value, QueryShardContext context) {
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
@ -193,7 +198,7 @@ public class SparseVectorFieldMapper extends FieldMapper {
@Override @Override
protected boolean docValuesByDefault() { protected boolean docValuesByDefault() {
return false; return true;
} }
@Override @Override

View File

@ -0,0 +1,36 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.vectors.mapper;
import org.elasticsearch.index.mapper.FieldTypeTestCase;
import java.util.Collections;
public class DenseVectorFieldTypeTests extends FieldTypeTestCase {
public void testHasDocValues() {
DenseVectorFieldMapper.DenseVectorFieldType ft = new DenseVectorFieldMapper.DenseVectorFieldType("f", 1, Collections.emptyMap());
assertTrue(ft.hasDocValues());
}
public void testIsAggregatable() {
DenseVectorFieldMapper.DenseVectorFieldType ft = new DenseVectorFieldMapper.DenseVectorFieldType("f", 1, Collections.emptyMap());
assertFalse(ft.isAggregatable());
}
public void testFielddataBuilder() {
DenseVectorFieldMapper.DenseVectorFieldType ft = new DenseVectorFieldMapper.DenseVectorFieldType("f", 1, Collections.emptyMap());
assertNotNull(ft.fielddataBuilder("index", () -> {
throw new UnsupportedOperationException();
}));
}
public void testDocValueFormat() {
DenseVectorFieldMapper.DenseVectorFieldType ft = new DenseVectorFieldMapper.DenseVectorFieldType("f", 1, Collections.emptyMap());
expectThrows(UnsupportedOperationException.class, () -> ft.docValueFormat(null, null));
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.vectors.mapper;
import org.elasticsearch.index.mapper.FieldTypeTestCase;
import org.elasticsearch.index.mapper.MappedFieldType;
import java.util.Collections;
public class SparseVectorFieldTypeTests extends FieldTypeTestCase {
public void testHasDocValues() {
MappedFieldType fieldType = new SparseVectorFieldMapper.SparseVectorFieldType("field", Collections.emptyMap());
assertTrue(fieldType.hasDocValues());
}
public void testFielddataBuilder() {
MappedFieldType fieldType = new SparseVectorFieldMapper.SparseVectorFieldType("field", Collections.emptyMap());
assertNotNull(fieldType.fielddataBuilder("index", () -> {
throw new UnsupportedOperationException();
}));
}
public void testIsNotAggregatable() {
MappedFieldType fieldType = new SparseVectorFieldMapper.SparseVectorFieldType("field", Collections.emptyMap());
assertFalse(fieldType.isAggregatable());
}
public void testDocValueFormatIsNotSupported() {
MappedFieldType fieldType = new SparseVectorFieldMapper.SparseVectorFieldType("field", Collections.emptyMap());
UnsupportedOperationException exc = expectThrows(UnsupportedOperationException.class, () -> fieldType.docValueFormat(null, null));
assertEquals("Field [field] of type [sparse_vector] doesn't support docvalue_fields or aggregations", exc.getMessage());
}
public void testTermQueryIsNotSupported() {
MappedFieldType fieldType = new SparseVectorFieldMapper.SparseVectorFieldType("field", Collections.emptyMap());
UnsupportedOperationException exc = expectThrows(UnsupportedOperationException.class, () -> fieldType.termQuery(null, null));
assertEquals("Field [field] of type [sparse_vector] doesn't support queries", exc.getMessage());
}
}