Replace FieldStatsProvider with a method on MappedFieldType. #17334

FieldStatsProvider had to perform instanceof calls to properly handle dates or
ip addresses. By moving the logic to MappedFieldType, each field type can check
whether all values are within bounds its way.

Note that this commit only keeps rewriting support for dates, which are the only
field for which the rewriting mechanism is likely to help (because of time-based
indices).
This commit is contained in:
Adrien Grand 2016-03-24 18:27:18 +01:00
parent 11fdd2608f
commit 4c4bbb3e45
36 changed files with 496 additions and 1165 deletions

View File

@ -168,8 +168,6 @@ public class TransportValidateQueryAction extends TransportBroadcastAction<Valid
protected ShardValidateQueryResponse shardOperation(ShardValidateQueryRequest request) { protected ShardValidateQueryResponse shardOperation(ShardValidateQueryRequest request) {
IndexService indexService = indicesService.indexServiceSafe(request.shardId().getIndex()); IndexService indexService = indicesService.indexServiceSafe(request.shardId().getIndex());
IndexShard indexShard = indexService.getShard(request.shardId().id()); IndexShard indexShard = indexService.getShard(request.shardId().id());
final QueryShardContext queryShardContext = indexService.newQueryShardContext();
queryShardContext.setTypes(request.types());
boolean valid; boolean valid;
String explanation = null; String explanation = null;
@ -182,7 +180,7 @@ public class TransportValidateQueryAction extends TransportBroadcastAction<Valid
parseFieldMatcher, SearchService.NO_TIMEOUT, fetchPhase); parseFieldMatcher, SearchService.NO_TIMEOUT, fetchPhase);
SearchContext.setCurrent(searchContext); SearchContext.setCurrent(searchContext);
try { try {
searchContext.parsedQuery(queryShardContext.toQuery(request.query())); searchContext.parsedQuery(searchContext.getQueryShardContext().toQuery(request.query()));
searchContext.preProcess(); searchContext.preProcess();
valid = true; valid = true;

View File

@ -32,17 +32,17 @@ import java.util.Map;
*/ */
public class FieldStatsShardResponse extends BroadcastShardResponse { public class FieldStatsShardResponse extends BroadcastShardResponse {
private Map<String, FieldStats> fieldStats; private Map<String, FieldStats<?>> fieldStats;
public FieldStatsShardResponse() { public FieldStatsShardResponse() {
} }
public FieldStatsShardResponse(ShardId shardId, Map<String, FieldStats> fieldStats) { public FieldStatsShardResponse(ShardId shardId, Map<String, FieldStats<?>> fieldStats) {
super(shardId); super(shardId);
this.fieldStats = fieldStats; this.fieldStats = fieldStats;
} }
public Map<String, FieldStats> getFieldStats() { public Map<String, FieldStats<?>> getFieldStats() {
return fieldStats; return fieldStats;
} }
@ -63,7 +63,7 @@ public class FieldStatsShardResponse extends BroadcastShardResponse {
public void writeTo(StreamOutput out) throws IOException { public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out); super.writeTo(out);
out.writeVInt(fieldStats.size()); out.writeVInt(fieldStats.size());
for (Map.Entry<String, FieldStats> entry : fieldStats.entrySet()) { for (Map.Entry<String, FieldStats<?>> entry : fieldStats.entrySet()) {
out.writeString(entry.getKey()); out.writeString(entry.getKey());
entry.getValue().writeTo(out); entry.getValue().writeTo(out);
} }

View File

@ -19,9 +19,6 @@
package org.elasticsearch.action.fieldstats; package org.elasticsearch.action.fieldstats;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiFields;
import org.apache.lucene.index.Terms;
import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.action.ShardOperationFailedException; import org.elasticsearch.action.ShardOperationFailedException;
import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.ActionFilters;
@ -102,9 +99,9 @@ public class TransportFieldStatsTransportAction extends TransportBroadcastAction
indicesMergedFieldStats.put(indexName, indexMergedFieldStats = new HashMap<>()); indicesMergedFieldStats.put(indexName, indexMergedFieldStats = new HashMap<>());
} }
Map<String, FieldStats> fieldStats = shardResponse.getFieldStats(); Map<String, FieldStats<?>> fieldStats = shardResponse.getFieldStats();
for (Map.Entry<String, FieldStats> entry : fieldStats.entrySet()) { for (Map.Entry<String, FieldStats<?>> entry : fieldStats.entrySet()) {
FieldStats existing = indexMergedFieldStats.get(entry.getKey()); FieldStats<?> existing = indexMergedFieldStats.get(entry.getKey());
if (existing != null) { if (existing != null) {
if (existing.getType() != entry.getValue().getType()) { if (existing.getType() != entry.getValue().getType()) {
throw new IllegalStateException( throw new IllegalStateException(
@ -156,22 +153,20 @@ public class TransportFieldStatsTransportAction extends TransportBroadcastAction
@Override @Override
protected FieldStatsShardResponse shardOperation(FieldStatsShardRequest request) { protected FieldStatsShardResponse shardOperation(FieldStatsShardRequest request) {
ShardId shardId = request.shardId(); ShardId shardId = request.shardId();
Map<String, FieldStats> fieldStats = new HashMap<>(); Map<String, FieldStats<?>> fieldStats = new HashMap<>();
IndexService indexServices = indicesService.indexServiceSafe(shardId.getIndex()); IndexService indexServices = indicesService.indexServiceSafe(shardId.getIndex());
MapperService mapperService = indexServices.mapperService(); MapperService mapperService = indexServices.mapperService();
IndexShard shard = indexServices.getShard(shardId.id()); IndexShard shard = indexServices.getShard(shardId.id());
try (Engine.Searcher searcher = shard.acquireSearcher("fieldstats")) { try (Engine.Searcher searcher = shard.acquireSearcher("fieldstats")) {
for (String field : request.getFields()) { for (String field : request.getFields()) {
MappedFieldType fieldType = mapperService.fullName(field); MappedFieldType fieldType = mapperService.fullName(field);
if (fieldType != null) { if (fieldType == null) {
IndexReader reader = searcher.reader();
Terms terms = MultiFields.getTerms(reader, field);
if (terms != null) {
fieldStats.put(field, fieldType.stats(terms, reader.maxDoc()));
}
} else {
throw new IllegalArgumentException("field [" + field + "] doesn't exist"); throw new IllegalArgumentException("field [" + field + "] doesn't exist");
} }
FieldStats<?> stats = fieldType.stats(searcher.reader());
if (stats != null) {
fieldStats.put(field, stats);
}
} }
} catch (IOException e) { } catch (IOException e) {
throw ExceptionsHelper.convertToElastic(e); throw ExceptionsHelper.convertToElastic(e);

View File

@ -19,6 +19,7 @@
package org.elasticsearch.index; package org.elasticsearch.index;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -438,14 +439,23 @@ public final class IndexService extends AbstractIndexComponent implements IndexC
* Creates a new QueryShardContext. The context has not types set yet, if types are required set them via * Creates a new QueryShardContext. The context has not types set yet, if types are required set them via
* {@link QueryShardContext#setTypes(String...)} * {@link QueryShardContext#setTypes(String...)}
*/ */
public QueryShardContext newQueryShardContext() { public QueryShardContext newQueryShardContext(IndexReader indexReader) {
return new QueryShardContext( return new QueryShardContext(
indexSettings, indexCache.bitsetFilterCache(), indexFieldData, mapperService(), indexSettings, indexCache.bitsetFilterCache(), indexFieldData, mapperService(),
similarityService(), nodeServicesProvider.getScriptService(), nodeServicesProvider.getIndicesQueriesRegistry(), similarityService(), nodeServicesProvider.getScriptService(), nodeServicesProvider.getIndicesQueriesRegistry(),
indexCache.getPercolatorQueryCache() indexCache.getPercolatorQueryCache(), indexReader
); );
} }
/**
* Creates a new QueryShardContext. The context has not types set yet, if types are required set them via
* {@link QueryShardContext#setTypes(String...)}. This context may be used for query parsing but cannot be
* used for rewriting since it does not know about the current {@link IndexReader}.
*/
public QueryShardContext newQueryShardContext() {
return newQueryShardContext(null);
}
public ThreadPool getThreadPool() { public ThreadPool getThreadPool() {
return threadPool; return threadPool;
} }

View File

@ -1,181 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.index.fieldstats;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiFields;
import org.apache.lucene.index.Terms;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.action.fieldstats.FieldStats;
import org.elasticsearch.action.fieldstats.IndexConstraint;
import org.elasticsearch.action.fieldstats.IndexConstraint.Comparison;
import org.elasticsearch.action.fieldstats.IndexConstraint.Property;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.index.engine.Engine.Searcher;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.core.DateFieldMapper.DateFieldType;
import org.elasticsearch.index.mapper.ip.IpFieldMapper.IpFieldType;
import org.joda.time.DateTimeZone;
import java.io.IOException;
/**
* Provides a service for gettings the {@link FieldStats} for a given field from
* the index.
*/
public class FieldStatsProvider {
private final Searcher searcher;
private final MapperService mapperService;
/**
* @param searcher
* the {@link Searcher}to use when retrieving the
* {@link FieldStats}
* @param mapperService
* the {@link MapperService}
*/
public FieldStatsProvider(Searcher searcher, MapperService mapperService) {
this.searcher = searcher;
this.mapperService = mapperService;
}
/**
* @param field
* the name of the field to return {@link FieldStats} for.
* @return a {@link FieldStats} object for the given field
* @throws IOException
* if the field statistics cannot be read
*/
public <T extends Comparable<T>> FieldStats<T> get(String field) throws IOException {
MappedFieldType mappedFieldType = mapperService.fullName(field);
if (mappedFieldType != null) {
IndexReader reader = searcher.reader();
Terms terms = MultiFields.getTerms(reader, field);
if (terms != null) {
return mappedFieldType.stats(terms, reader.maxDoc());
}
}
return null;
}
/**
* @param fieldName
* the fieldName to check
* @param from
* the minimum value for the query
* @param to
* the maximum value for the query
* @param includeLower
* whether the from value is inclusive
* @param includeUpper
* whether the to value is inclusive
* @param timeZone
* the timeZone to use for date fields
* @param dateMathParser
* the {@link DateMathParser} to use for date fields
* @return A {@link Relation} indicating the overlap of the range of terms
* for the field with the query range. This method will return:
* <ul>
* <li>{@link Relation#WITHIN} if the range of terms for the field
* in the shard is completely within the query range</li>
* <li>{@link Relation#DISJOINT} if the range of terms for the field
* in the shard is completely outside the query range</li>
* <li>{@link Relation#INTERSECTS} if the range of terms for the
* field in the shard intersects with the query range</li>
* </ul>
* @throws IOException
* if the index cannot be read
*/
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
MappedFieldType mappedFieldType = mapperService.fullName(fieldName);
FieldStats<?> fieldStats = get(fieldName);
if (fieldStats == null) {
// No fieldStats for the field so the field doesn't exist on
// this shard, so relation is DISJOINT
return Relation.DISJOINT;
} else {
// Convert the from and to values to Strings so they can be used
// in the IndexConstraints. Since DateTime is represented as a
// Long field in Lucene we need to use the millisecond value of
// the DateTime in that case
String fromString = null;
if (from != null) {
if (mappedFieldType instanceof DateFieldType) {
long millis = ((DateFieldType) mappedFieldType).parseToMilliseconds(from, !includeLower, timeZone, dateMathParser);
fromString = fieldStats.stringValueOf(millis, null);
} else if (mappedFieldType instanceof IpFieldType) {
if (from instanceof BytesRef) {
from = ((BytesRef) from).utf8ToString();
}
long ipAsLong = ((IpFieldType) mappedFieldType).value(from);
fromString = fieldStats.stringValueOf(ipAsLong, null);
} else {
fromString = fieldStats.stringValueOf(from, null);
}
}
String toString = null;
if (to != null) {
if (mappedFieldType instanceof DateFieldType) {
long millis = ((DateFieldType) mappedFieldType).parseToMilliseconds(to, includeUpper, timeZone, dateMathParser);
toString = fieldStats.stringValueOf(millis, null);
} else if (mappedFieldType instanceof IpFieldType) {
if (to instanceof BytesRef) {
to = ((BytesRef) to).utf8ToString();
}
long ipAsLong = ((IpFieldType) mappedFieldType).value(to);
toString = fieldStats.stringValueOf(ipAsLong, null);
} else {
toString = fieldStats.stringValueOf(to, null);
}
}
if ((from == null || fieldStats
.match(new IndexConstraint(fieldName, Property.MIN, includeLower ? Comparison.GTE : Comparison.GT, fromString)))
&& (to == null || fieldStats.match(
new IndexConstraint(fieldName, Property.MAX, includeUpper ? Comparison.LTE : Comparison.LT, toString)))) {
// If the min and max terms for the field are both within
// the query range then all documents will match so relation is
// WITHIN
return Relation.WITHIN;
} else if ((to != null && fieldStats
.match(new IndexConstraint(fieldName, Property.MIN, includeUpper ? Comparison.GT : Comparison.GTE, toString)))
|| (from != null && fieldStats.match(
new IndexConstraint(fieldName, Property.MAX, includeLower ? Comparison.LT : Comparison.LTE, fromString)))) {
// If the min and max terms are both outside the query range
// then no document will match so relation is DISJOINT (N.B.
// since from <= to we only need
// to check one bould for each side of the query range)
return Relation.DISJOINT;
}
}
// Range of terms doesn't match any of the constraints so must INTERSECT
return Relation.INTERSECTS;
}
/**
* An enum used to describe the relation between the range of terms in a
* shard when compared with a query range
*/
public static enum Relation {
WITHIN, INTERSECTS, DISJOINT;
}
}

View File

@ -21,6 +21,8 @@ package org.elasticsearch.index.mapper;
import org.apache.lucene.document.FieldType; import org.apache.lucene.document.FieldType;
import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiFields;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.index.Terms; import org.apache.lucene.index.Terms;
import org.apache.lucene.queries.TermsQuery; import org.apache.lucene.queries.TermsQuery;
@ -37,6 +39,7 @@ import org.apache.lucene.util.BytesRef;
import org.elasticsearch.Version; import org.elasticsearch.Version;
import org.elasticsearch.action.fieldstats.FieldStats; import org.elasticsearch.action.fieldstats.FieldStats;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.lucene.BytesRefs; import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.unit.Fuzziness; import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.analysis.NamedAnalyzer; import org.elasticsearch.index.analysis.NamedAnalyzer;
@ -44,6 +47,7 @@ import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.QueryShardException; import org.elasticsearch.index.query.QueryShardException;
import org.elasticsearch.index.similarity.SimilarityProvider; import org.elasticsearch.index.similarity.SimilarityProvider;
import org.joda.time.DateTimeZone;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
@ -394,14 +398,43 @@ public abstract class MappedFieldType extends FieldType {
} }
/** /**
* @return a {@link FieldStats} instance that maps to the type of this field based on the provided {@link Terms} instance. * @return a {@link FieldStats} instance that maps to the type of this
* field or {@code null} if the provided index has no stats about the
* current field
*/ */
public FieldStats stats(Terms terms, int maxDoc) throws IOException { public FieldStats stats(IndexReader reader) throws IOException {
int maxDoc = reader.maxDoc();
Terms terms = MultiFields.getTerms(reader, name());
if (terms == null) {
return null;
}
return new FieldStats.Text( return new FieldStats.Text(
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), terms.getMin(), terms.getMax() maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), terms.getMin(), terms.getMax()
); );
} }
/**
* An enum used to describe the relation between the range of terms in a
* shard when compared with a query range
*/
public static enum Relation {
WITHIN,
INTERSECTS,
DISJOINT;
}
/** Return whether all values of the given {@link IndexReader} are within the range,
* outside the range or cross the range. The default implementation returns
* {@link Relation#INTERSECTS}, which is always fine to return when there is
* no way to check whether values are actually within bounds. */
public Relation isFieldWithinQuery(
IndexReader reader,
Object from, Object to,
boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.INTERSECTS;
}
/** A term query to use when parsing a query string. Can return <tt>null</tt>. */ /** A term query to use when parsing a query string. Can return <tt>null</tt>. */
@Nullable @Nullable
public Query queryStringTermQuery(Term term) { public Query queryStringTermQuery(Term term) {
@ -424,4 +457,5 @@ public abstract class MappedFieldType extends FieldType {
checkIfFrozen(); checkIfFrozen();
this.eagerGlobalOrdinals = eagerGlobalOrdinals; this.eagerGlobalOrdinals = eagerGlobalOrdinals;
} }
} }

View File

@ -22,6 +22,7 @@ import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Terms; import org.apache.lucene.index.Terms;
import org.apache.lucene.search.LegacyNumericRangeQuery; import org.apache.lucene.search.LegacyNumericRangeQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -181,7 +182,12 @@ public class ByteFieldMapper extends NumberFieldMapper {
} }
@Override @Override
public FieldStats stats(Terms terms, int maxDoc) throws IOException { public FieldStats stats(IndexReader reader) throws IOException {
int maxDoc = reader.maxDoc();
Terms terms = org.apache.lucene.index.MultiFields.getTerms(reader, name());
if (terms == null) {
return null;
}
long minValue = LegacyNumericUtils.getMinInt(terms); long minValue = LegacyNumericUtils.getMinInt(terms);
long maxValue = LegacyNumericUtils.getMaxInt(terms); long maxValue = LegacyNumericUtils.getMaxInt(terms);
return new FieldStats.Long( return new FieldStats.Long(

View File

@ -22,6 +22,7 @@ package org.elasticsearch.index.mapper.core;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiFields;
import org.apache.lucene.index.Terms; import org.apache.lucene.index.Terms;
import org.apache.lucene.search.LegacyNumericRangeQuery; import org.apache.lucene.search.LegacyNumericRangeQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -398,7 +399,12 @@ public class DateFieldMapper extends NumberFieldMapper {
} }
@Override @Override
public FieldStats stats(Terms terms, int maxDoc) throws IOException { public FieldStats stats(IndexReader reader) throws IOException {
int maxDoc = reader.maxDoc();
Terms terms = org.apache.lucene.index.MultiFields.getTerms(reader, name());
if (terms == null) {
return null;
}
long minValue = LegacyNumericUtils.getMinLong(terms); long minValue = LegacyNumericUtils.getMinLong(terms);
long maxValue = LegacyNumericUtils.getMaxLong(terms); long maxValue = LegacyNumericUtils.getMaxLong(terms);
return new FieldStats.Date( return new FieldStats.Date(
@ -417,6 +423,55 @@ public class DateFieldMapper extends NumberFieldMapper {
includeLower, includeUpper); includeLower, includeUpper);
} }
@Override
public Relation isFieldWithinQuery(IndexReader reader,
Object from, Object to,
boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateParser) throws IOException {
if (dateParser == null) {
dateParser = this.dateMathParser;
}
Terms terms = org.apache.lucene.index.MultiFields.getTerms(reader, name());
if (terms == null) {
// no terms, so nothing matches
return Relation.DISJOINT;
}
long minValue = LegacyNumericUtils.getMinLong(terms);
long maxValue = LegacyNumericUtils.getMaxLong(terms);
long fromInclusive = Long.MIN_VALUE;
if (from != null) {
fromInclusive = parseToMilliseconds(from, !includeLower, timeZone, dateParser);
if (includeLower == false) {
if (fromInclusive == Long.MAX_VALUE) {
return Relation.DISJOINT;
}
++fromInclusive;
}
}
long toInclusive = Long.MAX_VALUE;
if (to != null) {
toInclusive = parseToMilliseconds(to, includeUpper, timeZone, dateParser);
if (includeUpper == false) {
if (toInclusive == Long.MIN_VALUE) {
return Relation.DISJOINT;
}
--toInclusive;
}
}
if (minValue >= fromInclusive && maxValue <= toInclusive) {
return Relation.WITHIN;
} else if (maxValue < fromInclusive || minValue > toInclusive) {
return Relation.DISJOINT;
} else {
return Relation.INTERSECTS;
}
}
public long parseToMilliseconds(Object value, boolean inclusive, @Nullable DateTimeZone zone, @Nullable DateMathParser forcedDateParser) { public long parseToMilliseconds(Object value, boolean inclusive, @Nullable DateTimeZone zone, @Nullable DateMathParser forcedDateParser) {
if (value instanceof Long) { if (value instanceof Long) {
return ((Long) value).longValue(); return ((Long) value).longValue();

View File

@ -23,6 +23,7 @@ import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Terms; import org.apache.lucene.index.Terms;
import org.apache.lucene.search.LegacyNumericRangeQuery; import org.apache.lucene.search.LegacyNumericRangeQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -184,7 +185,12 @@ public class DoubleFieldMapper extends NumberFieldMapper {
} }
@Override @Override
public FieldStats stats(Terms terms, int maxDoc) throws IOException { public FieldStats stats(IndexReader reader) throws IOException {
int maxDoc = reader.maxDoc();
Terms terms = org.apache.lucene.index.MultiFields.getTerms(reader, name());
if (terms == null) {
return null;
}
double minValue = NumericUtils.sortableLongToDouble(LegacyNumericUtils.getMinLong(terms)); double minValue = NumericUtils.sortableLongToDouble(LegacyNumericUtils.getMinLong(terms));
double maxValue = NumericUtils.sortableLongToDouble(LegacyNumericUtils.getMaxLong(terms)); double maxValue = NumericUtils.sortableLongToDouble(LegacyNumericUtils.getMaxLong(terms));
return new FieldStats.Double( return new FieldStats.Double(

View File

@ -23,6 +23,7 @@ import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Terms; import org.apache.lucene.index.Terms;
import org.apache.lucene.search.LegacyNumericRangeQuery; import org.apache.lucene.search.LegacyNumericRangeQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -185,7 +186,12 @@ public class FloatFieldMapper extends NumberFieldMapper {
} }
@Override @Override
public FieldStats stats(Terms terms, int maxDoc) throws IOException { public FieldStats stats(IndexReader reader) throws IOException {
int maxDoc = reader.maxDoc();
Terms terms = org.apache.lucene.index.MultiFields.getTerms(reader, name());
if (terms == null) {
return null;
}
float minValue = NumericUtils.sortableIntToFloat(LegacyNumericUtils.getMinInt(terms)); float minValue = NumericUtils.sortableIntToFloat(LegacyNumericUtils.getMinInt(terms));
float maxValue = NumericUtils.sortableIntToFloat(LegacyNumericUtils.getMaxInt(terms)); float maxValue = NumericUtils.sortableIntToFloat(LegacyNumericUtils.getMaxInt(terms));
return new FieldStats.Float( return new FieldStats.Float(

View File

@ -23,6 +23,7 @@ import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Terms; import org.apache.lucene.index.Terms;
import org.apache.lucene.search.LegacyNumericRangeQuery; import org.apache.lucene.search.LegacyNumericRangeQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -190,7 +191,12 @@ public class IntegerFieldMapper extends NumberFieldMapper {
} }
@Override @Override
public FieldStats stats(Terms terms, int maxDoc) throws IOException { public FieldStats stats(IndexReader reader) throws IOException {
int maxDoc = reader.maxDoc();
Terms terms = org.apache.lucene.index.MultiFields.getTerms(reader, name());
if (terms == null) {
return null;
}
long minValue = LegacyNumericUtils.getMinInt(terms); long minValue = LegacyNumericUtils.getMinInt(terms);
long maxValue = LegacyNumericUtils.getMaxInt(terms); long maxValue = LegacyNumericUtils.getMaxInt(terms);
return new FieldStats.Long( return new FieldStats.Long(

View File

@ -23,6 +23,7 @@ import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Terms; import org.apache.lucene.index.Terms;
import org.apache.lucene.search.LegacyNumericRangeQuery; import org.apache.lucene.search.LegacyNumericRangeQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -188,7 +189,12 @@ public class LongFieldMapper extends NumberFieldMapper {
} }
@Override @Override
public FieldStats stats(Terms terms, int maxDoc) throws IOException { public FieldStats stats(IndexReader reader) throws IOException {
int maxDoc = reader.maxDoc();
Terms terms = org.apache.lucene.index.MultiFields.getTerms(reader, name());
if (terms == null) {
return null;
}
long minValue = LegacyNumericUtils.getMinLong(terms); long minValue = LegacyNumericUtils.getMinLong(terms);
long maxValue = LegacyNumericUtils.getMaxLong(terms); long maxValue = LegacyNumericUtils.getMaxLong(terms);
return new FieldStats.Long( return new FieldStats.Long(

View File

@ -23,6 +23,7 @@ import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Terms; import org.apache.lucene.index.Terms;
import org.apache.lucene.search.LegacyNumericRangeQuery; import org.apache.lucene.search.LegacyNumericRangeQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -186,7 +187,12 @@ public class ShortFieldMapper extends NumberFieldMapper {
} }
@Override @Override
public FieldStats stats(Terms terms, int maxDoc) throws IOException { public FieldStats stats(IndexReader reader) throws IOException {
int maxDoc = reader.maxDoc();
Terms terms = org.apache.lucene.index.MultiFields.getTerms(reader, name());
if (terms == null) {
return null;
}
long minValue = LegacyNumericUtils.getMinInt(terms); long minValue = LegacyNumericUtils.getMinInt(terms);
long maxValue = LegacyNumericUtils.getMaxInt(terms); long maxValue = LegacyNumericUtils.getMaxInt(terms);
return new FieldStats.Long( return new FieldStats.Long(

View File

@ -22,6 +22,7 @@ package org.elasticsearch.index.mapper.ip;
import org.apache.lucene.analysis.LegacyNumericTokenStream; import org.apache.lucene.analysis.LegacyNumericTokenStream;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Terms; import org.apache.lucene.index.Terms;
import org.apache.lucene.search.LegacyNumericRangeQuery; import org.apache.lucene.search.LegacyNumericRangeQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -267,10 +268,16 @@ public class IpFieldMapper extends NumberFieldMapper {
} }
@Override @Override
public FieldStats stats(Terms terms, int maxDoc) throws IOException { public FieldStats stats(IndexReader reader) throws IOException {
int maxDoc = reader.maxDoc();
Terms terms = org.apache.lucene.index.MultiFields.getTerms(reader, name());
if (terms == null) {
return null;
}
long minValue = LegacyNumericUtils.getMinLong(terms); long minValue = LegacyNumericUtils.getMinLong(terms);
long maxValue = LegacyNumericUtils.getMaxLong(terms); long maxValue = LegacyNumericUtils.getMaxLong(terms);
return new FieldStats.Ip(maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue); return new FieldStats.Ip(maxDoc, terms.getDocCount(), terms.getSumDocFreq(),
terms.getSumTotalTermFreq(), minValue, maxValue);
} }
@Override @Override

View File

@ -18,9 +18,10 @@
*/ */
package org.elasticsearch.index.query; package org.elasticsearch.index.query;
import org.apache.lucene.index.IndexReader;
import org.elasticsearch.client.Client; import org.elasticsearch.client.Client;
import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.fieldstats.FieldStatsProvider; import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.indices.query.IndicesQueriesRegistry; import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.ScriptService;
@ -28,25 +29,21 @@ import org.elasticsearch.script.ScriptService;
* Context object used to rewrite {@link QueryBuilder} instances into simplified version. * Context object used to rewrite {@link QueryBuilder} instances into simplified version.
*/ */
public class QueryRewriteContext { public class QueryRewriteContext {
protected final MapperService mapperService;
protected final ScriptService scriptService; protected final ScriptService scriptService;
protected final IndexSettings indexSettings; protected final IndexSettings indexSettings;
protected final IndicesQueriesRegistry indicesQueriesRegistry; protected final IndicesQueriesRegistry indicesQueriesRegistry;
protected final QueryParseContext parseContext; protected final QueryParseContext parseContext;
protected FieldStatsProvider fieldStatsProvider; protected final IndexReader reader;
public QueryRewriteContext(IndexSettings indexSettings, ScriptService scriptService, IndicesQueriesRegistry indicesQueriesRegistry) { public QueryRewriteContext(IndexSettings indexSettings, MapperService mapperService, ScriptService scriptService,
IndicesQueriesRegistry indicesQueriesRegistry, IndexReader reader) {
this.mapperService = mapperService;
this.scriptService = scriptService; this.scriptService = scriptService;
this.indexSettings = indexSettings; this.indexSettings = indexSettings;
this.indicesQueriesRegistry = indicesQueriesRegistry; this.indicesQueriesRegistry = indicesQueriesRegistry;
this.parseContext = new QueryParseContext(indicesQueriesRegistry); this.parseContext = new QueryParseContext(indicesQueriesRegistry);
} this.reader = reader;
public void setFieldStatsProvider(FieldStatsProvider fieldStatsProvider) {
this.fieldStatsProvider = fieldStatsProvider;
}
public FieldStatsProvider getFieldStatsProvider() {
return fieldStatsProvider;
} }
/** /**
@ -71,6 +68,18 @@ public class QueryRewriteContext {
return scriptService; return scriptService;
} }
/**
* Return the MapperService.
*/
public final MapperService getMapperService() {
return mapperService;
}
/** Return the current {@link IndexReader}, or {@code null} if we are on the coordinating node. */
public IndexReader getIndexReader() {
return reader;
}
/** /**
* Returns a new {@link QueryParseContext} to parse template or wrapped queries. * Returns a new {@link QueryParseContext} to parse template or wrapped queries.
*/ */

View File

@ -20,6 +20,7 @@
package org.elasticsearch.index.query; package org.elasticsearch.index.query;
import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.MapperQueryParser; import org.apache.lucene.queryparser.classic.MapperQueryParser;
import org.apache.lucene.queryparser.classic.QueryParserSettings; import org.apache.lucene.queryparser.classic.QueryParserSettings;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -95,8 +96,8 @@ public class QueryShardContext extends QueryRewriteContext {
boolean isFilter; // pkg private for testing boolean isFilter; // pkg private for testing
public QueryShardContext(IndexSettings indexSettings, BitsetFilterCache bitsetFilterCache, IndexFieldDataService indexFieldDataService, MapperService mapperService, SimilarityService similarityService, ScriptService scriptService, public QueryShardContext(IndexSettings indexSettings, BitsetFilterCache bitsetFilterCache, IndexFieldDataService indexFieldDataService, MapperService mapperService, SimilarityService similarityService, ScriptService scriptService,
final IndicesQueriesRegistry indicesQueriesRegistry, PercolatorQueryCache percolatorQueryCache) { final IndicesQueriesRegistry indicesQueriesRegistry, PercolatorQueryCache percolatorQueryCache, IndexReader reader) {
super(indexSettings, scriptService, indicesQueriesRegistry); super(indexSettings, mapperService, scriptService, indicesQueriesRegistry, reader);
this.indexSettings = indexSettings; this.indexSettings = indexSettings;
this.similarityService = similarityService; this.similarityService = similarityService;
this.mapperService = mapperService; this.mapperService = mapperService;
@ -109,16 +110,10 @@ public class QueryShardContext extends QueryRewriteContext {
} }
public QueryShardContext(QueryShardContext source) { public QueryShardContext(QueryShardContext source) {
this(source.indexSettings, source.bitsetFilterCache, source.indexFieldDataService, source.mapperService, source.similarityService, source.scriptService, source.indicesQueriesRegistry, source.percolatorQueryCache); this(source.indexSettings, source.bitsetFilterCache, source.indexFieldDataService, source.mapperService, source.similarityService, source.scriptService, source.indicesQueriesRegistry, source.percolatorQueryCache, source.reader);
this.types = source.getTypes(); this.types = source.getTypes();
} }
@Override
public QueryShardContext clone() {
return new QueryShardContext(indexSettings, bitsetFilterCache, indexFieldDataService, mapperService, similarityService, scriptService, indicesQueriesRegistry, percolatorQueryCache);
}
public void parseFieldMatcher(ParseFieldMatcher parseFieldMatcher) { public void parseFieldMatcher(ParseFieldMatcher parseFieldMatcher) {
this.parseContext.parseFieldMatcher(parseFieldMatcher); this.parseContext.parseFieldMatcher(parseFieldMatcher);
} }
@ -145,10 +140,6 @@ public class QueryShardContext extends QueryRewriteContext {
return mapperService.analysisService(); return mapperService.analysisService();
} }
public MapperService getMapperService() {
return mapperService;
}
public PercolatorQueryCache getPercolatorQueryCache() { public PercolatorQueryCache getPercolatorQueryCache() {
return percolatorQueryCache; return percolatorQueryCache;
} }

View File

@ -19,6 +19,7 @@
package org.elasticsearch.index.query; package org.elasticsearch.index.query;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermRangeQuery; import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
@ -30,8 +31,8 @@ import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.joda.Joda; import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.lucene.BytesRefs; import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.fieldstats.FieldStatsProvider;
import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.core.DateFieldMapper; import org.elasticsearch.index.mapper.core.DateFieldMapper;
import org.joda.time.DateTimeZone; import org.joda.time.DateTimeZone;
@ -254,15 +255,28 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
return NAME; return NAME;
} }
// Overridable for testing only
protected MappedFieldType.Relation getRelation(QueryRewriteContext queryRewriteContext) throws IOException {
IndexReader reader = queryRewriteContext.getIndexReader();
// If the reader is null we are not on the shard and cannot
// rewrite so just pretend there is an intersection so that the rewrite is a noop
if (reader == null) {
return MappedFieldType.Relation.INTERSECTS;
}
final MapperService mapperService = queryRewriteContext.getMapperService();
final MappedFieldType fieldType = mapperService.fullName(fieldName);
if (fieldType == null) {
// no field means we have no values
return MappedFieldType.Relation.DISJOINT;
} else {
DateMathParser dateMathParser = format == null ? null : new DateMathParser(format);
return fieldType.isFieldWithinQuery(queryRewriteContext.getIndexReader(), from, to, includeLower, includeUpper, timeZone, dateMathParser);
}
}
@Override @Override
protected QueryBuilder<?> doRewrite(QueryRewriteContext queryRewriteContext) throws IOException { protected QueryBuilder<?> doRewrite(QueryRewriteContext queryRewriteContext) throws IOException {
FieldStatsProvider fieldStatsProvider = queryRewriteContext.getFieldStatsProvider(); final MappedFieldType.Relation relation = getRelation(queryRewriteContext);
// If the fieldStatsProvider is null we are not on the shard and cannot
// rewrite so just return without rewriting
if (fieldStatsProvider != null) {
DateMathParser dateMathParser = format == null ? null : new DateMathParser(format);
FieldStatsProvider.Relation relation = fieldStatsProvider.isFieldWithinQuery(fieldName, from, to, includeLower, includeUpper,
timeZone, dateMathParser);
switch (relation) { switch (relation) {
case DISJOINT: case DISJOINT:
return new MatchNoneQueryBuilder(); return new MatchNoneQueryBuilder();
@ -278,10 +292,10 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
return this; return this;
} }
case INTERSECTS: case INTERSECTS:
break;
}
}
return this; return this;
default:
throw new AssertionError();
}
} }
@Override @Override

View File

@ -48,7 +48,6 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.Index; import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexService; import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.engine.Engine; import org.elasticsearch.index.engine.Engine;
import org.elasticsearch.index.fieldstats.FieldStatsProvider;
import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.support.InnerHitBuilder; import org.elasticsearch.index.query.support.InnerHitBuilder;
@ -552,7 +551,6 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> imp
indexService, indexService,
indexShard, scriptService, pageCacheRecycler, bigArrays, threadPool.estimatedTimeInMillisCounter(), parseFieldMatcher, indexShard, scriptService, pageCacheRecycler, bigArrays, threadPool.estimatedTimeInMillisCounter(), parseFieldMatcher,
defaultSearchTimeout, fetchPhase); defaultSearchTimeout, fetchPhase);
context.getQueryShardContext().setFieldStatsProvider(new FieldStatsProvider(engineSearcher, indexService.mapperService()));
SearchContext.setCurrent(context); SearchContext.setCurrent(context);
request.rewrite(context.getQueryShardContext()); request.rewrite(context.getQueryShardContext());
// reset that we have used nowInMillis from the context since it may // reset that we have used nowInMillis from the context since it may

View File

@ -176,7 +176,7 @@ public class DefaultSearchContext extends SearchContext {
this.searcher = new ContextIndexSearcher(engineSearcher, indexService.cache().query(), indexShard.getQueryCachingPolicy()); this.searcher = new ContextIndexSearcher(engineSearcher, indexService.cache().query(), indexShard.getQueryCachingPolicy());
this.timeEstimateCounter = timeEstimateCounter; this.timeEstimateCounter = timeEstimateCounter;
this.timeoutInMillis = timeout.millis(); this.timeoutInMillis = timeout.millis();
queryShardContext = indexService.newQueryShardContext(); queryShardContext = indexService.newQueryShardContext(searcher.getIndexReader());
queryShardContext.setTypes(request.types()); queryShardContext.setTypes(request.types());
} }

View File

@ -1,446 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.index.fieldstats;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.BaseDirectoryWrapper;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.lucene.index.ElasticsearchDirectoryReader;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.env.Environment;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.analysis.AnalysisRegistry;
import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.engine.Engine;
import org.elasticsearch.index.engine.Engine.Searcher;
import org.elasticsearch.index.fieldstats.FieldStatsProvider.Relation;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.MapperService.MergeReason;
import org.elasticsearch.index.mapper.ParsedDocument;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.indices.IndicesModule;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.IndexSettingsModule;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.chrono.ISOChronology;
import org.junit.After;
import org.junit.Before;
import java.io.IOException;
import java.util.Collections;
import static org.elasticsearch.common.settings.Settings.settingsBuilder;
import static org.hamcrest.Matchers.equalTo;
public class FieldStatsProviderTests extends ESTestCase {
private DirectoryReader directoryReader;
private Searcher searcher;
private FieldStatsProvider fieldStatsProvider;
private BaseDirectoryWrapper dir;
private AnalysisRegistry analysisRegistry;
@Before
public void setup() throws IOException {
Settings nodeSettings = settingsBuilder().put(Environment.PATH_HOME_SETTING.getKey(), createTempDir()).build();
IndexSettings settings = IndexSettingsModule.newIndexSettings("_na", nodeSettings);
SimilarityService similarityService = new SimilarityService(settings, Collections.emptyMap());
analysisRegistry = new AnalysisRegistry(null, new Environment(nodeSettings));
AnalysisService analysisService = analysisRegistry.build(settings);
IndicesModule indicesModule = new IndicesModule();
MapperRegistry mapperRegistry = indicesModule.getMapperRegistry();
MapperService service = new MapperService(settings, analysisService, similarityService, mapperRegistry, () -> null);
putMapping(service);
dir = newDirectory();
IndexWriter w = new IndexWriter(dir, newIndexWriterConfig());
indexDocument(service, w, "1", 50L, 50.2f, 50.2, "cherry", new DateTime(2014, 1, 1, 0, 0, 0, ISOChronology.getInstanceUTC()),
"10.10.0.10");
indexDocument(service, w, "2", 60L, 60.1f, 60.1, "damson", new DateTime(2014, 2, 1, 0, 0, 0, ISOChronology.getInstanceUTC()),
"10.10.0.20");
indexDocument(service, w, "3", 70L, 70.6f, 70.6, "grape", new DateTime(2014, 3, 1, 0, 0, 0, ISOChronology.getInstanceUTC()),
"10.10.0.30");
indexDocument(service, w, "4", 80L, 80.2f, 80.2, "kiwi", new DateTime(2014, 4, 1, 0, 0, 0, ISOChronology.getInstanceUTC()),
"10.10.0.40");
indexDocument(service, w, "5", 90L, 90.4f, 90.4, "lemon", new DateTime(2014, 5, 1, 0, 0, 0, ISOChronology.getInstanceUTC()),
"10.10.0.50");
indexDocument(service, w, "6", 100L, 100.3f, 100.3, "orange", new DateTime(2014, 6, 1, 0, 0, 0, ISOChronology.getInstanceUTC()),
"10.10.0.60");
directoryReader = DirectoryReader.open(w, true, true);
w.close();
ShardId shard = new ShardId("index", "_na_", 0);
directoryReader = ElasticsearchDirectoryReader.wrap(directoryReader, shard);
IndexSearcher s = new IndexSearcher(directoryReader);
searcher = new Engine.Searcher("test", s);
fieldStatsProvider = new FieldStatsProvider(searcher, service);
}
@After
public void teardown() throws IOException {
searcher.close();
directoryReader.close();
dir.close();
analysisRegistry.close();
}
public void testiIsFieldWithinQueryLong() throws IOException {
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 10L, 200L, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 10L, null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", null, 200L, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", null, null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 10L, 100L, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 50L, 200L, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 30L, 80L, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 80L, 200L, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 60L, 80L, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 10L, 100L, true, false, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 50L, 200L, false, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 100L, 200L, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 1L, 50L, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 150L, 200L, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 1L, 8L, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", null, 8L, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 150L, null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 100L, 200L, false, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 1L, 50L, true, false, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
}
public void testiIsFieldWithinQueryFloat() throws IOException {
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 10.8f, 200.5f, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 10.8f, null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", null, 200.5f, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", null, null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 10.8f, 100.3f, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 50.2f, 200.5f, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 30.5f, 80.1f, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 80.1f, 200.5f, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 10.8f, 100.3f, true, false, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 50.2f, 200.5f, false, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 100.3f, 200.5f, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 1.9f, 50.2f, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 60.9f, 80.1f, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 150.4f, 200.5f, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 1.9f, 8.1f, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", null, 8.1f, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 150.4f, null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 100.3f, 200.5f, false, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("float_field", 1.9f, 50.2f, true, false, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
}
public void testiIsFieldWithinQueryDouble() throws IOException {
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", 10.8, 200.5, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", 10.8, null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", null, 200.5, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", null, null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", 10.8, 100.3, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", 50.2, 200.5, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", 30.5, 80.1, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", 80.1, 200.5, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", 60.9, 80.1, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", 10.8, 100.3, true, false, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", 50.2, 200.5, false, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", 100.3, 200.5, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", 1.9, 50.2, true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", 150.4, 200.5, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", 1.9, 8.1, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", null, 8.1, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("double_field", 150.4, null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 100.3, 200.5, false, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("long_field", 1.9, 50.2, true, false, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
}
public void testiIsFieldWithinQueryText() throws IOException {
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("banana"), new BytesRef("zebra"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("banana"), null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", null, new BytesRef("zebra"), true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", null, null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("banana"), new BytesRef("orange"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("cherry"), new BytesRef("zebra"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("banana"), new BytesRef("grape"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("grape"), new BytesRef("zebra"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("lime"), new BytesRef("mango"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("banana"), new BytesRef("orange"), true, false,
DateTimeZone.UTC, null), equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("cherry"), new BytesRef("zebra"), false, true,
DateTimeZone.UTC, null), equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("orange"), new BytesRef("zebra"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("apple"), new BytesRef("cherry"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("peach"), new BytesRef("zebra"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("apple"), new BytesRef("banana"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", null, new BytesRef("banana"), true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("peach"), null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("orange"), new BytesRef("zebra"), false, true,
DateTimeZone.UTC, null), equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("text_field", new BytesRef("apple"), new BytesRef("cherry"), true, false,
DateTimeZone.UTC, null), equalTo(Relation.DISJOINT));
}
public void testiIsFieldWithinQueryKeyword() throws IOException {
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("banana"), new BytesRef("zebra"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("banana"), null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", null, new BytesRef("zebra"), true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", null, null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("banana"), new BytesRef("orange"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("cherry"), new BytesRef("zebra"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("banana"), new BytesRef("grape"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("grape"), new BytesRef("zebra"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("lime"), new BytesRef("mango"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("banana"), new BytesRef("orange"), true, false,
DateTimeZone.UTC, null), equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("cherry"), new BytesRef("zebra"), false, true,
DateTimeZone.UTC, null), equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("orange"), new BytesRef("zebra"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("apple"), new BytesRef("cherry"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("peach"), new BytesRef("zebra"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("apple"), new BytesRef("banana"), true, true,
DateTimeZone.UTC, null), equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", null, new BytesRef("banana"), true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("peach"), null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("orange"), new BytesRef("zebra"), false, true,
DateTimeZone.UTC, null), equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("keyword_field", new BytesRef("apple"), new BytesRef("cherry"), true, false,
DateTimeZone.UTC, null), equalTo(Relation.DISJOINT));
}
public void testiIsFieldWithinQueryDate() throws IOException {
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2013-01-01", "now", true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2013-01-01", null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", null, "now", true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", null, null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2013-01-01", "2014-06-01", true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2014-01-01", "now", true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2013-01-01", "2014-03-01", true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2014-03-01", "now", true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2014-03-01", "2014-05-01", true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2013-01-01", "2014-06-01", true, false, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2014-01-01", "now", false, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2014-06-01", "now", true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2013-01-01", "2014-01-01", true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2015-01-01", "now", true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2013-01-01", "2013-09-01", true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", null, "2013-09-01", true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2015-01-01", null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2014-06-01", "now", false, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("date_field", "2013-01-01", "2014-01-01", true, false, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
}
public void testiIsFieldWithinQueryIp() throws IOException {
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.10.0.1", "10.20.0.1", true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.10.0.1", null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", null, "10.20.0.1", true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", null, null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.10.0.1", "10.10.0.60", true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.10.0.10", "10.20.0.1", true, true, DateTimeZone.UTC, null),
equalTo(Relation.WITHIN));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.10.0.1", "10.10.0.40", true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.10.0.40", "10.20.0.1", true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.10.0.30", "10.10.0.40", true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.10.0.1", "10.10.0.60", true, false, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.10.0.10", "10.20.0.1", false, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.10.0.60", "10.20.0.1", true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.0.0.1", "10.10.0.10", true, true, DateTimeZone.UTC, null),
equalTo(Relation.INTERSECTS));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.20.0.10", "10.20.0.1", true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.0.0.1", "10.0.0.100", true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", null, "10.0.0.100", true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.20.0.10", null, true, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.10.0.60", "10.20.0.1", false, true, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
assertThat(fieldStatsProvider.isFieldWithinQuery("ip_field", "10.0.0.1", "10.10.0.10", true, false, DateTimeZone.UTC, null),
equalTo(Relation.DISJOINT));
}
private void putMapping(MapperService service) throws IOException {
XContentBuilder mappingbuilder = JsonXContent.contentBuilder();
mappingbuilder.startObject();
mappingbuilder.startObject("type");
mappingbuilder.startObject("properties");
mappingbuilder.startObject("long_field");
mappingbuilder.field("type", "long");
mappingbuilder.endObject();
mappingbuilder.startObject("float_field");
mappingbuilder.field("type", "float");
mappingbuilder.endObject();
mappingbuilder.startObject("double_field");
mappingbuilder.field("type", "double");
mappingbuilder.endObject();
mappingbuilder.startObject("text_field");
mappingbuilder.field("type", "text");
mappingbuilder.endObject();
mappingbuilder.startObject("keyword_field");
mappingbuilder.field("type", "keyword");
mappingbuilder.endObject();
mappingbuilder.startObject("date_field");
mappingbuilder.field("type", "date");
mappingbuilder.endObject();
mappingbuilder.startObject("ip_field");
mappingbuilder.field("type", "ip");
mappingbuilder.endObject();
mappingbuilder.endObject();
mappingbuilder.endObject();
mappingbuilder.endObject();
service.merge("type", new CompressedXContent(mappingbuilder.bytes()), MergeReason.MAPPING_UPDATE, true);
}
private void indexDocument(MapperService service, IndexWriter writer, String id, long longValue, float floatValue, double doubleValue,
String stringValue, DateTime dateValue, String ipValue) throws IOException {
XContentBuilder docBuilder = JsonXContent.contentBuilder();
docBuilder.startObject();
docBuilder.field("long_field", longValue);
docBuilder.field("float_field", floatValue);
docBuilder.field("double_field", doubleValue);
docBuilder.field("text_field", stringValue);
docBuilder.field("keyword_field", stringValue);
docBuilder.field("date_field", dateValue);
docBuilder.field("ip_field", ipValue);
docBuilder.endObject();
DocumentMapper documentMapper = service.documentMapper("type");
ParsedDocument doc = documentMapper.parse("index", "type", id, docBuilder.bytes());
writer.addDocument(doc.rootDoc());
}
}

View File

@ -18,11 +18,27 @@
*/ */
package org.elasticsearch.index.mapper.core; package org.elasticsearch.index.mapper.core;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.LegacyLongField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.MultiReader;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.IOUtils;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.joda.Joda; import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.index.mapper.FieldTypeTestCase; import org.elasticsearch.index.mapper.FieldTypeTestCase;
import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MappedFieldType.Relation;
import org.elasticsearch.index.mapper.ParseContext.Document;
import org.elasticsearch.index.mapper.core.DateFieldMapper.DateFieldType;
import org.joda.time.DateTimeZone;
import org.junit.Before; import org.junit.Before;
import java.io.IOException;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -54,4 +70,58 @@ public class DateFieldTypeTests extends FieldTypeTestCase {
} }
}); });
} }
public void testIsFieldWithinQueryEmptyReader() throws IOException {
IndexReader reader = new MultiReader();
DateFieldType ft = new DateFieldType();
ft.setName("my_date");
assertEquals(Relation.DISJOINT, ft.isFieldWithinQuery(reader, "2015-10-12", "2016-04-03",
randomBoolean(), randomBoolean(), null, null));
}
private void doTestIsFieldWithinQuery(DateFieldType ft, DirectoryReader reader,
DateTimeZone zone, DateMathParser alternateFormat) throws IOException {
assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(reader, "2015-10-09", "2016-01-02",
randomBoolean(), randomBoolean(), null, null));
assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(reader, "2016-01-02", "2016-06-20",
randomBoolean(), randomBoolean(), null, null));
assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(reader, "2016-01-02", "2016-02-12",
randomBoolean(), randomBoolean(), null, null));
assertEquals(Relation.DISJOINT, ft.isFieldWithinQuery(reader, "2014-01-02", "2015-02-12",
randomBoolean(), randomBoolean(), null, null));
assertEquals(Relation.DISJOINT, ft.isFieldWithinQuery(reader, "2016-05-11", "2016-08-30",
randomBoolean(), randomBoolean(), null, null));
assertEquals(Relation.WITHIN, ft.isFieldWithinQuery(reader, "2015-09-25", "2016-05-29",
randomBoolean(), randomBoolean(), null, null));
assertEquals(Relation.WITHIN, ft.isFieldWithinQuery(reader, "2015-10-12", "2016-04-03",
true, true, null, null));
assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(reader, "2015-10-12", "2016-04-03",
false, false, null, null));
assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(reader, "2015-10-12", "2016-04-03",
false, true, null, null));
assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(reader, "2015-10-12", "2016-04-03",
true, false, null, null));
}
public void testIsFieldWithinQuery() throws IOException {
Directory dir = newDirectory();
IndexWriter w = new IndexWriter(dir, new IndexWriterConfig(null));
long instant1 = DateFieldMapper.Defaults.DATE_TIME_FORMATTER.parser().parseDateTime("2015-10-12").getMillis();
long instant2 = DateFieldMapper.Defaults.DATE_TIME_FORMATTER.parser().parseDateTime("2016-04-03").getMillis();
Document doc = new Document();
LegacyLongField field = new LegacyLongField("my_date", instant1, Store.NO);
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");
DateMathParser alternateFormat = new DateMathParser(DateFieldMapper.Defaults.DATE_TIME_FORMATTER);
doTestIsFieldWithinQuery(ft, reader, null, null);
doTestIsFieldWithinQuery(ft, reader, null, alternateFormat);
doTestIsFieldWithinQuery(ft, reader, DateTimeZone.UTC, null);
doTestIsFieldWithinQuery(ft, reader, DateTimeZone.UTC, alternateFormat);
IOUtils.close(reader, w, dir);
}
} }

View File

@ -20,8 +20,12 @@ package org.elasticsearch.index.mapper.core;
import org.elasticsearch.index.mapper.FieldTypeTestCase; import org.elasticsearch.index.mapper.FieldTypeTestCase;
import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MappedFieldType.Relation;
import org.elasticsearch.index.mapper.core.DoubleFieldMapper.DoubleFieldType;
import org.junit.Before; import org.junit.Before;
import java.io.IOException;
public class DoubleFieldTypeTests extends FieldTypeTestCase { public class DoubleFieldTypeTests extends FieldTypeTestCase {
@Override @Override
protected MappedFieldType createDefaultFieldType() { protected MappedFieldType createDefaultFieldType() {
@ -32,4 +36,11 @@ public class DoubleFieldTypeTests extends FieldTypeTestCase {
public void setupProperties() { public void setupProperties() {
setDummyNullValue(10.0D); setDummyNullValue(10.0D);
} }
public void testIsFieldWithinQuery() throws IOException {
DoubleFieldType ft = new DoubleFieldType();
// current impl ignores args and shourd always return INTERSECTS
assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(null, randomDouble(), randomDouble(),
randomBoolean(), randomBoolean(), null, null));
}
} }

View File

@ -20,8 +20,12 @@ package org.elasticsearch.index.mapper.core;
import org.elasticsearch.index.mapper.FieldTypeTestCase; import org.elasticsearch.index.mapper.FieldTypeTestCase;
import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MappedFieldType.Relation;
import org.elasticsearch.index.mapper.core.FloatFieldMapper.FloatFieldType;
import org.junit.Before; import org.junit.Before;
import java.io.IOException;
public class FloatFieldTypeTests extends FieldTypeTestCase { public class FloatFieldTypeTests extends FieldTypeTestCase {
@Override @Override
protected MappedFieldType createDefaultFieldType() { protected MappedFieldType createDefaultFieldType() {
@ -32,4 +36,11 @@ public class FloatFieldTypeTests extends FieldTypeTestCase {
public void setupProperties() { public void setupProperties() {
setDummyNullValue(10.0); setDummyNullValue(10.0);
} }
public void testIsFieldWithinQuery() throws IOException {
FloatFieldType ft = new FloatFieldType();
// current impl ignores args and shourd always return INTERSECTS
assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(null, randomFloat(), randomFloat(),
randomBoolean(), randomBoolean(), null, null));
}
} }

View File

@ -20,8 +20,12 @@ package org.elasticsearch.index.mapper.core;
import org.elasticsearch.index.mapper.FieldTypeTestCase; import org.elasticsearch.index.mapper.FieldTypeTestCase;
import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MappedFieldType.Relation;
import org.elasticsearch.index.mapper.core.IntegerFieldMapper.IntegerFieldType;
import org.junit.Before; import org.junit.Before;
import java.io.IOException;
public class IntegerFieldTypeTests extends FieldTypeTestCase { public class IntegerFieldTypeTests extends FieldTypeTestCase {
@Override @Override
protected MappedFieldType createDefaultFieldType() { protected MappedFieldType createDefaultFieldType() {
@ -32,4 +36,11 @@ public class IntegerFieldTypeTests extends FieldTypeTestCase {
public void setupProperties() { public void setupProperties() {
setDummyNullValue(10); setDummyNullValue(10);
} }
public void testIsFieldWithinQuery() throws IOException {
IntegerFieldType ft = new IntegerFieldType();
// current impl ignores args and shourd always return INTERSECTS
assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(null, randomInt(), randomInt(),
randomBoolean(), randomBoolean(), null, null));
}
} }

View File

@ -18,12 +18,27 @@
*/ */
package org.elasticsearch.index.mapper.core; package org.elasticsearch.index.mapper.core;
import com.carrotsearch.randomizedtesting.generators.RandomStrings;
import org.elasticsearch.index.mapper.FieldTypeTestCase; import org.elasticsearch.index.mapper.FieldTypeTestCase;
import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MappedFieldType.Relation;
import org.elasticsearch.index.mapper.core.KeywordFieldMapper.KeywordFieldType;
import java.io.IOException;
public class KeywordFieldTypeTests extends FieldTypeTestCase { public class KeywordFieldTypeTests extends FieldTypeTestCase {
@Override @Override
protected MappedFieldType createDefaultFieldType() { protected MappedFieldType createDefaultFieldType() {
return new KeywordFieldMapper.KeywordFieldType(); return new KeywordFieldMapper.KeywordFieldType();
} }
public void testIsFieldWithinQuery() throws IOException {
KeywordFieldType ft = new KeywordFieldType();
// current impl ignores args and shourd always return INTERSECTS
assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(null,
RandomStrings.randomAsciiOfLengthBetween(random(), 0, 5),
RandomStrings.randomAsciiOfLengthBetween(random(), 0, 5),
randomBoolean(), randomBoolean(), null, null));
}
} }

View File

@ -20,8 +20,12 @@ package org.elasticsearch.index.mapper.core;
import org.elasticsearch.index.mapper.FieldTypeTestCase; import org.elasticsearch.index.mapper.FieldTypeTestCase;
import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MappedFieldType.Relation;
import org.elasticsearch.index.mapper.core.LongFieldMapper.LongFieldType;
import org.junit.Before; import org.junit.Before;
import java.io.IOException;
public class LongFieldTypeTests extends FieldTypeTestCase { public class LongFieldTypeTests extends FieldTypeTestCase {
@Override @Override
protected MappedFieldType createDefaultFieldType() { protected MappedFieldType createDefaultFieldType() {
@ -32,4 +36,11 @@ public class LongFieldTypeTests extends FieldTypeTestCase {
public void setupProperties() { public void setupProperties() {
setDummyNullValue((long)10); setDummyNullValue((long)10);
} }
public void testIsFieldWithinQuery() throws IOException {
LongFieldType ft = new LongFieldType();
// current impl ignores args and shourd always return INTERSECTS
assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(null, randomLong(), randomLong(),
randomBoolean(), randomBoolean(), null, null));
}
} }

View File

@ -117,7 +117,7 @@ public class PercolatorQueryCacheTests extends ESTestCase {
MapperService.MergeReason.MAPPING_UPDATE, false); MapperService.MergeReason.MAPPING_UPDATE, false);
cache = new PercolatorQueryCache(idxSettings, () -> queryShardContext); cache = new PercolatorQueryCache(idxSettings, () -> queryShardContext);
queryShardContext = new QueryShardContext(idxSettings, null, null, mapperService, similarityService, null, queryShardContext = new QueryShardContext(idxSettings, null, null, mapperService, similarityService, null,
indicesQueriesRegistry, cache); indicesQueriesRegistry, cache, null);
} }
public void testLoadQueries() throws Exception { public void testLoadQueries() throws Exception {

View File

@ -287,7 +287,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
}); });
PercolatorQueryCache percolatorQueryCache = new PercolatorQueryCache(idxSettings, () -> queryShardContext); PercolatorQueryCache percolatorQueryCache = new PercolatorQueryCache(idxSettings, () -> queryShardContext);
indicesQueriesRegistry = injector.getInstance(IndicesQueriesRegistry.class); indicesQueriesRegistry = injector.getInstance(IndicesQueriesRegistry.class);
queryShardContext = new QueryShardContext(idxSettings, bitsetFilterCache, indexFieldDataService, mapperService, similarityService, scriptService, indicesQueriesRegistry, percolatorQueryCache); queryShardContext = new QueryShardContext(idxSettings, bitsetFilterCache, indexFieldDataService, mapperService, similarityService, scriptService, indicesQueriesRegistry, percolatorQueryCache, null);
//create some random type with some default field, those types will stick around for all of the subclasses //create some random type with some default field, those types will stick around for all of the subclasses
currentTypes = new String[randomIntBetween(0, 5)]; currentTypes = new String[randomIntBetween(0, 5)];
for (int i = 0; i < currentTypes.length; i++) { for (int i = 0; i < currentTypes.length; i++) {
@ -341,7 +341,6 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
@After @After
public void afterTest() { public void afterTest() {
queryShardContext.setFieldStatsProvider(null);
clientInvocationHandler.delegate = null; clientInvocationHandler.delegate = null;
SearchContext.removeCurrent(); SearchContext.removeCurrent();
} }

View File

@ -47,7 +47,7 @@ public class QueryShardContextTests extends ESTestCase {
MapperService mapperService = mock(MapperService.class); MapperService mapperService = mock(MapperService.class);
when(mapperService.getIndexSettings()).thenReturn(indexSettings); when(mapperService.getIndexSettings()).thenReturn(indexSettings);
QueryShardContext context = new QueryShardContext( QueryShardContext context = new QueryShardContext(
indexSettings, null, null, mapperService, null, null, null, null indexSettings, null, null, mapperService, null, null, null, null, null
); );
context.setAllowUnmappedFields(false); context.setAllowUnmappedFields(false);

View File

@ -22,13 +22,11 @@ package org.elasticsearch.index.query;
import org.apache.lucene.search.LegacyNumericRangeQuery; import org.apache.lucene.search.LegacyNumericRangeQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermRangeQuery; import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.action.fieldstats.FieldStats;
import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.lucene.BytesRefs; import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.index.fieldstats.FieldStatsProvider; import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MappedFieldType.Relation;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.DateTimeZone; import org.joda.time.DateTimeZone;
import org.joda.time.chrono.ISOChronology; import org.joda.time.chrono.ISOChronology;
@ -399,317 +397,13 @@ public class RangeQueryBuilderTests extends AbstractQueryTestCase<RangeQueryBuil
} }
} }
public void testRewriteLongToMatchAll() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName);
int queryFromValue = randomIntBetween(-1000000, 1000000);
int queryToValue = randomIntBetween(queryFromValue, 2000000);
long shardMinValue = randomIntBetween(queryFromValue, queryToValue);
long shardMaxValue = randomIntBetween((int) shardMinValue, queryToValue);
query.from((long) queryFromValue);
query.to((long) queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.WITHIN;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Comparable<T>> FieldStats<T> get(String field) throws IOException {
assertThat(field, equalTo(fieldName));
return (FieldStats<T>) new FieldStats.Long(randomLong(), randomLong(), randomLong(), randomLong(), shardMinValue,
shardMaxValue);
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, instanceOf(RangeQueryBuilder.class));
RangeQueryBuilder rewrittenRange = (RangeQueryBuilder) rewritten;
assertThat(rewrittenRange.fieldName(), equalTo(fieldName));
assertThat(rewrittenRange.from(), equalTo(null));
assertThat(rewrittenRange.to(), equalTo(null));
}
public void testRewriteLongToMatchNone() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName);
int queryFromValue = randomIntBetween(-1000000, 1000000);
int queryToValue = randomIntBetween(queryFromValue, 2000000);
query.from((long) queryFromValue);
query.to((long) queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.DISJOINT;
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, instanceOf(MatchNoneQueryBuilder.class));
}
public void testRewriteLongToSame() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName);
int queryFromValue = randomIntBetween(-1000000, 1000000);
int queryToValue = randomIntBetween(queryFromValue, 2000000);
query.from((long) queryFromValue);
query.to((long) queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.INTERSECTS;
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, sameInstance(query));
}
public void testRewriteDoubleToMatchAll() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName);
double queryFromValue = randomDoubleBetween(-1000000.0, 1000000.0, true);
double queryToValue = randomDoubleBetween(queryFromValue, 2000000, true);
double shardMinValue = randomDoubleBetween(queryFromValue, queryToValue, true);
double shardMaxValue = randomDoubleBetween(shardMinValue, queryToValue, true);
query.from(queryFromValue);
query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.WITHIN;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Comparable<T>> FieldStats<T> get(String field) throws IOException {
assertThat(field, equalTo(fieldName));
return (FieldStats<T>) new FieldStats.Double(randomLong(), randomLong(), randomLong(), randomLong(), shardMinValue,
shardMaxValue);
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, instanceOf(RangeQueryBuilder.class));
RangeQueryBuilder rewrittenRange = (RangeQueryBuilder) rewritten;
assertThat(rewrittenRange.fieldName(), equalTo(fieldName));
assertThat(rewrittenRange.from(), equalTo(null));
assertThat(rewrittenRange.to(), equalTo(null));
}
public void testRewriteDoubleToMatchNone() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName);
double queryFromValue = randomDoubleBetween(-1000000, 1000000, true);
double queryToValue = randomDoubleBetween(queryFromValue, 2000000, true);
query.from(queryFromValue);
query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.DISJOINT;
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, instanceOf(MatchNoneQueryBuilder.class));
}
public void testRewriteDoubleToSame() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName);
double queryFromValue = randomDoubleBetween(-1000000, 1000000, true);
double queryToValue = randomDoubleBetween(queryFromValue, 2000000, true);
query.from(queryFromValue);
query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.INTERSECTS;
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, sameInstance(query));
}
public void testRewriteFloatToMatchAll() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName);
float queryFromValue = (float) randomDoubleBetween(-1000000.0, 1000000.0, true);
float queryToValue = (float) randomDoubleBetween(queryFromValue, 2000000, true);
float shardMinValue = (float) randomDoubleBetween(queryFromValue, queryToValue, true);
float shardMaxValue = (float) randomDoubleBetween(shardMinValue, queryToValue, true);
query.from(queryFromValue);
query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.WITHIN;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Comparable<T>> FieldStats<T> get(String field) throws IOException {
assertThat(field, equalTo(fieldName));
return (FieldStats<T>) new FieldStats.Float(randomLong(), randomLong(), randomLong(), randomLong(), shardMinValue,
shardMaxValue);
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, instanceOf(RangeQueryBuilder.class));
RangeQueryBuilder rewrittenRange = (RangeQueryBuilder) rewritten;
assertThat(rewrittenRange.fieldName(), equalTo(fieldName));
assertThat(rewrittenRange.from(), equalTo(null));
assertThat(rewrittenRange.to(), equalTo(null));
}
public void testRewriteFloatToMatchNone() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName);
float queryFromValue = (float) randomDoubleBetween(-1000000, 1000000, true);
float queryToValue = (float) randomDoubleBetween(queryFromValue, 2000000, true);
query.from(queryFromValue);
query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.DISJOINT;
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, instanceOf(MatchNoneQueryBuilder.class));
}
public void testRewriteFloatToSame() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName);
float queryFromValue = (float) randomDoubleBetween(-1000000, 1000000, true);
float queryToValue = (float) randomDoubleBetween(queryFromValue, 2000000, true);
query.from(queryFromValue);
query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.INTERSECTS;
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, sameInstance(query));
}
public void testRewriteTextToMatchAll() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName);
String queryFromValue = "damson";
String queryToValue = "plum";
String shardMinValue = "grape";
String shardMaxValue = "orange";
query.from(queryFromValue);
query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.WITHIN;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Comparable<T>> FieldStats<T> get(String field) throws IOException {
assertThat(field, equalTo(fieldName));
return (FieldStats<T>) new FieldStats.Text(randomLong(), randomLong(), randomLong(), randomLong(),
new BytesRef(shardMinValue), new BytesRef(shardMaxValue));
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, instanceOf(RangeQueryBuilder.class));
RangeQueryBuilder rewrittenRange = (RangeQueryBuilder) rewritten;
assertThat(rewrittenRange.fieldName(), equalTo(fieldName));
assertThat(rewrittenRange.from(), equalTo(null));
assertThat(rewrittenRange.to(), equalTo(null));
}
public void testRewriteTextToMatchNone() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName);
String queryFromValue = "damson";
String queryToValue = "plum";
query.from(queryFromValue);
query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.DISJOINT;
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, instanceOf(MatchNoneQueryBuilder.class));
}
public void testRewriteTextToSame() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName);
String queryFromValue = "damson";
String queryToValue = "plum";
query.from(queryFromValue);
query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.INTERSECTS;
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, sameInstance(query));
}
public void testRewriteDateToMatchAll() throws IOException { public void testRewriteDateToMatchAll() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20); String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName); RangeQueryBuilder query = new RangeQueryBuilder(fieldName) {
protected MappedFieldType.Relation getRelation(QueryRewriteContext queryRewriteContext) throws IOException {
return Relation.WITHIN;
}
};
DateTime queryFromValue = new DateTime(2015, 1, 1, 0, 0, 0, ISOChronology.getInstanceUTC()); DateTime queryFromValue = new DateTime(2015, 1, 1, 0, 0, 0, ISOChronology.getInstanceUTC());
DateTime queryToValue = new DateTime(2016, 1, 1, 0, 0, 0, ISOChronology.getInstanceUTC()); DateTime queryToValue = new DateTime(2016, 1, 1, 0, 0, 0, ISOChronology.getInstanceUTC());
DateTime shardMinValue = new DateTime(2015, 3, 1, 0, 0, 0, ISOChronology.getInstanceUTC()); DateTime shardMinValue = new DateTime(2015, 3, 1, 0, 0, 0, ISOChronology.getInstanceUTC());
@ -717,58 +411,6 @@ public class RangeQueryBuilderTests extends AbstractQueryTestCase<RangeQueryBuil
query.from(queryFromValue); query.from(queryFromValue);
query.to(queryToValue); query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext(); QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.WITHIN;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Comparable<T>> FieldStats<T> get(String field) throws IOException {
assertThat(field, equalTo(fieldName));
return (FieldStats<T>) new FieldStats.Date(randomLong(), randomLong(), randomLong(), randomLong(),
shardMinValue.getMillis(), shardMaxValue.getMillis(), null);
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, instanceOf(RangeQueryBuilder.class));
RangeQueryBuilder rewrittenRange = (RangeQueryBuilder) rewritten;
assertThat(rewrittenRange.fieldName(), equalTo(fieldName));
assertThat(rewrittenRange.from(), equalTo(null));
assertThat(rewrittenRange.to(), equalTo(null));
}
public void testRewriteDateWithNowToMatchAll() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName);
String queryFromValue = "now-2d";
String queryToValue = "now";
DateTime shardMinValue = new DateTime().minusHours(12);
DateTime shardMaxValue = new DateTime().minusHours(24);
query.from(queryFromValue);
query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.WITHIN;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Comparable<T>> FieldStats<T> get(String field) throws IOException {
assertThat(field, equalTo(fieldName));
return (FieldStats<T>) new FieldStats.Date(randomLong(), randomLong(), randomLong(), randomLong(),
shardMinValue.getMillis(), shardMaxValue.getMillis(), null);
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext); QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, instanceOf(RangeQueryBuilder.class)); assertThat(rewritten, instanceOf(RangeQueryBuilder.class));
RangeQueryBuilder rewrittenRange = (RangeQueryBuilder) rewritten; RangeQueryBuilder rewrittenRange = (RangeQueryBuilder) rewritten;
@ -779,84 +421,44 @@ public class RangeQueryBuilderTests extends AbstractQueryTestCase<RangeQueryBuil
public void testRewriteDateToMatchNone() throws IOException { public void testRewriteDateToMatchNone() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20); String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName); RangeQueryBuilder query = new RangeQueryBuilder(fieldName) {
protected MappedFieldType.Relation getRelation(QueryRewriteContext queryRewriteContext) throws IOException {
return Relation.DISJOINT;
}
};
DateTime queryFromValue = new DateTime(2015, 1, 1, 0, 0, 0, ISOChronology.getInstanceUTC()); DateTime queryFromValue = new DateTime(2015, 1, 1, 0, 0, 0, ISOChronology.getInstanceUTC());
DateTime queryToValue = new DateTime(2016, 1, 1, 0, 0, 0, ISOChronology.getInstanceUTC()); DateTime queryToValue = new DateTime(2016, 1, 1, 0, 0, 0, ISOChronology.getInstanceUTC());
query.from(queryFromValue); query.from(queryFromValue);
query.to(queryToValue); query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext(); QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.DISJOINT;
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, instanceOf(MatchNoneQueryBuilder.class));
}
public void testRewriteDateWithNowToMatchNone() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName);
String queryFromValue = "now-2d";
String queryToValue = "now";
query.from(queryFromValue);
query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.DISJOINT;
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext); QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, instanceOf(MatchNoneQueryBuilder.class)); assertThat(rewritten, instanceOf(MatchNoneQueryBuilder.class));
} }
public void testRewriteDateToSame() throws IOException { public void testRewriteDateToSame() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20); String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName); RangeQueryBuilder query = new RangeQueryBuilder(fieldName) {
protected MappedFieldType.Relation getRelation(QueryRewriteContext queryRewriteContext) throws IOException {
return Relation.INTERSECTS;
}
};
DateTime queryFromValue = new DateTime(2015, 1, 1, 0, 0, 0, ISOChronology.getInstanceUTC()); DateTime queryFromValue = new DateTime(2015, 1, 1, 0, 0, 0, ISOChronology.getInstanceUTC());
DateTime queryToValue = new DateTime(2016, 1, 1, 0, 0, 0, ISOChronology.getInstanceUTC()); DateTime queryToValue = new DateTime(2016, 1, 1, 0, 0, 0, ISOChronology.getInstanceUTC());
query.from(queryFromValue); query.from(queryFromValue);
query.to(queryToValue); query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext(); QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.INTERSECTS;
}
};
queryShardContext.setFieldStatsProvider(fieldStatsProvider);
QueryBuilder<?> rewritten = query.rewrite(queryShardContext); QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, sameInstance(query)); assertThat(rewritten, sameInstance(query));
} }
public void testRewriteDateWithNowToSame() throws IOException { public void testRewriteOpenBoundsToSame() throws IOException {
String fieldName = randomAsciiOfLengthBetween(1, 20); String fieldName = randomAsciiOfLengthBetween(1, 20);
RangeQueryBuilder query = new RangeQueryBuilder(fieldName); RangeQueryBuilder query = new RangeQueryBuilder(fieldName) {
String queryFromValue = "now-2d"; protected MappedFieldType.Relation getRelation(QueryRewriteContext queryRewriteContext) throws IOException {
String queryToValue = "now";
query.from(queryFromValue);
query.to(queryToValue);
QueryShardContext queryShardContext = queryShardContext();
FieldStatsProvider fieldStatsProvider = new FieldStatsProvider(null, null) {
@Override
public Relation isFieldWithinQuery(String fieldName, Object from, Object to, boolean includeLower, boolean includeUpper,
DateTimeZone timeZone, DateMathParser dateMathParser) throws IOException {
return Relation.INTERSECTS; return Relation.INTERSECTS;
} }
}; };
queryShardContext.setFieldStatsProvider(fieldStatsProvider); QueryShardContext queryShardContext = queryShardContext();
QueryBuilder<?> rewritten = query.rewrite(queryShardContext); QueryBuilder<?> rewritten = query.rewrite(queryShardContext);
assertThat(rewritten, sameInstance(query)); assertThat(rewritten, sameInstance(query));
} }

View File

@ -0,0 +1,81 @@
/*
* 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.query;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiReader;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.MappedFieldType.Relation;
import org.elasticsearch.index.mapper.MapperService.MergeReason;
import org.elasticsearch.test.ESSingleNodeTestCase;
// The purpose of this test case is to test RangeQueryBuilder.getRelation()
// Whether it should return INTERSECT/DISJOINT/WITHIN is already tested in
// RangeQueryBuilderTests
public class RangeQueryRewriteTests extends ESSingleNodeTestCase {
public void testRewriteMissingField() throws Exception {
IndexService indexService = createIndex("test");
IndexReader reader = new MultiReader();
QueryRewriteContext context = new QueryRewriteContext(indexService.getIndexSettings(),
indexService.mapperService(), null, null, reader);
RangeQueryBuilder range = new RangeQueryBuilder("foo");
assertEquals(Relation.DISJOINT, range.getRelation(context));
}
public void testRewriteMissingReader() throws Exception {
IndexService indexService = createIndex("test");
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties")
.startObject("foo")
.field("type", "date")
.endObject()
.endObject()
.endObject().endObject().string();
indexService.mapperService().merge("type",
new CompressedXContent(mapping), MergeReason.MAPPING_UPDATE, false);
QueryRewriteContext context = new QueryRewriteContext(indexService.getIndexSettings(),
indexService.mapperService(), null, null, null);
RangeQueryBuilder range = new RangeQueryBuilder("foo");
// can't make assumptions on a missing reader, so it must return INTERSECT
assertEquals(Relation.INTERSECTS, range.getRelation(context));
}
public void testRewriteEmptyReader() throws Exception {
IndexService indexService = createIndex("test");
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("properties")
.startObject("foo")
.field("type", "date")
.endObject()
.endObject()
.endObject().endObject().string();
indexService.mapperService().merge("type",
new CompressedXContent(mapping), MergeReason.MAPPING_UPDATE, false);
IndexReader reader = new MultiReader();
QueryRewriteContext context = new QueryRewriteContext(indexService.getIndexSettings(),
indexService.mapperService(), null, null, reader);
RangeQueryBuilder range = new RangeQueryBuilder("foo");
// no values -> DISJOINT
assertEquals(Relation.DISJOINT, range.getRelation(context));
}
}

View File

@ -85,20 +85,20 @@ public class IndicesRequestCacheIT extends ESIntegTestCase {
} }
public void testQueryRewrite() throws Exception { public void testQueryRewrite() throws Exception {
assertAcked(client().admin().indices().prepareCreate("index").addMapping("type", "s", "type=text") assertAcked(client().admin().indices().prepareCreate("index").addMapping("type", "s", "type=date")
.setSettings(IndicesRequestCache.INDEX_CACHE_REQUEST_ENABLED_SETTING.getKey(), true, .setSettings(IndicesRequestCache.INDEX_CACHE_REQUEST_ENABLED_SETTING.getKey(), true,
IndexMetaData.SETTING_NUMBER_OF_SHARDS, 5, IndexMetaData.SETTING_NUMBER_OF_SHARDS, 5,
IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0) IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)
.get()); .get());
indexRandom(true, client().prepareIndex("index", "type", "1").setRouting("1").setSource("s", "a"), indexRandom(true, client().prepareIndex("index", "type", "1").setRouting("1").setSource("s", "2016-03-19"),
client().prepareIndex("index", "type", "2").setRouting("1").setSource("s", "b"), client().prepareIndex("index", "type", "2").setRouting("1").setSource("s", "2016-03-20"),
client().prepareIndex("index", "type", "3").setRouting("1").setSource("s", "c"), client().prepareIndex("index", "type", "3").setRouting("1").setSource("s", "2016-03-21"),
client().prepareIndex("index", "type", "4").setRouting("2").setSource("s", "d"), client().prepareIndex("index", "type", "4").setRouting("2").setSource("s", "2016-03-22"),
client().prepareIndex("index", "type", "5").setRouting("2").setSource("s", "e"), client().prepareIndex("index", "type", "5").setRouting("2").setSource("s", "2016-03-23"),
client().prepareIndex("index", "type", "6").setRouting("2").setSource("s", "f"), client().prepareIndex("index", "type", "6").setRouting("2").setSource("s", "2016-03-24"),
client().prepareIndex("index", "type", "7").setRouting("3").setSource("s", "g"), client().prepareIndex("index", "type", "7").setRouting("3").setSource("s", "2016-03-25"),
client().prepareIndex("index", "type", "8").setRouting("3").setSource("s", "h"), client().prepareIndex("index", "type", "8").setRouting("3").setSource("s", "2016-03-26"),
client().prepareIndex("index", "type", "9").setRouting("3").setSource("s", "i")); client().prepareIndex("index", "type", "9").setRouting("3").setSource("s", "2016-03-27"));
ensureSearchable("index"); ensureSearchable("index");
assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(), assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(),
@ -107,7 +107,7 @@ public class IndicesRequestCacheIT extends ESIntegTestCase {
equalTo(0L)); equalTo(0L));
final SearchResponse r1 = client().prepareSearch("index").setSearchType(SearchType.QUERY_THEN_FETCH).setSize(0) final SearchResponse r1 = client().prepareSearch("index").setSearchType(SearchType.QUERY_THEN_FETCH).setSize(0)
.setQuery(QueryBuilders.rangeQuery("s").gte("a").lte("g")).get(); .setQuery(QueryBuilders.rangeQuery("s").gte("2016-03-19").lte("2016-03-25")).get();
assertSearchResponse(r1); assertSearchResponse(r1);
assertThat(r1.getHits().getTotalHits(), equalTo(7L)); assertThat(r1.getHits().getTotalHits(), equalTo(7L));
assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(), assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(),
@ -116,7 +116,7 @@ public class IndicesRequestCacheIT extends ESIntegTestCase {
equalTo(5L)); equalTo(5L));
final SearchResponse r2 = client().prepareSearch("index").setSearchType(SearchType.QUERY_THEN_FETCH).setSize(0) final SearchResponse r2 = client().prepareSearch("index").setSearchType(SearchType.QUERY_THEN_FETCH).setSize(0)
.setQuery(QueryBuilders.rangeQuery("s").gte("b").lte("h")).get(); .setQuery(QueryBuilders.rangeQuery("s").gte("2016-03-20").lte("2016-03-26")).get();
assertSearchResponse(r2); assertSearchResponse(r2);
assertThat(r2.getHits().getTotalHits(), equalTo(7L)); assertThat(r2.getHits().getTotalHits(), equalTo(7L));
assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(), assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(),
@ -125,7 +125,7 @@ public class IndicesRequestCacheIT extends ESIntegTestCase {
equalTo(7L)); equalTo(7L));
final SearchResponse r3 = client().prepareSearch("index").setSearchType(SearchType.QUERY_THEN_FETCH).setSize(0) final SearchResponse r3 = client().prepareSearch("index").setSearchType(SearchType.QUERY_THEN_FETCH).setSize(0)
.setQuery(QueryBuilders.rangeQuery("s").gte("c").lte("i")).get(); .setQuery(QueryBuilders.rangeQuery("s").gte("2016-03-21").lte("2016-03-27")).get();
assertSearchResponse(r3); assertSearchResponse(r3);
assertThat(r3.getHits().getTotalHits(), equalTo(7L)); assertThat(r3.getHits().getTotalHits(), equalTo(7L));
assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(), assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(),
@ -135,19 +135,19 @@ public class IndicesRequestCacheIT extends ESIntegTestCase {
} }
public void testQueryRewriteMissingValues() throws Exception { public void testQueryRewriteMissingValues() throws Exception {
assertAcked(client().admin().indices().prepareCreate("index").addMapping("type", "s", "type=text") assertAcked(client().admin().indices().prepareCreate("index").addMapping("type", "s", "type=date")
.setSettings(IndicesRequestCache.INDEX_CACHE_REQUEST_ENABLED_SETTING.getKey(), true, IndexMetaData.SETTING_NUMBER_OF_SHARDS, .setSettings(IndicesRequestCache.INDEX_CACHE_REQUEST_ENABLED_SETTING.getKey(), true, IndexMetaData.SETTING_NUMBER_OF_SHARDS,
1, IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0) 1, IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)
.get()); .get());
indexRandom(true, client().prepareIndex("index", "type", "1").setSource("s", "a"), indexRandom(true, client().prepareIndex("index", "type", "1").setSource("s", "2016-03-19"),
client().prepareIndex("index", "type", "2").setSource("s", "b"), client().prepareIndex("index", "type", "2").setSource("s", "2016-03-20"),
client().prepareIndex("index", "type", "3").setSource("s", "c"), client().prepareIndex("index", "type", "3").setSource("s", "2016-03-21"),
client().prepareIndex("index", "type", "4").setSource("s", "d"), client().prepareIndex("index", "type", "4").setSource("s", "2016-03-22"),
client().prepareIndex("index", "type", "5").setSource("s", "e"), client().prepareIndex("index", "type", "5").setSource("s", "2016-03-23"),
client().prepareIndex("index", "type", "6").setSource("s", "f"), client().prepareIndex("index", "type", "6").setSource("s", "2016-03-24"),
client().prepareIndex("index", "type", "7").setSource("other", "value"), client().prepareIndex("index", "type", "7").setSource("other", "value"),
client().prepareIndex("index", "type", "8").setSource("s", "h"), client().prepareIndex("index", "type", "8").setSource("s", "2016-03-26"),
client().prepareIndex("index", "type", "9").setSource("s", "i")); client().prepareIndex("index", "type", "9").setSource("s", "2016-03-27"));
ensureSearchable("index"); ensureSearchable("index");
assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(), assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(),
@ -156,7 +156,7 @@ public class IndicesRequestCacheIT extends ESIntegTestCase {
equalTo(0L)); equalTo(0L));
final SearchResponse r1 = client().prepareSearch("index").setSearchType(SearchType.QUERY_THEN_FETCH).setSize(0) final SearchResponse r1 = client().prepareSearch("index").setSearchType(SearchType.QUERY_THEN_FETCH).setSize(0)
.setQuery(QueryBuilders.rangeQuery("s").gte("a").lte("j")).get(); .setQuery(QueryBuilders.rangeQuery("s").gte("2016-03-19").lte("2016-03-28")).get();
assertSearchResponse(r1); assertSearchResponse(r1);
assertThat(r1.getHits().getTotalHits(), equalTo(8L)); assertThat(r1.getHits().getTotalHits(), equalTo(8L));
assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(), assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(),
@ -165,7 +165,7 @@ public class IndicesRequestCacheIT extends ESIntegTestCase {
equalTo(1L)); equalTo(1L));
final SearchResponse r2 = client().prepareSearch("index").setSearchType(SearchType.QUERY_THEN_FETCH).setSize(0) final SearchResponse r2 = client().prepareSearch("index").setSearchType(SearchType.QUERY_THEN_FETCH).setSize(0)
.setQuery(QueryBuilders.rangeQuery("s").gte("a").lte("j")).get(); .setQuery(QueryBuilders.rangeQuery("s").gte("2016-03-19").lte("2016-03-28")).get();
assertSearchResponse(r2); assertSearchResponse(r2);
assertThat(r2.getHits().getTotalHits(), equalTo(8L)); assertThat(r2.getHits().getTotalHits(), equalTo(8L));
assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(), assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(),
@ -174,7 +174,7 @@ public class IndicesRequestCacheIT extends ESIntegTestCase {
equalTo(1L)); equalTo(1L));
final SearchResponse r3 = client().prepareSearch("index").setSearchType(SearchType.QUERY_THEN_FETCH).setSize(0) final SearchResponse r3 = client().prepareSearch("index").setSearchType(SearchType.QUERY_THEN_FETCH).setSize(0)
.setQuery(QueryBuilders.rangeQuery("s").gte("a").lte("j")).get(); .setQuery(QueryBuilders.rangeQuery("s").gte("2016-03-19").lte("2016-03-28")).get();
assertSearchResponse(r3); assertSearchResponse(r3);
assertThat(r3.getHits().getTotalHits(), equalTo(8L)); assertThat(r3.getHits().getTotalHits(), equalTo(8L));
assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(), assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(),

View File

@ -291,7 +291,7 @@ public class HighlightBuilderTests extends ESTestCase {
IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(index, indexSettings); IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(index, indexSettings);
// shard context will only need indicesQueriesRegistry for building Query objects nested in highlighter // shard context will only need indicesQueriesRegistry for building Query objects nested in highlighter
QueryShardContext mockShardContext = new QueryShardContext(idxSettings, null, null, null, null, null, indicesQueriesRegistry, QueryShardContext mockShardContext = new QueryShardContext(idxSettings, null, null, null, null, null, indicesQueriesRegistry,
null) { null, null) {
@Override @Override
public MappedFieldType fieldMapper(String name) { public MappedFieldType fieldMapper(String name) {
TextFieldMapper.Builder builder = new TextFieldMapper.Builder(name); TextFieldMapper.Builder builder = new TextFieldMapper.Builder(name);

View File

@ -163,7 +163,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(randomAsciiOfLengthBetween(1, 10), indexSettings); IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(randomAsciiOfLengthBetween(1, 10), indexSettings);
// shard context will only need indicesQueriesRegistry for building Query objects nested in query rescorer // shard context will only need indicesQueriesRegistry for building Query objects nested in query rescorer
QueryShardContext mockShardContext = new QueryShardContext(idxSettings, null, null, null, null, null, indicesQueriesRegistry, QueryShardContext mockShardContext = new QueryShardContext(idxSettings, null, null, null, null, null, indicesQueriesRegistry,
null) { null, null) {
@Override @Override
public MappedFieldType fieldMapper(String name) { public MappedFieldType fieldMapper(String name) {
TextFieldMapper.Builder builder = new TextFieldMapper.Builder(name); TextFieldMapper.Builder builder = new TextFieldMapper.Builder(name);

View File

@ -225,7 +225,7 @@ public abstract class AbstractSortTestCase<T extends SortBuilder<T>> extends EST
} }
}); });
return new QueryShardContext(idxSettings, bitsetFilterCache, ifds, null, null, scriptService, return new QueryShardContext(idxSettings, bitsetFilterCache, ifds, null, null, scriptService,
indicesQueriesRegistry, null) { indicesQueriesRegistry, null, null) {
@Override @Override
public MappedFieldType fieldMapper(String name) { public MappedFieldType fieldMapper(String name) {
return provideMappedFieldType(name); return provideMappedFieldType(name);

View File

@ -149,7 +149,7 @@ public class TemplateQueryParserTests extends ESTestCase {
} }
}); });
IndicesQueriesRegistry indicesQueriesRegistry = injector.getInstance(IndicesQueriesRegistry.class); IndicesQueriesRegistry indicesQueriesRegistry = injector.getInstance(IndicesQueriesRegistry.class);
context = new QueryShardContext(idxSettings, bitsetFilterCache, indexFieldDataService, mapperService, similarityService, scriptService, indicesQueriesRegistry, null); context = new QueryShardContext(idxSettings, bitsetFilterCache, indexFieldDataService, mapperService, similarityService, scriptService, indicesQueriesRegistry, null, null);
} }
@Override @Override