Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use date format in date_range mapping before fallback to default #29310

Merged
merged 8 commits into from
May 9, 2018
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,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