Fix the MapperFieldType.rangeQuery API. (#26552)

RangeQueryBuilder needs to perform too many `instanceof` checks in order to
check for `date` or `range` fields in order to know what it should do with the
shape relation, time zone and date format.

This commit adds those 3 parameters to the `rangeQuery` factory method so that
those instanceof checks are not necessary anymore.
This commit is contained in:
Adrien Grand 2017-09-11 11:02:05 +02:00 committed by GitHub
parent 2bc3eeccde
commit 1adee8b5a8
20 changed files with 205 additions and 136 deletions

View File

@ -33,6 +33,7 @@ import org.apache.lucene.util.BytesRef;
import org.elasticsearch.Version;
import org.elasticsearch.common.Explicit;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.joda.Joda;
@ -246,7 +247,7 @@ public class DateFieldMapper extends FieldMapper {
@Override
public Query termQuery(Object value, @Nullable QueryShardContext context) {
Query query = innerRangeQuery(value, value, true, true, null, null, context);
Query query = rangeQuery(value, value, true, true, ShapeRelation.INTERSECTS, null, null, context);
if (boost() != 1f) {
query = new BoostQuery(query, boost());
}
@ -254,20 +255,13 @@ public class DateFieldMapper extends FieldMapper {
}
@Override
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, QueryShardContext context) {
failIfNotIndexed();
return rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, null, null, context);
}
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper,
@Nullable DateTimeZone timeZone, @Nullable DateMathParser forcedDateParser, QueryShardContext context) {
failIfNotIndexed();
return innerRangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, timeZone, forcedDateParser, context);
}
Query innerRangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper,
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, ShapeRelation relation,
@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");
}
DateMathParser parser = forcedDateParser == null
? dateMathParser
: forcedDateParser;

View File

@ -120,7 +120,7 @@ public class IpFieldMapper extends FieldMapper {
}
}
public static final class IpFieldType extends MappedFieldType {
public static final class IpFieldType extends SimpleMappedFieldType {
public IpFieldType() {
super();

View File

@ -35,6 +35,7 @@ import org.apache.lucene.search.TermInSetQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.util.BytesRef;
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.index.analysis.NamedAnalyzer;
@ -347,7 +348,15 @@ public abstract class MappedFieldType extends FieldType {
return new ConstantScoreQuery(builder.build());
}
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, QueryShardContext context) {
/**
* Factory method for range queries.
* @param relation the relation, nulls should be interpreted like INTERSECTS
*/
public Query rangeQuery(
Object lowerTerm, Object upperTerm,
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");
}

View File

@ -44,7 +44,6 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentParser.Token;
import org.elasticsearch.common.xcontent.support.AbstractXContentParser;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.IndexNumericFieldData.NumericType;
import org.elasticsearch.index.fielddata.plain.DocValuesIndexFieldData;
@ -836,7 +835,7 @@ public class NumberFieldMapper extends FieldMapper {
}
}
public static final class NumberFieldType extends MappedFieldType {
public static final class NumberFieldType extends SimpleMappedFieldType {
NumberType type;

View File

@ -162,7 +162,7 @@ public class ScaledFloatFieldMapper extends FieldMapper {
}
}
public static final class ScaledFloatFieldType extends MappedFieldType {
public static final class ScaledFloatFieldType extends SimpleMappedFieldType {
private double scalingFactor;

View File

@ -126,7 +126,7 @@ public class SeqNoFieldMapper extends MetadataFieldMapper {
}
}
static final class SeqNoFieldType extends MappedFieldType {
static final class SeqNoFieldType extends SimpleMappedFieldType {
SeqNoFieldType() {
}

View File

@ -0,0 +1,63 @@
/*
* 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.apache.lucene.search.Query;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.index.query.QueryShardContext;
import org.joda.time.DateTimeZone;
/**
* {@link MappedFieldType} base impl for field types that are neither dates nor ranges.
*/
public abstract class SimpleMappedFieldType extends MappedFieldType {
protected SimpleMappedFieldType() {
super();
}
protected SimpleMappedFieldType(MappedFieldType ref) {
super(ref);
}
@Override
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");
}
// 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
// but then the API has no way to know which fields are dates and which fields are not dates
return rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, context);
}
/**
* Same as {@link #rangeQuery(Object, Object, boolean, boolean, ShapeRelation, DateTimeZone, DateMathParser, QueryShardContext)}
* but without the trouble of relations or date-specific options.
*/
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");
}
}

View File

@ -32,7 +32,7 @@ import org.elasticsearch.index.query.QueryShardContext;
/** Base {@link MappedFieldType} implementation for a field that is indexed
* with the inverted index. */
abstract class TermBasedFieldType extends MappedFieldType {
abstract class TermBasedFieldType extends SimpleMappedFieldType {
TermBasedFieldType() {}

View File

@ -36,7 +36,6 @@ import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.DateFieldMapper;
import org.elasticsearch.index.mapper.FieldNamesFieldMapper;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
@ -453,7 +452,7 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
// no field means we have no values
return MappedFieldType.Relation.DISJOINT;
} else {
DateMathParser dateMathParser = format == null ? null : new DateMathParser(format);
DateMathParser dateMathParser = getForceDateParser();
return fieldType.isFieldWithinQuery(shardContext.getIndexReader(), from, to, includeLower,
includeUpper, timeZone, dateMathParser, queryRewriteContext);
}
@ -503,25 +502,10 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
Query query = null;
MappedFieldType mapper = context.fieldMapper(this.fieldName);
if (mapper != null) {
if (mapper instanceof DateFieldMapper.DateFieldType) {
query = ((DateFieldMapper.DateFieldType) mapper).rangeQuery(from, to, includeLower, includeUpper,
timeZone, getForceDateParser(), context);
} else if (mapper instanceof RangeFieldMapper.RangeFieldType) {
DateMathParser forcedDateParser = null;
if (mapper.typeName() == RangeFieldMapper.RangeType.DATE.name && this.format != null) {
forcedDateParser = new DateMathParser(this.format);
}
query = ((RangeFieldMapper.RangeFieldType) mapper).rangeQuery(from, to, includeLower, includeUpper,
DateMathParser forcedDateParser = getForceDateParser();
query = mapper.rangeQuery(
from, to, includeLower, includeUpper,
relation, timeZone, forcedDateParser, context);
} else {
if (timeZone != null) {
throw new QueryShardException(context, "[range] time_zone can not be applied to non date field ["
+ fieldName + "]");
}
//LUCENE 4 UPGRADE Mapper#rangeQuery should use bytesref as well?
query = mapper.rangeQuery(from, to, includeLower, includeUpper, context);
}
} else {
if (timeZone != null) {
throw new QueryShardException(context, "[range] time_zone can not be applied to non unmapped field ["
@ -530,7 +514,9 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
}
if (query == null) {
query = new TermRangeQuery(this.fieldName, BytesRefs.toBytesRef(from), BytesRefs.toBytesRef(to), includeLower, includeUpper);
query = new TermRangeQuery(this.fieldName,
BytesRefs.toBytesRef(from), BytesRefs.toBytesRef(to),
includeLower, includeUpper);
}
return query;
}

View File

@ -46,11 +46,10 @@ import org.apache.lucene.util.IOUtils;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.mapper.DateFieldMapper;
import org.elasticsearch.index.mapper.FieldNamesFieldMapper;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.StringFieldType;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.StringFieldType;
import org.elasticsearch.index.query.ExistsQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryShardContext;
@ -394,14 +393,8 @@ public class QueryStringQueryParser extends XQueryParser {
Analyzer normalizer = forceAnalyzer == null ? queryBuilder.context.getSearchAnalyzer(currentFieldType) : forceAnalyzer;
BytesRef part1Binary = part1 == null ? null : normalizer.normalize(field, part1);
BytesRef part2Binary = part2 == null ? null : normalizer.normalize(field, part2);
Query rangeQuery;
if (currentFieldType instanceof DateFieldMapper.DateFieldType && timeZone != null) {
DateFieldMapper.DateFieldType dateFieldType = (DateFieldMapper.DateFieldType) this.currentFieldType;
rangeQuery = dateFieldType.rangeQuery(part1Binary, part2Binary,
startInclusive, endInclusive, timeZone, null, context);
} else {
rangeQuery = currentFieldType.rangeQuery(part1Binary, part2Binary, startInclusive, endInclusive, context);
}
Query rangeQuery = currentFieldType.rangeQuery(part1Binary, part2Binary,
startInclusive, endInclusive, null, timeZone, null, context);
return rangeQuery;
} catch (RuntimeException e) {
if (lenient) {

View File

@ -200,11 +200,11 @@ public class DateFieldTypeTests extends FieldTypeTestCase {
LongPoint.newRangeQuery("field", instant1, instant2),
SortedNumericDocValuesField.newSlowRangeQuery("field", instant1, instant2));
assertEquals(expected,
ft.rangeQuery(date1, date2, true, true, context).rewrite(new MultiReader()));
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, context));
() -> ft.rangeQuery(date1, date2, true, true, null, null, null, context));
assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage());
}
}

View File

@ -42,7 +42,7 @@ public class IdFieldTypeTests extends FieldTypeTestCase {
MappedFieldType ft = createDefaultFieldType();
ft.setName("_id");
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
() -> ft.rangeQuery(null, null, randomBoolean(), randomBoolean(), null));
() -> ft.rangeQuery(null, null, randomBoolean(), randomBoolean(), null, null, null, null));
assertEquals("Field [_id] of type [_id] does not support range queries", e.getMessage());
}

View File

@ -106,83 +106,84 @@ public class IpFieldTypeTests extends FieldTypeTestCase {
InetAddressPoint.newRangeQuery("field",
InetAddresses.forString("::"),
InetAddressPoint.MAX_VALUE),
ft.rangeQuery(null, null, randomBoolean(), randomBoolean(), null));
ft.rangeQuery(null, null, randomBoolean(), randomBoolean(), null, null, null, null));
assertEquals(
InetAddressPoint.newRangeQuery("field",
InetAddresses.forString("::"),
InetAddresses.forString("192.168.2.0")),
ft.rangeQuery(null, "192.168.2.0", randomBoolean(), true, null));
ft.rangeQuery(null, "192.168.2.0", randomBoolean(), true, null, null, null, null));
assertEquals(
InetAddressPoint.newRangeQuery("field",
InetAddresses.forString("::"),
InetAddresses.forString("192.168.1.255")),
ft.rangeQuery(null, "192.168.2.0", randomBoolean(), false, null));
ft.rangeQuery(null, "192.168.2.0", randomBoolean(), false, null, null, null, null));
assertEquals(
InetAddressPoint.newRangeQuery("field",
InetAddresses.forString("2001:db8::"),
InetAddressPoint.MAX_VALUE),
ft.rangeQuery("2001:db8::", null, true, randomBoolean(), null));
ft.rangeQuery("2001:db8::", null, true, randomBoolean(), null, null, null, null));
assertEquals(
InetAddressPoint.newRangeQuery("field",
InetAddresses.forString("2001:db8::1"),
InetAddressPoint.MAX_VALUE),
ft.rangeQuery("2001:db8::", null, false, randomBoolean(), null));
ft.rangeQuery("2001:db8::", null, false, randomBoolean(), null, null, null, null));
assertEquals(
InetAddressPoint.newRangeQuery("field",
InetAddresses.forString("2001:db8::"),
InetAddresses.forString("2001:db8::ffff")),
ft.rangeQuery("2001:db8::", "2001:db8::ffff", true, true, null));
ft.rangeQuery("2001:db8::", "2001:db8::ffff", true, true, null, null, null, null));
assertEquals(
InetAddressPoint.newRangeQuery("field",
InetAddresses.forString("2001:db8::1"),
InetAddresses.forString("2001:db8::fffe")),
ft.rangeQuery("2001:db8::", "2001:db8::ffff", false, false, null));
ft.rangeQuery("2001:db8::", "2001:db8::ffff", false, false, null, null, null, null));
assertEquals(
InetAddressPoint.newRangeQuery("field",
InetAddresses.forString("2001:db8::2"),
InetAddresses.forString("2001:db8::")),
// same lo/hi values but inclusive=false so this won't match anything
ft.rangeQuery("2001:db8::1", "2001:db8::1", false, false, null));
ft.rangeQuery("2001:db8::1", "2001:db8::1", false, false, null, null, null, null));
// Upper bound is the min IP and is not inclusive
assertEquals(new MatchNoDocsQuery(),
ft.rangeQuery("::", "::", true, false, null));
ft.rangeQuery("::", "::", true, false, null, null, null, null));
// Lower bound is the max IP and is not inclusive
assertEquals(new MatchNoDocsQuery(),
ft.rangeQuery("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", false, true, null));
ft.rangeQuery("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
false, true, null, null, null, null));
assertEquals(
InetAddressPoint.newRangeQuery("field",
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));
ft.rangeQuery("::", "0.0.0.0", true, false, null, null, null, null));
assertEquals(
InetAddressPoint.newRangeQuery("field",
InetAddresses.forString("::1:0:0:0"),
InetAddressPoint.MAX_VALUE),
// same lo/hi values but inclusive=false so this won't match anything
ft.rangeQuery("255.255.255.255", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", false, true, null));
ft.rangeQuery("255.255.255.255", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", false, true, null, null, null, null));
assertEquals(
// lower bound is ipv4, upper bound is ipv6
InetAddressPoint.newRangeQuery("field",
InetAddresses.forString("192.168.1.7"),
InetAddresses.forString("2001:db8::")),
ft.rangeQuery("::ffff:c0a8:107", "2001:db8::", true, true, null));
ft.rangeQuery("::ffff:c0a8:107", "2001:db8::", true, true, null, null, null, null));
ft.setIndexOptions(IndexOptions.NONE);
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
() -> ft.rangeQuery("::1", "2001::", true, true, null));
() -> ft.rangeQuery("::1", "2001::", true, true, null, null, null, null));
assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage());
}
}

View File

@ -139,76 +139,116 @@ public class NumberFieldTypeTests extends FieldTypeTestCase {
MappedFieldType ftInt = new NumberFieldMapper.NumberFieldType(NumberType.INTEGER);
ftInt.setName("field");
ftInt.setIndexOptions(IndexOptions.DOCS);
assertEquals(ftInt.rangeQuery(-3, -3, true, true, null), ftInt.rangeQuery(-3.5, -2.5, true, true, null));
assertEquals(ftInt.rangeQuery(-3, -3, true, true, null), ftInt.rangeQuery(-3.5, -2.5, false, false, null));
assertEquals(ftInt.rangeQuery(0, 0, true, true, null), ftInt.rangeQuery(-0.5, 0.5, true, true, null));
assertEquals(ftInt.rangeQuery(0, 0, true, true, null), ftInt.rangeQuery(-0.5, 0.5, false, false, null));
assertEquals(ftInt.rangeQuery(1, 2, true, true, null), ftInt.rangeQuery(0.5, 2.5, true, true, null));
assertEquals(ftInt.rangeQuery(1, 2, true, true, null), ftInt.rangeQuery(0.5, 2.5, false, false, null));
assertEquals(ftInt.rangeQuery(0, 2, true, true, null), ftInt.rangeQuery(-0.5, 2.5, true, true, null));
assertEquals(ftInt.rangeQuery(0, 2, true, true, null), ftInt.rangeQuery(-0.5, 2.5, false, false, null));
assertEquals(ftInt.rangeQuery(-3, -3, true, true, null, null, null, null),
ftInt.rangeQuery(-3.5, -2.5, true, true, null, null, null, null));
assertEquals(ftInt.rangeQuery(-3, -3, true, true, null, null, null, null),
ftInt.rangeQuery(-3.5, -2.5, false, false, null, null, null, null));
assertEquals(ftInt.rangeQuery(0, 0, true, true, null, null, null, null),
ftInt.rangeQuery(-0.5, 0.5, true, true, null, null, null, null));
assertEquals(ftInt.rangeQuery(0, 0, true, true, null, null, null, null),
ftInt.rangeQuery(-0.5, 0.5, false, false, null, null, null, null));
assertEquals(ftInt.rangeQuery(1, 2, true, true, null, null, null, null),
ftInt.rangeQuery(0.5, 2.5, true, true, null, null, null, null));
assertEquals(ftInt.rangeQuery(1, 2, true, true, null, null, null, null),
ftInt.rangeQuery(0.5, 2.5, false, false, null, null, null, null));
assertEquals(ftInt.rangeQuery(0, 2, true, true, null, null, null, null),
ftInt.rangeQuery(-0.5, 2.5, true, true, null, null, null, null));
assertEquals(ftInt.rangeQuery(0, 2, true, true, null, null, null, null),
ftInt.rangeQuery(-0.5, 2.5, false, false, null, null, null, null));
assertEquals(ftInt.rangeQuery(-2, 0, true, true, null), ftInt.rangeQuery(-2.5, 0.5, true, true, null));
assertEquals(ftInt.rangeQuery(-2, 0, true, true, null), ftInt.rangeQuery(-2.5, 0.5, false, false, null));
assertEquals(ftInt.rangeQuery(-2, -1, true, true, null), ftInt.rangeQuery(-2.5, -0.5, true, true, null));
assertEquals(ftInt.rangeQuery(-2, -1, true, true, null), ftInt.rangeQuery(-2.5, -0.5, false, false, null));
assertEquals(ftInt.rangeQuery(-2, 0, true, true, null, null, null, null),
ftInt.rangeQuery(-2.5, 0.5, true, true, null, null, null, null));
assertEquals(ftInt.rangeQuery(-2, 0, true, true, null, null, null, null),
ftInt.rangeQuery(-2.5, 0.5, false, false, null, null, null, null));
assertEquals(ftInt.rangeQuery(-2, -1, true, true, null, null, null, null),
ftInt.rangeQuery(-2.5, -0.5, true, true, null, null, null, null));
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");
ftLong.setIndexOptions(IndexOptions.DOCS);
assertEquals(ftLong.rangeQuery(-3, -3, true, true, null), ftLong.rangeQuery(-3.5, -2.5, true, true, null));
assertEquals(ftLong.rangeQuery(-3, -3, true, true, null), ftLong.rangeQuery(-3.5, -2.5, false, false, null));
assertEquals(ftLong.rangeQuery(0, 0, true, true, null), ftLong.rangeQuery(-0.5, 0.5, true, true, null));
assertEquals(ftLong.rangeQuery(0, 0, true, true, null), ftLong.rangeQuery(-0.5, 0.5, false, false, null));
assertEquals(ftLong.rangeQuery(1, 2, true, true, null), ftLong.rangeQuery(0.5, 2.5, true, true, null));
assertEquals(ftLong.rangeQuery(1, 2, true, true, null), ftLong.rangeQuery(0.5, 2.5, false, false, null));
assertEquals(ftLong.rangeQuery(0, 2, true, true, null), ftLong.rangeQuery(-0.5, 2.5, true, true, null));
assertEquals(ftLong.rangeQuery(0, 2, true, true, null), ftLong.rangeQuery(-0.5, 2.5, false, false, null));
assertEquals(ftLong.rangeQuery(-3, -3, true, true, null, null, null, null),
ftLong.rangeQuery(-3.5, -2.5, true, true, null, null, null, null));
assertEquals(ftLong.rangeQuery(-3, -3, true, true, null, null, null, null),
ftLong.rangeQuery(-3.5, -2.5, false, false, null, null, null, null));
assertEquals(ftLong.rangeQuery(0, 0, true, true, null, null, null, null),
ftLong.rangeQuery(-0.5, 0.5, true, true, null, null, null, null));
assertEquals(ftLong.rangeQuery(0, 0, true, true, null, null, null, null),
ftLong.rangeQuery(-0.5, 0.5, false, false, null, null, null, null));
assertEquals(ftLong.rangeQuery(1, 2, true, true, null, null, null, null),
ftLong.rangeQuery(0.5, 2.5, true, true, null, null, null, null));
assertEquals(ftLong.rangeQuery(1, 2, true, true, null, null, null, null),
ftLong.rangeQuery(0.5, 2.5, false, false, null, null, null, null));
assertEquals(ftLong.rangeQuery(0, 2, true, true, null, null, null, null),
ftLong.rangeQuery(-0.5, 2.5, true, true, null, null, null, null));
assertEquals(ftLong.rangeQuery(0, 2, true, true, null, null, null, null),
ftLong.rangeQuery(-0.5, 2.5, false, false, null, null, null, null));
assertEquals(ftLong.rangeQuery(-2, 0, true, true, null), ftLong.rangeQuery(-2.5, 0.5, true, true, null));
assertEquals(ftLong.rangeQuery(-2, 0, true, true, null), ftLong.rangeQuery(-2.5, 0.5, false, false, null));
assertEquals(ftLong.rangeQuery(-2, -1, true, true, null), ftLong.rangeQuery(-2.5, -0.5, true, true, null));
assertEquals(ftLong.rangeQuery(-2, -1, true, true, null), ftLong.rangeQuery(-2.5, -0.5, false, false, null));
assertEquals(ftLong.rangeQuery(-2, 0, true, true, null, null, null, null),
ftLong.rangeQuery(-2.5, 0.5, true, true, null, null, null, null));
assertEquals(ftLong.rangeQuery(-2, 0, true, true, null, null, null, null),
ftLong.rangeQuery(-2.5, 0.5, false, false, null, null, null, null));
assertEquals(ftLong.rangeQuery(-2, -1, true, true, null, null, null, null),
ftLong.rangeQuery(-2.5, -0.5, true, true, null, null, null, null));
assertEquals(ftLong.rangeQuery(-2, -1, true, true, null, null, null, null),
ftLong.rangeQuery(-2.5, -0.5, false, false, null, null, null, null));
}
public void testByteRangeQueryWithDecimalParts() {
MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberType.BYTE);
ft.setName("field");
ft.setIndexOptions(IndexOptions.DOCS);
assertEquals(ft.rangeQuery(2, 10, true, true, null), ft.rangeQuery(1.1, 10, true, true, null));
assertEquals(ft.rangeQuery(2, 10, true, true, null), ft.rangeQuery(1.1, 10, false, true, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null), ft.rangeQuery(1, 10.1, true, true, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null), ft.rangeQuery(1, 10.1, true, false, null));
assertEquals(ft.rangeQuery(2, 10, true, true, null, null, null, null),
ft.rangeQuery(1.1, 10, true, true, null, null, null, null));
assertEquals(ft.rangeQuery(2, 10, true, true, null, null, null, null),
ft.rangeQuery(1.1, 10, false, true, null, null, null, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null, null, null, null),
ft.rangeQuery(1, 10.1, true, true, null, null, null, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null, null, null, null),
ft.rangeQuery(1, 10.1, true, false, null, null, null, null));
}
public void testShortRangeQueryWithDecimalParts() {
MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberType.SHORT);
ft.setName("field");
ft.setIndexOptions(IndexOptions.DOCS);
assertEquals(ft.rangeQuery(2, 10, true, true, null), ft.rangeQuery(1.1, 10, true, true, null));
assertEquals(ft.rangeQuery(2, 10, true, true, null), ft.rangeQuery(1.1, 10, false, true, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null), ft.rangeQuery(1, 10.1, true, true, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null), ft.rangeQuery(1, 10.1, true, false, null));
assertEquals(ft.rangeQuery(2, 10, true, true, null, null, null, null),
ft.rangeQuery(1.1, 10, true, true, null, null, null, null));
assertEquals(ft.rangeQuery(2, 10, true, true, null, null, null, null),
ft.rangeQuery(1.1, 10, false, true, null, null, null, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null, null, null, null),
ft.rangeQuery(1, 10.1, true, true, null, null, null, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null, null, null, null),
ft.rangeQuery(1, 10.1, true, false, null, null, null, null));
}
public void testIntegerRangeQueryWithDecimalParts() {
MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberType.INTEGER);
ft.setName("field");
ft.setIndexOptions(IndexOptions.DOCS);
assertEquals(ft.rangeQuery(2, 10, true, true, null), ft.rangeQuery(1.1, 10, true, true, null));
assertEquals(ft.rangeQuery(2, 10, true, true, null), ft.rangeQuery(1.1, 10, false, true, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null), ft.rangeQuery(1, 10.1, true, true, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null), ft.rangeQuery(1, 10.1, true, false, null));
assertEquals(ft.rangeQuery(2, 10, true, true, null, null, null, null),
ft.rangeQuery(1.1, 10, true, true, null, null, null, null));
assertEquals(ft.rangeQuery(2, 10, true, true, null, null, null, null),
ft.rangeQuery(1.1, 10, false, true, null, null, null, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null, null, null, null),
ft.rangeQuery(1, 10.1, true, true, null, null, null, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null, null, null, null),
ft.rangeQuery(1, 10.1, true, false, null, null, null, null));
}
public void testLongRangeQueryWithDecimalParts() {
MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberType.LONG);
ft.setName("field");
ft.setIndexOptions(IndexOptions.DOCS);
assertEquals(ft.rangeQuery(2, 10, true, true, null), ft.rangeQuery(1.1, 10, true, true, null));
assertEquals(ft.rangeQuery(2, 10, true, true, null), ft.rangeQuery(1.1, 10, false, true, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null), ft.rangeQuery(1, 10.1, true, true, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null), ft.rangeQuery(1, 10.1, true, false, null));
assertEquals(ft.rangeQuery(2, 10, true, true, null, null, null, null),
ft.rangeQuery(1.1, 10, true, true, null, null, null, null));
assertEquals(ft.rangeQuery(2, 10, true, true, null, null, null, null),
ft.rangeQuery(1.1, 10, false, true, null, null, null, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null, null, null, null),
ft.rangeQuery(1, 10.1, true, true, null, null, null, null));
assertEquals(ft.rangeQuery(1, 10, true, true, null, null, null, null),
ft.rangeQuery(1, 10.1, true, false, null, null, null, null));
}
public void testRangeQuery() {
@ -218,11 +258,11 @@ public class NumberFieldTypeTests extends FieldTypeTestCase {
Query expected = new IndexOrDocValuesQuery(
LongPoint.newRangeQuery("field", 1, 3),
SortedNumericDocValuesField.newSlowRangeQuery("field", 1, 3));
assertEquals(expected, ft.rangeQuery("1", "3", true, true, null));
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));
() -> ft.rangeQuery("1", "3", true, true, null, null, null, null));
assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage());
}

View File

@ -45,7 +45,7 @@ public class UidFieldTypeTests extends FieldTypeTestCase {
MappedFieldType ft = createDefaultFieldType();
ft.setName("_uid");
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
() -> ft.rangeQuery(null, null, randomBoolean(), randomBoolean(), null));
() -> ft.rangeQuery(null, null, randomBoolean(), randomBoolean(), null, null, null, null));
assertEquals("Field [_uid] of type [_uid] does not support range queries", e.getMessage());
}

View File

@ -234,16 +234,6 @@ public class RangeQueryBuilderTests extends AbstractQueryTestCase<RangeQueryBuil
expectThrows(IllegalArgumentException.class, () -> rangeQueryBuilder.format("badFormat"));
}
/**
* Specifying a timezone together with a numeric range query should throw an exception.
*/
public void testToQueryNonDateWithTimezone() throws QueryShardException {
RangeQueryBuilder query = new RangeQueryBuilder(INT_FIELD_NAME);
query.from(1).to(10).timeZone("UTC");
QueryShardException e = expectThrows(QueryShardException.class, () -> query.toQuery(createShardContext()));
assertThat(e.getMessage(), containsString("[range] time_zone can not be applied"));
}
/**
* Specifying a timezone together with an unmapped field should throw an exception.
*/
@ -364,7 +354,7 @@ public class RangeQueryBuilderTests extends AbstractQueryTestCase<RangeQueryBuil
" }\n" +
"}";
QueryBuilder queryBuilder = parseQuery(query);
expectThrows(QueryShardException.class, () -> queryBuilder.toQuery(createShardContext()));
queryBuilder.toQuery(createShardContext()); // no exception
}
public void testFromJson() throws IOException {

View File

@ -146,28 +146,28 @@ public class NestedHelperTests extends ESSingleNodeTestCase {
}
public void testRangeQuery() {
Query rangeQuery = mapperService.fullName("foo2").rangeQuery(2, 5, true, true, null);
Query rangeQuery = mapperService.fullName("foo2").rangeQuery(2, 5, true, true, null, null, null, null);
assertFalse(new NestedHelper(mapperService).mightMatchNestedDocs(rangeQuery));
assertTrue(new NestedHelper(mapperService).mightMatchNonNestedDocs(rangeQuery, "nested1"));
assertTrue(new NestedHelper(mapperService).mightMatchNonNestedDocs(rangeQuery, "nested2"));
assertTrue(new NestedHelper(mapperService).mightMatchNonNestedDocs(rangeQuery, "nested3"));
assertTrue(new NestedHelper(mapperService).mightMatchNonNestedDocs(rangeQuery, "nested_missing"));
rangeQuery = mapperService.fullName("nested1.foo2").rangeQuery(2, 5, true, true, null);
rangeQuery = mapperService.fullName("nested1.foo2").rangeQuery(2, 5, true, true, null, null, null, null);
assertTrue(new NestedHelper(mapperService).mightMatchNestedDocs(rangeQuery));
assertFalse(new NestedHelper(mapperService).mightMatchNonNestedDocs(rangeQuery, "nested1"));
assertTrue(new NestedHelper(mapperService).mightMatchNonNestedDocs(rangeQuery, "nested2"));
assertTrue(new NestedHelper(mapperService).mightMatchNonNestedDocs(rangeQuery, "nested3"));
assertTrue(new NestedHelper(mapperService).mightMatchNonNestedDocs(rangeQuery, "nested_missing"));
rangeQuery = mapperService.fullName("nested2.foo2").rangeQuery(2, 5, true, true, null);
rangeQuery = mapperService.fullName("nested2.foo2").rangeQuery(2, 5, true, true, null, null, null, null);
assertTrue(new NestedHelper(mapperService).mightMatchNestedDocs(rangeQuery));
assertTrue(new NestedHelper(mapperService).mightMatchNonNestedDocs(rangeQuery, "nested1"));
assertTrue(new NestedHelper(mapperService).mightMatchNonNestedDocs(rangeQuery, "nested2"));
assertTrue(new NestedHelper(mapperService).mightMatchNonNestedDocs(rangeQuery, "nested3"));
assertTrue(new NestedHelper(mapperService).mightMatchNonNestedDocs(rangeQuery, "nested_missing"));
rangeQuery = mapperService.fullName("nested3.foo2").rangeQuery(2, 5, true, true, null);
rangeQuery = mapperService.fullName("nested3.foo2").rangeQuery(2, 5, true, true, null, null, null, null);
assertTrue(new NestedHelper(mapperService).mightMatchNestedDocs(rangeQuery));
assertTrue(new NestedHelper(mapperService).mightMatchNonNestedDocs(rangeQuery, "nested1"));
assertTrue(new NestedHelper(mapperService).mightMatchNonNestedDocs(rangeQuery, "nested2"));

View File

@ -1788,12 +1788,6 @@ public class SearchQueryIT extends ESIntegTestCase {
.get();
assertHitCount(searchResponse, 1L);
assertThat(searchResponse.getHits().getAt(0).getId(), is("4"));
// A Range Filter on a numeric field with a TimeZone should raise an exception
e = expectThrows(SearchPhaseExecutionException.class, () ->
client().prepareSearch("test")
.setQuery(QueryBuilders.rangeQuery("num").from("0").to("4").timeZone("-01:00"))
.get());
}
public void testSearchEmptyDoc() {

View File

@ -195,10 +195,10 @@ public class PercolatorFieldMapperTests extends ESSingleNodeTestCase {
addQueryFieldMappings();
BooleanQuery.Builder bq = new BooleanQuery.Builder();
Query rangeQuery1 = mapperService.documentMapper("doc").mappers().getMapper("number_field1").fieldType()
.rangeQuery(10, 20, true, true, null);
.rangeQuery(10, 20, true, true, null, null, null, null);
bq.add(rangeQuery1, Occur.MUST);
Query rangeQuery2 = mapperService.documentMapper("doc").mappers().getMapper("number_field1").fieldType()
.rangeQuery(15, 20, true, true, null);
.rangeQuery(15, 20, true, true, null, null, null, null);
bq.add(rangeQuery2, Occur.MUST);
DocumentMapper documentMapper = mapperService.documentMapper("doc");

View File

@ -135,11 +135,11 @@ public class CollationFieldTypeTests extends FieldTypeTestCase {
TermRangeQuery expected = new TermRangeQuery("field", new BytesRef(aKey.bytes, 0, aKey.size),
new BytesRef(bKey.bytes, 0, bKey.size), false, false);
assertEquals(expected, ft.rangeQuery("a", "b", false, false, null));
assertEquals(expected, ft.rangeQuery("a", "b", false, false, null, null, null, null));
ft.setIndexOptions(IndexOptions.NONE);
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
() -> ft.rangeQuery("a", "b", false, false, null));
() -> ft.rangeQuery("a", "b", false, false, null, null, null, null));
assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage());
}
}