From e1409a9f0e3f52f35633cf47051c3e4258f67636 Mon Sep 17 00:00:00 2001 From: Shay Banon Date: Tue, 5 Mar 2013 18:10:30 -0800 Subject: [PATCH] Problems with range searches for time with lte fixes #2731 --- .../common/joda/DateMathParser.java | 6 +++- .../mapper/date/SimpleDateMappingTests.java | 29 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/elasticsearch/common/joda/DateMathParser.java b/src/main/java/org/elasticsearch/common/joda/DateMathParser.java index 7366cb0d58b..17bf4d2d852 100644 --- a/src/main/java/org/elasticsearch/common/joda/DateMathParser.java +++ b/src/main/java/org/elasticsearch/common/joda/DateMathParser.java @@ -198,7 +198,11 @@ public class DateMathParser { private long parseUpperInclusiveStringValue(String value) { try { - MutableDateTime dateTime = new MutableDateTime(3000, 12, 31, 23, 59, 59, 999, DateTimeZone.UTC); + // we create a date time for inclusive upper range, we "include" by default the day level data + // so something like 2011-01-01 will include the full first day of 2011. + // we also use 1970-01-01 as the base for it so we can handle searches like 10:12:55 (just time) + // since when we index those, the base is 1970-01-01 + MutableDateTime dateTime = new MutableDateTime(1970, 1, 1, 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()) { diff --git a/src/test/java/org/elasticsearch/test/unit/index/mapper/date/SimpleDateMappingTests.java b/src/test/java/org/elasticsearch/test/unit/index/mapper/date/SimpleDateMappingTests.java index 97dd6c0f623..a52b7575fad 100644 --- a/src/test/java/org/elasticsearch/test/unit/index/mapper/date/SimpleDateMappingTests.java +++ b/src/test/java/org/elasticsearch/test/unit/index/mapper/date/SimpleDateMappingTests.java @@ -19,15 +19,21 @@ package org.elasticsearch.test.unit.index.mapper.date; +import org.apache.lucene.search.Filter; +import org.apache.lucene.search.NumericRangeFilter; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.index.mapper.DocumentMapper; import org.elasticsearch.index.mapper.FieldMapper; import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.ParsedDocument; import org.elasticsearch.index.mapper.core.DateFieldMapper; +import org.elasticsearch.index.mapper.core.LongFieldMapper; import org.elasticsearch.index.mapper.core.StringFieldMapper; import org.elasticsearch.test.unit.index.mapper.MapperTests; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; import org.testng.annotations.Test; import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder; @@ -106,6 +112,29 @@ public class SimpleDateMappingTests { assertThat(doc.rootDoc().get("date_field_x"), equalTo("2010-01-01")); } + @Test + public void testHourFormat() throws Exception { + String mapping = XContentFactory.jsonBuilder().startObject().startObject("type") + .field("date_detection", false) + .startObject("properties").startObject("date_field").field("type", "date").field("format", "HH:mm:ss").endObject().endObject() + .endObject().endObject().string(); + + DocumentMapper defaultMapper = MapperTests.newParser().parse(mapping); + + ParsedDocument doc = defaultMapper.parse("type", "1", XContentFactory.jsonBuilder() + .startObject() + .field("date_field", "10:00:00") + .endObject() + .bytes()); + assertThat(((LongFieldMapper.CustomLongNumericField) doc.rootDoc().getField("date_field")).numericAsString(), equalTo(Long.toString(new DateTime(TimeValue.timeValueHours(10).millis(), DateTimeZone.UTC).getMillis()))); + + Filter filter = defaultMapper.mappers().smartNameFieldMapper("date_field").rangeFilter("10:00:00", "11:00:00", true, true, null); + assertThat(filter, instanceOf(NumericRangeFilter.class)); + NumericRangeFilter rangeFilter = (NumericRangeFilter) filter; + assertThat(rangeFilter.getMax(), equalTo(new DateTime(TimeValue.timeValueHours(11).millis() + 999).getMillis())); // +999 to include the 00-01 minute + assertThat(rangeFilter.getMin(), equalTo(new DateTime(TimeValue.timeValueHours(10).millis()).getMillis())); + } + @Test public void testIgnoreMalformedOption() throws Exception { String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")