Date Mapping: Support "date math" when searching, closes #1708.

This commit is contained in:
Shay Banon 2012-02-16 18:10:12 +02:00
parent eb9503f674
commit f997315f54
24 changed files with 361 additions and 89 deletions

View File

@ -42,7 +42,7 @@ public class ExistsFieldQueryExtension implements FieldQueryExtension {
MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName); MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName);
if (smartNameFieldMappers != null) { if (smartNameFieldMappers != null) {
if (smartNameFieldMappers.hasMapper()) { if (smartNameFieldMappers.hasMapper()) {
filter = smartNameFieldMappers.mapper().rangeFilter(null, null, true, true); filter = smartNameFieldMappers.mapper().rangeFilter(null, null, true, true, parseContext);
} }
} }
if (filter == null) { if (filter == null) {

View File

@ -167,7 +167,7 @@ public class MapperQueryParser extends QueryParser {
if (fieldMappers != null) { if (fieldMappers != null) {
currentMapper = fieldMappers.fieldMappers().mapper(); currentMapper = fieldMappers.fieldMappers().mapper();
if (currentMapper != null) { if (currentMapper != null) {
Query rangeQuery = currentMapper.rangeQuery(part1, part2, inclusive, inclusive); Query rangeQuery = currentMapper.rangeQuery(part1, part2, inclusive, inclusive, parseContext);
return wrapSmartNameQuery(rangeQuery, fieldMappers, parseContext); return wrapSmartNameQuery(rangeQuery, fieldMappers, parseContext);
} }
} }

View File

@ -44,7 +44,7 @@ public class MissingFieldQueryExtension implements FieldQueryExtension {
MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName); MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName);
if (smartNameFieldMappers != null) { if (smartNameFieldMappers != null) {
if (smartNameFieldMappers.hasMapper()) { if (smartNameFieldMappers.hasMapper()) {
filter = smartNameFieldMappers.mapper().rangeFilter(null, null, true, true); filter = smartNameFieldMappers.mapper().rangeFilter(null, null, true, true, parseContext);
} }
} }
if (filter == null) { if (filter == null) {

View File

@ -0,0 +1,227 @@
package org.elasticsearch.common.joda;
import org.elasticsearch.ElasticSearchParseException;
import org.joda.time.DateTimeZone;
import org.joda.time.MutableDateTime;
import java.util.concurrent.TimeUnit;
/**
*/
public class DateMathParser {
private final FormatDateTimeFormatter dateTimeFormatter;
private final TimeUnit timeUnit;
public DateMathParser(FormatDateTimeFormatter dateTimeFormatter, TimeUnit timeUnit) {
this.dateTimeFormatter = dateTimeFormatter;
this.timeUnit = timeUnit;
}
public long parse(String text, long now) {
return parse(text, now, false, false);
}
public long parseUpperInclusive(String text, long now) {
return parse(text, now, true, true);
}
public long parse(String text, long now, boolean roundUp, boolean upperInclusive) {
long time;
String mathString;
if (text.startsWith("now")) {
time = now;
mathString = text.substring("now".length());
} else {
int index = text.indexOf("||");
String parseString;
if (index == -1) {
parseString = text;
mathString = ""; // nothing else
} else {
parseString = text.substring(0, index);
mathString = text.substring(index + 2);
}
if (upperInclusive) {
time = parseUpperInclusiveStringValue(parseString);
} else {
time = parseStringValue(parseString);
}
}
if (mathString.isEmpty()) {
return time;
}
return parseMath(mathString, time, roundUp);
}
private long parseMath(String mathString, long time, boolean roundUp) throws ElasticSearchParseException {
MutableDateTime dateTime = new MutableDateTime(time, DateTimeZone.UTC);
try {
for (int i = 0; i < mathString.length(); ) {
char c = mathString.charAt(i++);
int type;
if (c == '/') {
type = 0;
} else if (c == '+') {
type = 1;
} else if (c == '-') {
type = 2;
} else {
throw new ElasticSearchParseException("operator not supported for date math [" + mathString + "]");
}
int num;
if (!Character.isDigit(mathString.charAt(i))) {
num = 1;
} else {
int numFrom = i;
while (Character.isDigit(mathString.charAt(i))) {
i++;
}
num = Integer.parseInt(mathString.substring(numFrom, i));
}
if (type == 0) {
// rounding is only allowed on whole numbers
if (num != 1) {
throw new ElasticSearchParseException("rounding `/` can only be used on single unit types [" + mathString + "]");
}
}
char unit = mathString.charAt(i++);
switch (unit) {
case 'M':
if (type == 0) {
if (roundUp) {
dateTime.monthOfYear().roundCeiling();
} else {
dateTime.monthOfYear().roundFloor();
}
} else if (type == 1) {
dateTime.addMonths(num);
} else if (type == 2) {
dateTime.addMonths(-num);
}
break;
case 'w':
if (type == 0) {
if (roundUp) {
dateTime.weekOfWeekyear().roundCeiling();
} else {
dateTime.weekOfWeekyear().roundFloor();
}
} else if (type == 1) {
dateTime.addWeeks(num);
} else if (type == 2) {
dateTime.addWeeks(-num);
}
break;
case 'd':
if (type == 0) {
if (roundUp) {
dateTime.dayOfMonth().roundCeiling();
} else {
dateTime.dayOfMonth().roundFloor();
}
} else if (type == 1) {
dateTime.addDays(num);
} else if (type == 2) {
dateTime.addDays(-num);
}
break;
case 'h':
case 'H':
if (type == 0) {
if (roundUp) {
dateTime.hourOfDay().roundCeiling();
} else {
dateTime.hourOfDay().roundFloor();
}
} else if (type == 1) {
dateTime.addHours(num);
} else if (type == 2) {
dateTime.addHours(-num);
}
break;
case 'm':
if (type == 0) {
if (roundUp) {
dateTime.minuteOfHour().roundCeiling();
} else {
dateTime.minuteOfHour().roundFloor();
}
} else if (type == 1) {
dateTime.addMinutes(num);
} else if (type == 2) {
dateTime.addMinutes(-num);
}
break;
case 's':
if (type == 0) {
if (roundUp) {
dateTime.secondOfMinute().roundCeiling();
} else {
dateTime.secondOfMinute().roundFloor();
}
} else if (type == 1) {
dateTime.addSeconds(num);
} else if (type == 2) {
dateTime.addSeconds(-num);
}
break;
default:
throw new ElasticSearchParseException("unit [" + unit + "] not supported for date math [" + mathString + "]");
}
}
} catch (Exception e) {
if (e instanceof ElasticSearchParseException) {
throw (ElasticSearchParseException) e;
}
throw new ElasticSearchParseException("failed to parse date math [" + mathString + "]");
}
return dateTime.getMillis();
}
private long parseStringValue(String value) {
try {
return dateTimeFormatter.parser().parseMillis(value);
} catch (RuntimeException e) {
try {
long time = Long.parseLong(value);
return timeUnit.toMillis(time);
} catch (NumberFormatException e1) {
throw new ElasticSearchParseException("failed to parse date field [" + value + "], tried both date format [" + dateTimeFormatter.format() + "], and timestamp number", e);
}
}
}
private long parseUpperInclusiveStringValue(String value) {
try {
MutableDateTime dateTime = new MutableDateTime(3000, 12, 31, 23, 59, 59, 999, DateTimeZone.UTC);
int location = dateTimeFormatter.parser().parseInto(dateTime, value, 0);
// if we parsed all the string value, we are good
if (location == value.length()) {
return dateTime.getMillis();
}
// if we did not manage to parse, or the year is really high year which is unreasonable
// see if its a number
if (location <= 0 || dateTime.getYear() > 5000) {
try {
long time = Long.parseLong(value);
return timeUnit.toMillis(time);
} catch (NumberFormatException e1) {
throw new ElasticSearchParseException("failed to parse date field [" + value + "], tried both date format [" + dateTimeFormatter.format() + "], and timestamp number");
}
}
return dateTime.getMillis();
} catch (RuntimeException e) {
try {
long time = Long.parseLong(value);
return timeUnit.toMillis(time);
} catch (NumberFormatException e1) {
throw new ElasticSearchParseException("failed to parse date field [" + value + "], tried both date format [" + dateTimeFormatter.format() + "], and timestamp number", e);
}
}
}
}

View File

@ -198,12 +198,12 @@ public interface FieldMapper<T> {
/** /**
* Constructs a range query based on the mapper. * Constructs a range query based on the mapper.
*/ */
Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper); Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context);
/** /**
* Constructs a range query filter based on the mapper. * Constructs a range query filter based on the mapper.
*/ */
Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper); Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context);
FieldDataType fieldDataType(); FieldDataType fieldDataType();
} }

View File

@ -395,7 +395,7 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T>, Mapper {
} }
@Override @Override
public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return new TermRangeQuery(names.indexName(), return new TermRangeQuery(names.indexName(),
lowerTerm == null ? null : indexedValue(lowerTerm), lowerTerm == null ? null : indexedValue(lowerTerm),
upperTerm == null ? null : indexedValue(upperTerm), upperTerm == null ? null : indexedValue(upperTerm),
@ -403,7 +403,7 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T>, Mapper {
} }
@Override @Override
public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return new TermRangeFilter(names.indexName(), return new TermRangeFilter(names.indexName(),
lowerTerm == null ? null : indexedValue(lowerTerm), lowerTerm == null ? null : indexedValue(lowerTerm),
upperTerm == null ? null : indexedValue(upperTerm), upperTerm == null ? null : indexedValue(upperTerm),

View File

@ -167,7 +167,7 @@ public class ByteFieldMapper extends NumberFieldMapper<Byte> {
} }
@Override @Override
public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeQuery.newIntRange(names.indexName(), precisionStep, return NumericRangeQuery.newIntRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Integer.parseInt(lowerTerm), lowerTerm == null ? null : Integer.parseInt(lowerTerm),
upperTerm == null ? null : Integer.parseInt(upperTerm), upperTerm == null ? null : Integer.parseInt(upperTerm),
@ -182,7 +182,7 @@ public class ByteFieldMapper extends NumberFieldMapper<Byte> {
} }
@Override @Override
public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFilter.newIntRange(names.indexName(), precisionStep, return NumericRangeFilter.newIntRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Integer.parseInt(lowerTerm), lowerTerm == null ? null : Integer.parseInt(lowerTerm),
upperTerm == null ? null : Integer.parseInt(upperTerm), upperTerm == null ? null : Integer.parseInt(upperTerm),
@ -190,7 +190,7 @@ public class ByteFieldMapper extends NumberFieldMapper<Byte> {
} }
@Override @Override
public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFieldDataFilter.newByteRange(fieldDataCache, names.indexName(), return NumericRangeFieldDataFilter.newByteRange(fieldDataCache, names.indexName(),
lowerTerm == null ? null : Byte.parseByte(lowerTerm), lowerTerm == null ? null : Byte.parseByte(lowerTerm),
upperTerm == null ? null : Byte.parseByte(upperTerm), upperTerm == null ? null : Byte.parseByte(upperTerm),

View File

@ -29,6 +29,7 @@ import org.apache.lucene.util.NumericUtils;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Numbers; import org.elasticsearch.common.Numbers;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.FormatDateTimeFormatter; import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.joda.Joda; import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
@ -41,8 +42,6 @@ import org.elasticsearch.index.field.data.FieldDataType;
import org.elasticsearch.index.mapper.*; import org.elasticsearch.index.mapper.*;
import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.search.NumericRangeFieldDataFilter; import org.elasticsearch.index.search.NumericRangeFieldDataFilter;
import org.joda.time.DateTimeZone;
import org.joda.time.MutableDateTime;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
@ -133,6 +132,8 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
private final boolean parseUpperInclusive; private final boolean parseUpperInclusive;
private final DateMathParser dateMathParser;
private String nullValue; private String nullValue;
protected final TimeUnit timeUnit; protected final TimeUnit timeUnit;
@ -148,6 +149,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
this.nullValue = nullValue; this.nullValue = nullValue;
this.timeUnit = timeUnit; this.timeUnit = timeUnit;
this.parseUpperInclusive = parseUpperInclusive; this.parseUpperInclusive = parseUpperInclusive;
this.dateMathParser = new DateMathParser(dateTimeFormatter, timeUnit);
} }
@Override @Override
@ -205,7 +207,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
@Override @Override
public Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions) { public Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions) {
long iValue = parseStringValue(value); long iValue = dateMathParser.parse(value, System.currentTimeMillis());
long iSim; long iSim;
try { try {
iSim = TimeValue.parseTimeValue(minSim, null).millis(); iSim = TimeValue.parseTimeValue(minSim, null).millis();
@ -221,7 +223,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
@Override @Override
public Query fuzzyQuery(String value, double minSim, int prefixLength, int maxExpansions) { public Query fuzzyQuery(String value, double minSim, int prefixLength, int maxExpansions) {
long iValue = parseStringValue(value); long iValue = dateMathParser.parse(value, System.currentTimeMillis());
long iSim = (long) (minSim * dFuzzyFactor); long iSim = (long) (minSim * dFuzzyFactor);
return NumericRangeQuery.newLongRange(names.indexName(), precisionStep, return NumericRangeQuery.newLongRange(names.indexName(), precisionStep,
iValue - iSim, iValue - iSim,
@ -231,39 +233,44 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
@Override @Override
public Query fieldQuery(String value, @Nullable QueryParseContext context) { public Query fieldQuery(String value, @Nullable QueryParseContext context) {
long lValue = parseStringValue(value); long now = context == null ? System.currentTimeMillis() : context.nowInMillis();
long lValue = dateMathParser.parse(value, now);
return NumericRangeQuery.newLongRange(names.indexName(), precisionStep, return NumericRangeQuery.newLongRange(names.indexName(), precisionStep,
lValue, lValue, true, true); lValue, lValue, true, true);
} }
@Override @Override
public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
long now = context == null ? System.currentTimeMillis() : context.nowInMillis();
return NumericRangeQuery.newLongRange(names.indexName(), precisionStep, return NumericRangeQuery.newLongRange(names.indexName(), precisionStep,
lowerTerm == null ? null : parseStringValue(lowerTerm), lowerTerm == null ? null : dateMathParser.parse(lowerTerm, now),
upperTerm == null ? null : includeUpper ? parseUpperInclusiveStringValue(upperTerm) : parseStringValue(upperTerm), upperTerm == null ? null : (includeUpper && parseUpperInclusive) ? dateMathParser.parseUpperInclusive(upperTerm, now) : dateMathParser.parse(upperTerm, now),
includeLower, includeUpper); includeLower, includeUpper);
} }
@Override @Override
public Filter fieldFilter(String value, @Nullable QueryParseContext context) { public Filter fieldFilter(String value, @Nullable QueryParseContext context) {
long lValue = parseStringValue(value); long now = context == null ? System.currentTimeMillis() : context.nowInMillis();
long lValue = dateMathParser.parse(value, now);
return NumericRangeFilter.newLongRange(names.indexName(), precisionStep, return NumericRangeFilter.newLongRange(names.indexName(), precisionStep,
lValue, lValue, true, true); lValue, lValue, true, true);
} }
@Override @Override
public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
long now = context == null ? System.currentTimeMillis() : context.nowInMillis();
return NumericRangeFilter.newLongRange(names.indexName(), precisionStep, return NumericRangeFilter.newLongRange(names.indexName(), precisionStep,
lowerTerm == null ? null : parseStringValue(lowerTerm), lowerTerm == null ? null : dateMathParser.parse(lowerTerm, now),
upperTerm == null ? null : includeUpper ? parseUpperInclusiveStringValue(upperTerm) : parseStringValue(upperTerm), upperTerm == null ? null : (includeUpper && parseUpperInclusive) ? dateMathParser.parseUpperInclusive(upperTerm, now) : dateMathParser.parse(upperTerm, now),
includeLower, includeUpper); includeLower, includeUpper);
} }
@Override @Override
public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
long now = context == null ? System.currentTimeMillis() : context.nowInMillis();
return NumericRangeFieldDataFilter.newLongRange(fieldDataCache, names.indexName(), return NumericRangeFieldDataFilter.newLongRange(fieldDataCache, names.indexName(),
lowerTerm == null ? null : parseStringValue(lowerTerm), lowerTerm == null ? null : dateMathParser.parse(lowerTerm, now),
upperTerm == null ? null : includeUpper ? parseUpperInclusiveStringValue(upperTerm) : parseStringValue(upperTerm), upperTerm == null ? null : (includeUpper && parseUpperInclusive) ? dateMathParser.parseUpperInclusive(upperTerm, now) : dateMathParser.parse(upperTerm, now),
includeLower, includeUpper); includeLower, includeUpper);
} }
@ -394,7 +401,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
} }
} }
protected long parseStringValue(String value) { private long parseStringValue(String value) {
try { try {
return dateTimeFormatter.parser().parseMillis(value); return dateTimeFormatter.parser().parseMillis(value);
} catch (RuntimeException e) { } catch (RuntimeException e) {
@ -406,36 +413,4 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
} }
} }
} }
protected long parseUpperInclusiveStringValue(String value) {
if (!parseUpperInclusive) {
return parseStringValue(value);
}
try {
MutableDateTime dateTime = new MutableDateTime(3000, 12, 31, 23, 59, 59, 999, DateTimeZone.UTC);
int location = dateTimeFormatter.parser().parseInto(dateTime, value, 0);
// if we parsed all the string value, we are good
if (location == value.length()) {
return dateTime.getMillis();
}
// if we did not manage to parse, or the year is really high year which is unreasonable
// see if its a number
if (location <= 0 || dateTime.getYear() > 5000) {
try {
long time = Long.parseLong(value);
return timeUnit.toMillis(time);
} catch (NumberFormatException e1) {
throw new MapperParsingException("failed to parse date field [" + value + "], tried both date format [" + dateTimeFormatter.format() + "], and timestamp number");
}
}
return dateTime.getMillis();
} catch (RuntimeException e) {
try {
long time = Long.parseLong(value);
return timeUnit.toMillis(time);
} catch (NumberFormatException e1) {
throw new MapperParsingException("failed to parse date field [" + value + "], tried both date format [" + dateTimeFormatter.format() + "], and timestamp number", e);
}
}
}
} }

View File

@ -164,7 +164,7 @@ public class DoubleFieldMapper extends NumberFieldMapper<Double> {
} }
@Override @Override
public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeQuery.newDoubleRange(names.indexName(), precisionStep, return NumericRangeQuery.newDoubleRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Double.parseDouble(lowerTerm), lowerTerm == null ? null : Double.parseDouble(lowerTerm),
upperTerm == null ? null : Double.parseDouble(upperTerm), upperTerm == null ? null : Double.parseDouble(upperTerm),
@ -179,7 +179,7 @@ public class DoubleFieldMapper extends NumberFieldMapper<Double> {
} }
@Override @Override
public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFilter.newDoubleRange(names.indexName(), precisionStep, return NumericRangeFilter.newDoubleRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Double.parseDouble(lowerTerm), lowerTerm == null ? null : Double.parseDouble(lowerTerm),
upperTerm == null ? null : Double.parseDouble(upperTerm), upperTerm == null ? null : Double.parseDouble(upperTerm),
@ -191,7 +191,7 @@ public class DoubleFieldMapper extends NumberFieldMapper<Double> {
} }
@Override @Override
public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFieldDataFilter.newDoubleRange(fieldDataCache, names.indexName(), return NumericRangeFieldDataFilter.newDoubleRange(fieldDataCache, names.indexName(),
lowerTerm == null ? null : Double.parseDouble(lowerTerm), lowerTerm == null ? null : Double.parseDouble(lowerTerm),
upperTerm == null ? null : Double.parseDouble(upperTerm), upperTerm == null ? null : Double.parseDouble(upperTerm),

View File

@ -163,7 +163,7 @@ public class FloatFieldMapper extends NumberFieldMapper<Float> {
} }
@Override @Override
public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeQuery.newFloatRange(names.indexName(), precisionStep, return NumericRangeQuery.newFloatRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Float.parseFloat(lowerTerm), lowerTerm == null ? null : Float.parseFloat(lowerTerm),
upperTerm == null ? null : Float.parseFloat(upperTerm), upperTerm == null ? null : Float.parseFloat(upperTerm),
@ -178,7 +178,7 @@ public class FloatFieldMapper extends NumberFieldMapper<Float> {
} }
@Override @Override
public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFilter.newFloatRange(names.indexName(), precisionStep, return NumericRangeFilter.newFloatRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Float.parseFloat(lowerTerm), lowerTerm == null ? null : Float.parseFloat(lowerTerm),
upperTerm == null ? null : Float.parseFloat(upperTerm), upperTerm == null ? null : Float.parseFloat(upperTerm),
@ -186,7 +186,7 @@ public class FloatFieldMapper extends NumberFieldMapper<Float> {
} }
@Override @Override
public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFieldDataFilter.newFloatRange(fieldDataCache, names.indexName(), return NumericRangeFieldDataFilter.newFloatRange(fieldDataCache, names.indexName(),
lowerTerm == null ? null : Float.parseFloat(lowerTerm), lowerTerm == null ? null : Float.parseFloat(lowerTerm),
upperTerm == null ? null : Float.parseFloat(upperTerm), upperTerm == null ? null : Float.parseFloat(upperTerm),

View File

@ -168,7 +168,7 @@ public class IntegerFieldMapper extends NumberFieldMapper<Integer> {
} }
@Override @Override
public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeQuery.newIntRange(names.indexName(), precisionStep, return NumericRangeQuery.newIntRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Integer.parseInt(lowerTerm), lowerTerm == null ? null : Integer.parseInt(lowerTerm),
upperTerm == null ? null : Integer.parseInt(upperTerm), upperTerm == null ? null : Integer.parseInt(upperTerm),
@ -183,7 +183,7 @@ public class IntegerFieldMapper extends NumberFieldMapper<Integer> {
} }
@Override @Override
public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFilter.newIntRange(names.indexName(), precisionStep, return NumericRangeFilter.newIntRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Integer.parseInt(lowerTerm), lowerTerm == null ? null : Integer.parseInt(lowerTerm),
upperTerm == null ? null : Integer.parseInt(upperTerm), upperTerm == null ? null : Integer.parseInt(upperTerm),
@ -191,7 +191,7 @@ public class IntegerFieldMapper extends NumberFieldMapper<Integer> {
} }
@Override @Override
public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFieldDataFilter.newIntRange(fieldDataCache, names.indexName(), return NumericRangeFieldDataFilter.newIntRange(fieldDataCache, names.indexName(),
lowerTerm == null ? null : Integer.parseInt(lowerTerm), lowerTerm == null ? null : Integer.parseInt(lowerTerm),
upperTerm == null ? null : Integer.parseInt(upperTerm), upperTerm == null ? null : Integer.parseInt(upperTerm),

View File

@ -168,7 +168,7 @@ public class LongFieldMapper extends NumberFieldMapper<Long> {
} }
@Override @Override
public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeQuery.newLongRange(names.indexName(), precisionStep, return NumericRangeQuery.newLongRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Long.parseLong(lowerTerm), lowerTerm == null ? null : Long.parseLong(lowerTerm),
upperTerm == null ? null : Long.parseLong(upperTerm), upperTerm == null ? null : Long.parseLong(upperTerm),
@ -183,7 +183,7 @@ public class LongFieldMapper extends NumberFieldMapper<Long> {
} }
@Override @Override
public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFilter.newLongRange(names.indexName(), precisionStep, return NumericRangeFilter.newLongRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Long.parseLong(lowerTerm), lowerTerm == null ? null : Long.parseLong(lowerTerm),
upperTerm == null ? null : Long.parseLong(upperTerm), upperTerm == null ? null : Long.parseLong(upperTerm),
@ -191,7 +191,7 @@ public class LongFieldMapper extends NumberFieldMapper<Long> {
} }
@Override @Override
public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFieldDataFilter.newLongRange(fieldDataCache, names.indexName(), return NumericRangeFieldDataFilter.newLongRange(fieldDataCache, names.indexName(),
lowerTerm == null ? null : Long.parseLong(lowerTerm), lowerTerm == null ? null : Long.parseLong(lowerTerm),
upperTerm == null ? null : Long.parseLong(upperTerm), upperTerm == null ? null : Long.parseLong(upperTerm),

View File

@ -166,7 +166,7 @@ public abstract class NumberFieldMapper<T extends Number> extends AbstractFieldM
*/ */
@Override @Override
public Query fieldQuery(String value, @Nullable QueryParseContext context) { public Query fieldQuery(String value, @Nullable QueryParseContext context) {
return rangeQuery(value, value, true, true); return rangeQuery(value, value, true, true, context);
} }
@Override @Override
@ -181,19 +181,19 @@ public abstract class NumberFieldMapper<T extends Number> extends AbstractFieldM
*/ */
@Override @Override
public Filter fieldFilter(String value, @Nullable QueryParseContext context) { public Filter fieldFilter(String value, @Nullable QueryParseContext context) {
return rangeFilter(value, value, true, true); return rangeFilter(value, value, true, true, context);
} }
@Override @Override
public abstract Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper); public abstract Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context);
@Override @Override
public abstract Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper); public abstract Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context);
/** /**
* A range filter based on the field data cache. * A range filter based on the field data cache.
*/ */
public abstract Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper); public abstract Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context);
/** /**
* Override the default behavior (to return the string, and return the actual Number instance). * Override the default behavior (to return the string, and return the actual Number instance).

View File

@ -168,7 +168,7 @@ public class ShortFieldMapper extends NumberFieldMapper<Short> {
} }
@Override @Override
public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeQuery.newIntRange(names.indexName(), precisionStep, return NumericRangeQuery.newIntRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Integer.parseInt(lowerTerm), lowerTerm == null ? null : Integer.parseInt(lowerTerm),
upperTerm == null ? null : Integer.parseInt(upperTerm), upperTerm == null ? null : Integer.parseInt(upperTerm),
@ -183,7 +183,7 @@ public class ShortFieldMapper extends NumberFieldMapper<Short> {
} }
@Override @Override
public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFilter.newIntRange(names.indexName(), precisionStep, return NumericRangeFilter.newIntRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Integer.parseInt(lowerTerm), lowerTerm == null ? null : Integer.parseInt(lowerTerm),
upperTerm == null ? null : Integer.parseInt(upperTerm), upperTerm == null ? null : Integer.parseInt(upperTerm),
@ -191,7 +191,7 @@ public class ShortFieldMapper extends NumberFieldMapper<Short> {
} }
@Override @Override
public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFieldDataFilter.newShortRange(fieldDataCache, names.indexName(), return NumericRangeFieldDataFilter.newShortRange(fieldDataCache, names.indexName(),
lowerTerm == null ? null : Short.parseShort(lowerTerm), lowerTerm == null ? null : Short.parseShort(lowerTerm),
upperTerm == null ? null : Short.parseShort(upperTerm), upperTerm == null ? null : Short.parseShort(upperTerm),

View File

@ -26,6 +26,7 @@ import org.apache.lucene.search.NumericRangeFilter;
import org.apache.lucene.search.NumericRangeQuery; import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.lucene.util.NumericUtils; import org.apache.lucene.util.NumericUtils;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Numbers; import org.elasticsearch.common.Numbers;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
@ -37,6 +38,7 @@ import org.elasticsearch.index.field.data.FieldDataType;
import org.elasticsearch.index.mapper.*; import org.elasticsearch.index.mapper.*;
import org.elasticsearch.index.mapper.core.FloatFieldMapper; import org.elasticsearch.index.mapper.core.FloatFieldMapper;
import org.elasticsearch.index.mapper.core.NumberFieldMapper; import org.elasticsearch.index.mapper.core.NumberFieldMapper;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.search.NumericRangeFieldDataFilter; import org.elasticsearch.index.search.NumericRangeFieldDataFilter;
import java.io.IOException; import java.io.IOException;
@ -165,7 +167,7 @@ public class BoostFieldMapper extends NumberFieldMapper<Float> implements Intern
} }
@Override @Override
public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeQuery.newFloatRange(names.indexName(), precisionStep, return NumericRangeQuery.newFloatRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Float.parseFloat(lowerTerm), lowerTerm == null ? null : Float.parseFloat(lowerTerm),
upperTerm == null ? null : Float.parseFloat(upperTerm), upperTerm == null ? null : Float.parseFloat(upperTerm),
@ -173,7 +175,7 @@ public class BoostFieldMapper extends NumberFieldMapper<Float> implements Intern
} }
@Override @Override
public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFilter.newFloatRange(names.indexName(), precisionStep, return NumericRangeFilter.newFloatRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Float.parseFloat(lowerTerm), lowerTerm == null ? null : Float.parseFloat(lowerTerm),
upperTerm == null ? null : Float.parseFloat(upperTerm), upperTerm == null ? null : Float.parseFloat(upperTerm),
@ -181,7 +183,7 @@ public class BoostFieldMapper extends NumberFieldMapper<Float> implements Intern
} }
@Override @Override
public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFieldDataFilter.newFloatRange(fieldDataCache, names.indexName(), return NumericRangeFieldDataFilter.newFloatRange(fieldDataCache, names.indexName(),
lowerTerm == null ? null : Float.parseFloat(lowerTerm), lowerTerm == null ? null : Float.parseFloat(lowerTerm),
upperTerm == null ? null : Float.parseFloat(upperTerm), upperTerm == null ? null : Float.parseFloat(upperTerm),

View File

@ -25,6 +25,7 @@ import org.apache.lucene.document.Fieldable;
import org.apache.lucene.search.*; import org.apache.lucene.search.*;
import org.apache.lucene.util.NumericUtils; import org.apache.lucene.util.NumericUtils;
import org.elasticsearch.ElasticSearchIllegalArgumentException; import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Numbers; import org.elasticsearch.common.Numbers;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
@ -37,6 +38,7 @@ import org.elasticsearch.index.field.data.FieldDataType;
import org.elasticsearch.index.mapper.*; import org.elasticsearch.index.mapper.*;
import org.elasticsearch.index.mapper.core.LongFieldMapper; import org.elasticsearch.index.mapper.core.LongFieldMapper;
import org.elasticsearch.index.mapper.core.NumberFieldMapper; import org.elasticsearch.index.mapper.core.NumberFieldMapper;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.search.NumericRangeFieldDataFilter; import org.elasticsearch.index.search.NumericRangeFieldDataFilter;
import java.io.IOException; import java.io.IOException;
@ -201,7 +203,7 @@ public class IpFieldMapper extends NumberFieldMapper<Long> {
} }
@Override @Override
public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeQuery.newLongRange(names.indexName(), precisionStep, return NumericRangeQuery.newLongRange(names.indexName(), precisionStep,
lowerTerm == null ? null : ipToLong(lowerTerm), lowerTerm == null ? null : ipToLong(lowerTerm),
upperTerm == null ? null : ipToLong(upperTerm), upperTerm == null ? null : ipToLong(upperTerm),
@ -209,7 +211,7 @@ public class IpFieldMapper extends NumberFieldMapper<Long> {
} }
@Override @Override
public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFilter.newLongRange(names.indexName(), precisionStep, return NumericRangeFilter.newLongRange(names.indexName(), precisionStep,
lowerTerm == null ? null : ipToLong(lowerTerm), lowerTerm == null ? null : ipToLong(lowerTerm),
upperTerm == null ? null : ipToLong(upperTerm), upperTerm == null ? null : ipToLong(upperTerm),
@ -217,7 +219,7 @@ public class IpFieldMapper extends NumberFieldMapper<Long> {
} }
@Override @Override
public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return NumericRangeFieldDataFilter.newLongRange(fieldDataCache, names.indexName(), return NumericRangeFieldDataFilter.newLongRange(fieldDataCache, names.indexName(),
lowerTerm == null ? null : ipToLong(lowerTerm), lowerTerm == null ? null : ipToLong(lowerTerm),
upperTerm == null ? null : ipToLong(upperTerm), upperTerm == null ? null : ipToLong(upperTerm),

View File

@ -75,7 +75,7 @@ public class ExistsFilterParser implements FilterParser {
Filter filter = null; Filter filter = null;
MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName); MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName);
if (smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) { if (smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) {
filter = smartNameFieldMappers.mapper().rangeFilter(null, null, true, true); filter = smartNameFieldMappers.mapper().rangeFilter(null, null, true, true, parseContext);
} }
if (filter == null) { if (filter == null) {
filter = new TermRangeFilter(fieldName, null, null, true, true); filter = new TermRangeFilter(fieldName, null, null, true, true);

View File

@ -76,7 +76,7 @@ public class MissingFilterParser implements FilterParser {
Filter filter = null; Filter filter = null;
MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName); MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName);
if (smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) { if (smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) {
filter = smartNameFieldMappers.mapper().rangeFilter(null, null, true, true); filter = smartNameFieldMappers.mapper().rangeFilter(null, null, true, true, parseContext);
} }
if (filter == null) { if (filter == null) {
filter = new TermRangeFilter(fieldName, null, null, true, true); filter = new TermRangeFilter(fieldName, null, null, true, true);

View File

@ -119,7 +119,7 @@ public class NumericRangeFilterParser implements FilterParser {
if (!(mapper instanceof NumberFieldMapper)) { if (!(mapper instanceof NumberFieldMapper)) {
throw new QueryParsingException(parseContext.index(), "Field [" + fieldName + "] is not a numeric type"); throw new QueryParsingException(parseContext.index(), "Field [" + fieldName + "] is not a numeric type");
} }
Filter filter = ((NumberFieldMapper) mapper).rangeFilter(parseContext.indexCache().fieldData(), from, to, includeLower, includeUpper); Filter filter = ((NumberFieldMapper) mapper).rangeFilter(parseContext.indexCache().fieldData(), from, to, includeLower, includeUpper, parseContext);
if (cache) { if (cache) {
filter = parseContext.cacheFilter(filter, cacheKey); filter = parseContext.cacheFilter(filter, cacheKey);

View File

@ -293,4 +293,12 @@ public class QueryParseContext {
} }
return lookup; return lookup;
} }
public long nowInMillis() {
SearchContext current = SearchContext.current();
if (current != null) {
return current.nowInMillis();
}
return System.currentTimeMillis();
}
} }

View File

@ -116,7 +116,7 @@ public class RangeFilterParser implements FilterParser {
MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName); MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName);
if (smartNameFieldMappers != null) { if (smartNameFieldMappers != null) {
if (smartNameFieldMappers.hasMapper()) { if (smartNameFieldMappers.hasMapper()) {
filter = smartNameFieldMappers.mapper().rangeFilter(from, to, includeLower, includeUpper); filter = smartNameFieldMappers.mapper().rangeFilter(from, to, includeLower, includeUpper, parseContext);
} }
} }
if (filter == null) { if (filter == null) {

View File

@ -108,7 +108,7 @@ public class RangeQueryParser implements QueryParser {
MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName); MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName);
if (smartNameFieldMappers != null) { if (smartNameFieldMappers != null) {
if (smartNameFieldMappers.hasMapper()) { if (smartNameFieldMappers.hasMapper()) {
query = smartNameFieldMappers.mapper().rangeQuery(from, to, includeLower, includeUpper); query = smartNameFieldMappers.mapper().rangeQuery(from, to, includeLower, includeUpper, parseContext);
} }
} }
if (query == null) { if (query == null) {

View File

@ -126,4 +126,19 @@ public class SimpleSearchTests extends AbstractNodesTests {
searchResponse = client.prepareSearch("test").setQuery(QueryBuilders.rangeQuery("field").gte("2010-01-05").lt("2010-01-06")).execute().actionGet(); searchResponse = client.prepareSearch("test").setQuery(QueryBuilders.rangeQuery("field").gte("2010-01-05").lt("2010-01-06")).execute().actionGet();
assertThat(searchResponse.hits().totalHits(), equalTo(1l)); assertThat(searchResponse.hits().totalHits(), equalTo(1l));
} }
@Test
public void simpleDateMathTests() throws Exception {
client.admin().indices().prepareDelete().execute().actionGet();
client.admin().indices().prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder()).execute().actionGet();
client.prepareIndex("test", "type1", "1").setSource("field", "2010-01-05T02:00").execute().actionGet();
client.prepareIndex("test", "type1", "2").setSource("field", "2010-01-06T02:00").execute().actionGet();
client.admin().indices().prepareRefresh().execute().actionGet();
SearchResponse searchResponse = client.prepareSearch("test").setQuery(QueryBuilders.rangeQuery("field").gte("2010-01-03||+2d").lte("2010-01-04||+2d")).execute().actionGet();
assertThat(searchResponse.hits().totalHits(), equalTo(2l));
searchResponse = client.prepareSearch("test").setQuery(QueryBuilders.queryString("field:[2010-01-03||+2d TO 2010-01-04||+2d]")).execute().actionGet();
assertThat(searchResponse.hits().totalHits(), equalTo(2l));
}
} }

View File

@ -0,0 +1,43 @@
package org.elasticsearch.test.unit.common.joda;
import org.elasticsearch.common.joda.DateMathParser;
import org.elasticsearch.common.joda.Joda;
import org.testng.annotations.Test;
import java.util.concurrent.TimeUnit;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
/**
*/
@Test
public class DateMathParserTests {
@Test
public void dataMathTests() {
DateMathParser parser = new DateMathParser(Joda.forPattern("dateOptionalTime"), TimeUnit.MILLISECONDS);
assertThat(parser.parse("now", 0), equalTo(0l));
assertThat(parser.parse("now+m", 0), equalTo(TimeUnit.MINUTES.toMillis(1)));
assertThat(parser.parse("now+1m", 0), equalTo(TimeUnit.MINUTES.toMillis(1)));
assertThat(parser.parse("now+11m", 0), equalTo(TimeUnit.MINUTES.toMillis(11)));
assertThat(parser.parse("now+1d", 0), equalTo(TimeUnit.DAYS.toMillis(1)));
assertThat(parser.parse("now+1m+1s", 0), equalTo(TimeUnit.MINUTES.toMillis(1) + TimeUnit.SECONDS.toMillis(1)));
assertThat(parser.parse("now+1m-1s", 0), equalTo(TimeUnit.MINUTES.toMillis(1) - TimeUnit.SECONDS.toMillis(1)));
assertThat(parser.parse("now+1m+1s/m", 0), equalTo(TimeUnit.MINUTES.toMillis(1)));
assertThat(parser.parseUpperInclusive("now+1m+1s/m", 0), equalTo(TimeUnit.MINUTES.toMillis(2)));
}
@Test
public void actualDateTests() {
DateMathParser parser = new DateMathParser(Joda.forPattern("dateOptionalTime"), TimeUnit.MILLISECONDS);
assertThat(parser.parse("1970-01-01", 0), equalTo(0l));
assertThat(parser.parse("1970-01-01||+1m", 0), equalTo(TimeUnit.MINUTES.toMillis(1)));
assertThat(parser.parse("1970-01-01||+1m+1s", 0), equalTo(TimeUnit.MINUTES.toMillis(1) + TimeUnit.SECONDS.toMillis(1)));
}
}