Skip to content

Commit

Permalink
Use date format in date_range mapping before fallback to default (#…
Browse files Browse the repository at this point in the history
…29310)

If the date format is not forced in query, use the format in mapping before 
fallback to the default format.

Closes #29282
  • Loading branch information
Ke Li authored and Christoph Büscher committed May 9, 2018
1 parent 28cc588 commit 5ec9041
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 22 deletions.
9 changes: 9 additions & 0 deletions docs/CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ elasticsearch plugin.

Engine::
* Harden periodically check to avoid endless flush loop {pull}29125[#29125] (issues: {issue}28350[#28350], {issue}29097[#29097])
Use date format in `date_range` mapping before fallback to default ({pull}29310[#29310])

Fix NPE in 'more_like_this' when field has zero tokens ({pull}30365[#30365])

Fixed prerelease version of elasticsearch in the `deb` package to sort before GA versions
({pull}29000[#29000])

Ingest::
* Don't allow referencing the pattern bank name in the pattern bank {pull}29295[#29295] (issue: {issue}29257[#29257])
Expand Down Expand Up @@ -336,6 +342,9 @@ Added put index template API to the high level rest client ({pull}30400[#30400])

Core::
* Remove special handling for _all in nodes info {pull}28971[#28971] (issue: {issue}28797[#28797])
Use date format in `date_range` mapping before fallback to default ({pull}29310[#29310])

Fix NPE in 'more_like_this' when field has zero tokens ({pull}30365[#30365])

Engine::
* Avoid class cast exception from index writer {pull}28989[#28989]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,9 @@ public Query termQuery(Object value, QueryShardContext context) {
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper,
ShapeRelation relation, DateTimeZone timeZone, DateMathParser parser, QueryShardContext context) {
failIfNotIndexed();
if (parser == null) {
parser = dateMathParser();
}
return rangeType.rangeQuery(name(), hasDocValues(), lowerTerm, upperTerm, includeLower, includeUpper, relation,
timeZone, parser, context);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package org.elasticsearch.index.mapper;

import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import org.apache.lucene.document.DoubleRange;
import org.apache.lucene.document.FloatRange;
import org.apache.lucene.document.InetAddressPoint;
Expand All @@ -31,13 +30,16 @@
import org.apache.lucene.search.IndexOrDocValuesQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.mapper.RangeFieldMapper.RangeFieldType;
import org.elasticsearch.index.mapper.RangeFieldMapper.RangeType;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.test.IndexSettingsModule;
Expand All @@ -55,49 +57,80 @@ public class RangeFieldTypeTests extends FieldTypeTestCase {

@Before
public void setupProperties() {
type = RandomPicks.randomFrom(random(), RangeType.values());
type = randomFrom(RangeType.values());
nowInMillis = randomNonNegativeLong();
if (type == RangeType.DATE) {
addModifier(new Modifier("format", true) {
@Override
public void modify(MappedFieldType ft) {
((RangeFieldMapper.RangeFieldType) ft).setDateTimeFormatter(Joda.forPattern("basic_week_date", Locale.ROOT));
((RangeFieldType) ft).setDateTimeFormatter(Joda.forPattern("basic_week_date", Locale.ROOT));
}
});
addModifier(new Modifier("locale", true) {
@Override
public void modify(MappedFieldType ft) {
((RangeFieldMapper.RangeFieldType) ft).setDateTimeFormatter(Joda.forPattern("date_optional_time", Locale.CANADA));
((RangeFieldType) ft).setDateTimeFormatter(Joda.forPattern("date_optional_time", Locale.CANADA));
}
});
}
}

@Override
protected RangeFieldMapper.RangeFieldType createDefaultFieldType() {
return new RangeFieldMapper.RangeFieldType(type, Version.CURRENT);
protected RangeFieldType createDefaultFieldType() {
return new RangeFieldType(type, Version.CURRENT);
}

public void testRangeQuery() throws Exception {
Settings indexSettings = Settings.builder()
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT).build();
IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(randomAlphaOfLengthBetween(1, 10), indexSettings);
QueryShardContext context = new QueryShardContext(0, idxSettings, null, null, null, null, null, xContentRegistry(),
writableRegistry(), null, null, () -> nowInMillis, null);
RangeFieldMapper.RangeFieldType ft = new RangeFieldMapper.RangeFieldType(type, Version.CURRENT);
QueryShardContext context = createContext();
RangeFieldType ft = new RangeFieldType(type, Version.CURRENT);
ft.setName(FIELDNAME);
ft.setIndexOptions(IndexOptions.DOCS);

ShapeRelation relation = RandomPicks.randomFrom(random(), ShapeRelation.values());
boolean includeLower = random().nextBoolean();
boolean includeUpper = random().nextBoolean();
ShapeRelation relation = randomFrom(ShapeRelation.values());
boolean includeLower = randomBoolean();
boolean includeUpper = randomBoolean();
Object from = nextFrom();
Object to = nextTo(from);

assertEquals(getExpectedRangeQuery(relation, from, to, includeLower, includeUpper),
ft.rangeQuery(from, to, includeLower, includeUpper, relation, null, null, context));
}

private QueryShardContext createContext() {
Settings indexSettings = Settings.builder()
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT).build();
IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(randomAlphaOfLengthBetween(1, 10), indexSettings);
return new QueryShardContext(0, idxSettings, null, null, null, null, null, xContentRegistry(),
writableRegistry(), null, null, () -> nowInMillis, null);
}

public void testDateRangeQueryUsingMappingFormat() {
QueryShardContext context = createContext();
RangeFieldType fieldType = new RangeFieldType(RangeType.DATE, Version.CURRENT);
fieldType.setName(FIELDNAME);
fieldType.setIndexOptions(IndexOptions.DOCS);
fieldType.setHasDocValues(false);
ShapeRelation relation = randomFrom(ShapeRelation.values());

// dates will break the default format
final String from = "2016-15-06T15:29:50+08:00";
final String to = "2016-16-06T15:29:50+08:00";

ElasticsearchParseException ex = expectThrows(ElasticsearchParseException.class,
() -> fieldType.rangeQuery(from, to, true, true, relation, null, null, context));
assertEquals("failed to parse date field [2016-15-06T15:29:50+08:00] with format [strict_date_optional_time||epoch_millis]",
ex.getMessage());

// setting mapping format which is compatible with those dates
final FormatDateTimeFormatter formatter = Joda.forPattern("yyyy-dd-MM'T'HH:mm:ssZZ");
assertEquals(1465975790000L, formatter.parser().parseMillis(from));
assertEquals(1466062190000L, formatter.parser().parseMillis(to));

fieldType.setDateTimeFormatter(formatter);
final Query query = fieldType.rangeQuery(from, to, true, true, relation, null, null, context);
assertEquals("field:<ranges:[1465975790000 : 1466062190000]>", query.toString());
}

private Query getExpectedRangeQuery(ShapeRelation relation, Object from, Object to, boolean includeLower, boolean includeUpper) {
switch (type) {
case DATE:
Expand Down Expand Up @@ -277,14 +310,10 @@ public void testParseIp() {
assertEquals(InetAddresses.forString("::1"), RangeFieldMapper.RangeType.IP.parse(new BytesRef("::1"), randomBoolean()));
}

public void testTermQuery() throws Exception, IllegalArgumentException {
public void testTermQuery() throws Exception {
// See https://github.com/elastic/elasticsearch/issues/25950
Settings indexSettings = Settings.builder()
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT).build();
IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(randomAlphaOfLengthBetween(1, 10), indexSettings);
QueryShardContext context = new QueryShardContext(0, idxSettings, null, null, null, null, null, xContentRegistry(),
writableRegistry(), null, null, () -> nowInMillis, null);
RangeFieldMapper.RangeFieldType ft = new RangeFieldMapper.RangeFieldType(type, Version.CURRENT);
QueryShardContext context = createContext();
RangeFieldType ft = new RangeFieldType(type, Version.CURRENT);
ft.setName(FIELDNAME);
ft.setIndexOptions(IndexOptions.DOCS);

Expand Down

0 comments on commit 5ec9041

Please sign in to comment.