Extend nextDoc to delegate to the wrapped doc-value iterator for date_nanos (#39176)

The type date_nanos does not direct doc-value iterators and it needs to extend `next_doc` in order to delegate the call to the wrapped iterator.
This commit is contained in:
Ignacio Vera 2019-02-21 11:09:50 +01:00 committed by iverase
parent f40139c403
commit be8a5315d7
3 changed files with 83 additions and 0 deletions

View File

@ -177,6 +177,11 @@ public class SortedNumericDVIndexFieldData extends DocValuesIndexFieldData imple
public int docValueCount() { public int docValueCount() {
return dv.docValueCount(); return dv.docValueCount();
} }
@Override
public int nextDoc() throws IOException {
return dv.nextDoc();
}
}; };
} }

View File

@ -19,6 +19,7 @@
package org.elasticsearch.index.mapper; package org.elasticsearch.index.mapper;
import org.apache.lucene.document.LongPoint; import org.apache.lucene.document.LongPoint;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.SortedNumericDocValuesField; import org.apache.lucene.document.SortedNumericDocValuesField;
import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexOptions;
@ -26,6 +27,8 @@ import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.MultiReader; import org.apache.lucene.index.MultiReader;
import org.apache.lucene.index.SortedNumericDocValues;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexOrDocValuesQuery; import org.apache.lucene.search.IndexOrDocValuesQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
@ -37,6 +40,9 @@ import org.elasticsearch.common.time.DateFormatters;
import org.elasticsearch.common.time.DateMathParser; import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.core.internal.io.IOUtils; import org.elasticsearch.core.internal.io.IOUtils;
import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.fielddata.AtomicNumericFieldData;
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
import org.elasticsearch.index.fielddata.plain.SortedNumericDVIndexFieldData;
import org.elasticsearch.index.mapper.DateFieldMapper.DateFieldType; import org.elasticsearch.index.mapper.DateFieldMapper.DateFieldType;
import org.elasticsearch.index.mapper.MappedFieldType.Relation; import org.elasticsearch.index.mapper.MappedFieldType.Relation;
import org.elasticsearch.index.mapper.ParseContext.Document; import org.elasticsearch.index.mapper.ParseContext.Document;
@ -214,4 +220,33 @@ public class DateFieldTypeTests extends FieldTypeTestCase {
() -> ft.rangeQuery(date1, date2, true, true, null, null, null, context)); () -> ft.rangeQuery(date1, date2, true, true, null, null, null, context));
assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage()); assertEquals("Cannot search on field [field] since it is not indexed.", e.getMessage());
} }
public void testDateNanoDocValues() throws IOException {
// Create an index with some docValues
Directory dir = newDirectory();
IndexWriter w = new IndexWriter(dir, new IndexWriterConfig(null));
Document doc = new Document();
NumericDocValuesField docValuesField = new NumericDocValuesField("my_date", 1444608000000L);
doc.add(docValuesField);
w.addDocument(doc);
docValuesField.setLongValue(1459641600000L);
w.addDocument(doc);
// Create the doc values reader
Settings settings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1).put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1).build();
IndexSettings indexSettings = new IndexSettings(IndexMetaData.builder("foo").settings(settings).build(), settings);
SortedNumericDVIndexFieldData fieldData = new SortedNumericDVIndexFieldData(indexSettings.getIndex(), "my_date",
IndexNumericFieldData.NumericType.DATE_NANOSECONDS);
// Read index and check the doc values
DirectoryReader reader = DirectoryReader.open(w);
assertTrue(reader.leaves().size() > 0);
AtomicNumericFieldData a = fieldData.load(reader.leaves().get(0).reader().getContext());
SortedNumericDocValues docValues = a.getLongValues();
assertEquals(0, docValues.nextDoc());
assertEquals(1, docValues.nextDoc());
assertEquals(DocIdSetIterator.NO_MORE_DOCS, docValues.nextDoc());
reader.close();
w.close();
dir.close();
}
} }

View File

@ -1561,4 +1561,47 @@ public class DateHistogramIT extends ESIntegTestCase {
private ZonedDateTime key(Histogram.Bucket bucket) { private ZonedDateTime key(Histogram.Bucket bucket) {
return (ZonedDateTime) bucket.getKey(); return (ZonedDateTime) bucket.getKey();
} }
/**
* See https://github.com/elastic/elasticsearch/issues/39107. Make sure we handle properly different
* timeZones.
*/
public void testDateNanosHistogram() throws Exception {
assertAcked(prepareCreate("nanos").addMapping("_doc", "date", "type=date_nanos").get());
indexRandom(true,
client().prepareIndex("nanos", "_doc", "1").setSource("date", "2000-01-01"));
indexRandom(true,
client().prepareIndex("nanos", "_doc", "2").setSource("date", "2000-01-02"));
//Search interval 24 hours
SearchResponse r = client().prepareSearch("nanos")
.addAggregation(dateHistogram("histo").field("date").
interval(1000 * 60 * 60 * 24).timeZone(ZoneId.of("Europe/Berlin")))
.addDocValueField("date")
.get();
assertSearchResponse(r);
Histogram histogram = r.getAggregations().get("histo");
List<? extends Bucket> buckets = histogram.getBuckets();
assertEquals(2, buckets.size());
assertEquals(946681200000L, ((ZonedDateTime)buckets.get(0).getKey()).toEpochSecond() * 1000);
assertEquals(1, buckets.get(0).getDocCount());
assertEquals(946767600000L, ((ZonedDateTime)buckets.get(1).getKey()).toEpochSecond() * 1000);
assertEquals(1, buckets.get(1).getDocCount());
r = client().prepareSearch("nanos")
.addAggregation(dateHistogram("histo").field("date")
.interval(1000 * 60 * 60 * 24).timeZone(ZoneId.of("UTC")))
.addDocValueField("date")
.get();
assertSearchResponse(r);
histogram = r.getAggregations().get("histo");
buckets = histogram.getBuckets();
assertEquals(2, buckets.size());
assertEquals(946684800000L, ((ZonedDateTime)buckets.get(0).getKey()).toEpochSecond() * 1000);
assertEquals(1, buckets.get(0).getDocCount());
assertEquals(946771200000L, ((ZonedDateTime)buckets.get(1).getKey()).toEpochSecond() * 1000);
assertEquals(1, buckets.get(1).getDocCount());
}
} }