Description
Elasticsearch version (Version: 6.3.0 (docker image based on docker.elastic.co/elasticsearch/elasticsearch:6.3.0)):
Plugins installed: []
JVM version (client build 1.8.0_171-b11):
OS version (Linux 4.15.0-23-generic):
Description of the problem including expected versus actual behavior:
The date histogram ignores the format of the aggregation or date field
if the search is performed on multiple indexes where the alphabetically first index does not contain the date field. This results in an unexpected value for the key_as_string in the bucket
Steps to reproduce:
I created a unit test to reproduce the issue. This uses the following mappings:
searchIndexWithDateField.json
{
"doc": {
"dynamic": "strict",
"properties": {
"title": {
"type": "keyword",
"index": false
},
"dateField": {
"type": "date",
"format": "yyyy-MM-dd"
}
}
}
}
searchIndexWithoutDateField.json
{
"doc": {
"dynamic": "strict",
"properties": {
"title": {
"type": "keyword",
"index": false
}
}
}
}
The unit test itself uses version 6.3.0 for the java client maven dependencies:
package nl.gellygwin;
import org.apache.commons.io.IOUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class DateHistogramFormatTest {
private static final String INDEX_TYPE = "doc";
private static final String AGGREGATION_NAME = "dateTest";
private static final String DATE_FIELD = "dateField";
private TransportClient transportClient;
@Before
public void before() throws UnknownHostException {
transportClient = new PreBuiltTransportClient(Settings.builder()
.put("cluster.name", "docker-cluster")
.build())
.addTransportAddress(new TransportAddress(InetAddress.getByName("localhost"), 9300));
transportClient.admin().indices().prepareDelete("_all")
.get();
}
@Test
public void testDateFieldFormatIncorrect() throws IOException {
//setup indexes
final String indexNameWithDateField = "b";
final String indexNameWithoutDateField = "a";
setup(indexNameWithDateField, indexNameWithoutDateField);
final SearchResponse searchResponse = transportClient.prepareSearch("*")
.addAggregation(AggregationBuilders.dateHistogram(AGGREGATION_NAME)
.dateHistogramInterval(DateHistogramInterval.MONTH)
.field(DATE_FIELD))
.get();
System.out.println("testDateFieldFormatIncorrect: " + searchResponse.getAggregations().get(AGGREGATION_NAME));
}
@Test
public void testDateFieldFormatCorrect() throws IOException {
//setup indexes
final String indexNameWithDateField = "a";
final String indexNameWithoutDateField = "b";
setup(indexNameWithDateField, indexNameWithoutDateField);
final SearchResponse searchResponse = transportClient.prepareSearch("*")
.addAggregation(AggregationBuilders.dateHistogram(AGGREGATION_NAME)
.dateHistogramInterval(DateHistogramInterval.MONTH)
.field(DATE_FIELD))
.get();
System.out.println("testDateFieldFormatCorrect: " + searchResponse.getAggregations().get(AGGREGATION_NAME));
}
@Test
public void testAggregationFormatIncorrect() throws IOException {
//setup indexes
final String indexNameWithDateField = "b";
final String indexNameWithoutDateField = "a";
setup(indexNameWithDateField, indexNameWithoutDateField);
final SearchResponse searchResponse = transportClient.prepareSearch("*")
.addAggregation(AggregationBuilders.dateHistogram(AGGREGATION_NAME)
.dateHistogramInterval(DateHistogramInterval.MONTH)
.format("yyyy-MM-dd")
.field(DATE_FIELD))
.get();
System.out.println("testAggregationFormatIncorrect: " + searchResponse.getAggregations().get(AGGREGATION_NAME));
}
@Test
public void testAggregationFormatCorrect() throws IOException {
//setup indexes
final String indexNameWithDateField = "a";
final String indexNameWithoutDateField = "b";
setup(indexNameWithDateField, indexNameWithoutDateField);
final SearchResponse searchResponse = transportClient.prepareSearch("*")
.addAggregation(AggregationBuilders.dateHistogram(AGGREGATION_NAME)
.dateHistogramInterval(DateHistogramInterval.MONTH)
.format("yyyy-MM-dd")
.field(DATE_FIELD))
.get();
System.out.println("testAggregationFormatCorrect: " + searchResponse.getAggregations().get(AGGREGATION_NAME));
}
private void setup(String indexNameWithDateField, String indexNameWithoutDateField) throws IOException {
transportClient.admin().indices().prepareCreate(indexNameWithDateField)
.addMapping(INDEX_TYPE, readMappingWithDateField(), XContentType.JSON)
.get();
transportClient.admin().indices().prepareCreate(indexNameWithoutDateField)
.addMapping(INDEX_TYPE, readMappingWithoutDateField(), XContentType.JSON)
.get();
//create data
transportClient.prepareIndex(indexNameWithDateField, INDEX_TYPE, "1")
.setSource("{\"title\": \"1\", \"dateField\": \"2018-01-01\"}", XContentType.JSON)
.get();
transportClient.prepareIndex(indexNameWithoutDateField, INDEX_TYPE, "1")
.setSource("{\"title\": \"1\"}", XContentType.JSON)
.get();
transportClient.admin().indices().prepareRefresh(indexNameWithDateField)
.get();
transportClient.admin().indices().prepareRefresh(indexNameWithoutDateField)
.get();
}
private String readMappingWithDateField() throws IOException {
return IOUtils.toString(this.getClass().getResourceAsStream("/searchIndexWithDateField.json"), "UTF-8");
}
private String readMappingWithoutDateField() throws IOException {
return IOUtils.toString(this.getClass().getResourceAsStream("/searchIndexWithoutDateField.json"), "UTF-8");
}
}
The output of these tests are:
testAggregationFormatIncorrect: {"dateTest":{"buckets":[{"key_as_string":"2018-01-01T00:00:00.000Z","key":1514764800000,"doc_count":1}]}}
testDateFieldFormatIncorrect: {"dateTest":{"buckets":[{"key_as_string":"2018-01-01T00:00:00.000Z","key":1514764800000,"doc_count":1}]}}
testDateFieldFormatCorrect: {"dateTest":{"buckets":[{"key_as_string":"2018-01-01","key":1514764800000,"doc_count":1}]}}
testAggregationFormatCorrect: {"dateTest":{"buckets":[{"key_as_string":"2018-01-01","key":1514764800000,"doc_count":1}]}}
You can see that the output for testAggregationFormatIncorrect and testDateFieldFormatIncorrect uses the default date format while the only difference is that the names of the indexes are switched.
I would expect that the output would be the same for all test cases.