Skip to content

Commit c7a7c79

Browse files
committed
Fix sorted query when date_nanos is used as the numeric_type (#64183)
The formatting of the global bottom value does not take the resolution of the provided numeric_type into account. This change fixes this bug by providing the resolution directly in the doc value format if the numeric_type is provided as `date_nanos`. Closes #63719
1 parent f5631f4 commit c7a7c79

File tree

3 files changed

+63
-24
lines changed

3 files changed

+63
-24
lines changed

server/src/internalClusterTest/java/org/elasticsearch/search/sort/FieldSortIT.java

Lines changed: 60 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1751,7 +1751,6 @@ public void testCastNumericType() throws Exception {
17511751
}
17521752
}
17531753

1754-
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/63719")
17551754
public void testCastDate() throws Exception {
17561755
assertAcked(prepareCreate("index_date")
17571756
.addMapping("_doc", "field", "type=date"));
@@ -1769,7 +1768,7 @@ public void testCastDate() throws Exception {
17691768
{
17701769
SearchResponse response = client().prepareSearch()
17711770
.setQuery(matchAllQuery())
1772-
.setSize(builders.size())
1771+
.setSize(2)
17731772
.addSort(SortBuilders.fieldSort("field").setNumericType("date"))
17741773
.get();
17751774
SearchHits hits = response.getHits();
@@ -1780,12 +1779,36 @@ public void testCastDate() throws Exception {
17801779
}
17811780
assertEquals(1712879236854L, hits.getAt(0).getSortValues()[0]);
17821781
assertEquals(1712879237000L, hits.getAt(1).getSortValues()[0]);
1782+
1783+
response = client().prepareSearch()
1784+
.setMaxConcurrentShardRequests(1)
1785+
.setQuery(matchAllQuery())
1786+
.setSize(1)
1787+
.addSort(SortBuilders.fieldSort("field").setNumericType("date"))
1788+
.get();
1789+
hits = response.getHits();
1790+
1791+
assertEquals(1, hits.getHits().length);
1792+
assertThat(hits.getAt(0).getSortValues()[0].getClass(), equalTo(Long.class));
1793+
assertEquals(1712879236854L, hits.getAt(0).getSortValues()[0]);
1794+
1795+
response = client().prepareSearch()
1796+
.setMaxConcurrentShardRequests(1)
1797+
.setQuery(matchAllQuery())
1798+
.setSize(1)
1799+
.addSort(SortBuilders.fieldSort("field").order(SortOrder.DESC).setNumericType("date"))
1800+
.get();
1801+
hits = response.getHits();
1802+
1803+
assertEquals(1, hits.getHits().length);
1804+
assertThat(hits.getAt(0).getSortValues()[0].getClass(), equalTo(Long.class));
1805+
assertEquals(1712879237000L, hits.getAt(0).getSortValues()[0]);
17831806
}
17841807

17851808
{
17861809
SearchResponse response = client().prepareSearch()
17871810
.setQuery(matchAllQuery())
1788-
.setSize(builders.size())
1811+
.setSize(2)
17891812
.addSort(SortBuilders.fieldSort("field").setNumericType("date_nanos"))
17901813
.get();
17911814
SearchHits hits = response.getHits();
@@ -1795,38 +1818,58 @@ public void testCastDate() throws Exception {
17951818
}
17961819
assertEquals(1712879236854775807L, hits.getAt(0).getSortValues()[0]);
17971820
assertEquals(1712879237000000000L, hits.getAt(1).getSortValues()[0]);
1821+
1822+
response = client().prepareSearch()
1823+
.setMaxConcurrentShardRequests(1)
1824+
.setQuery(matchAllQuery())
1825+
.setSize(1)
1826+
.addSort(SortBuilders.fieldSort("field").setNumericType("date_nanos"))
1827+
.get();
1828+
hits = response.getHits();
1829+
assertEquals(1, hits.getHits().length);
1830+
assertThat(hits.getAt(0).getSortValues()[0].getClass(), equalTo(Long.class));
1831+
assertEquals(1712879236854775807L, hits.getAt(0).getSortValues()[0]);
1832+
1833+
response = client().prepareSearch()
1834+
.setMaxConcurrentShardRequests(1)
1835+
.setQuery(matchAllQuery())
1836+
.setSize(1)
1837+
.addSort(SortBuilders.fieldSort("field").order(SortOrder.DESC).setNumericType("date_nanos"))
1838+
.get();
1839+
hits = response.getHits();
1840+
assertEquals(1, hits.getHits().length);
1841+
assertThat(hits.getAt(0).getSortValues()[0].getClass(), equalTo(Long.class));
1842+
assertEquals(1712879237000000000L, hits.getAt(0).getSortValues()[0]);
17981843
}
17991844

18001845
{
18011846
builders.clear();
18021847
builders.add(client().prepareIndex("index_date", "_doc")
18031848
.setSource("field", "1905-04-11T23:47:17"));
18041849
indexRandom(true, true, builders);
1805-
SearchPhaseExecutionException exc = expectThrows(SearchPhaseExecutionException.class,
1806-
() -> client().prepareSearch()
1850+
SearchResponse response = client().prepareSearch()
18071851
.setQuery(matchAllQuery())
1808-
.setSize(builders.size())
1809-
.setAllowPartialSearchResults(false)
1852+
.setSize(1)
18101853
.addSort(SortBuilders.fieldSort("field").setNumericType("date_nanos"))
1811-
.get()
1812-
);
1813-
assertThat(exc.toString(), containsString("are before the epoch in 1970"));
1854+
.get();
1855+
assertNotNull(response.getShardFailures());
1856+
assertThat(response.getShardFailures().length, equalTo(1));
1857+
assertThat(response.getShardFailures()[0].toString(), containsString("are before the epoch in 1970"));
18141858
}
18151859

18161860
{
18171861
builders.clear();
18181862
builders.add(client().prepareIndex("index_date", "_doc")
18191863
.setSource("field", "2346-04-11T23:47:17"));
18201864
indexRandom(true, true, builders);
1821-
SearchPhaseExecutionException exc = expectThrows(SearchPhaseExecutionException.class,
1822-
() -> client().prepareSearch()
1865+
SearchResponse response = client().prepareSearch()
18231866
.setQuery(QueryBuilders.rangeQuery("field").gt("1970-01-01"))
1824-
.setSize(builders.size())
1825-
.setAllowPartialSearchResults(false)
1867+
.setSize(10)
18261868
.addSort(SortBuilders.fieldSort("field").setNumericType("date_nanos"))
1827-
.get()
1828-
);
1829-
assertThat(exc.toString(), containsString("are after 2262"));
1869+
.get();
1870+
assertNotNull(response.getShardFailures());
1871+
assertThat(response.getShardFailures().length, equalTo(1));
1872+
assertThat(response.getShardFailures()[0].toString(), containsString("are after 2262"));
18301873
}
18311874
}
18321875

server/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ public SortFieldAndFormat build(QueryShardContext context) throws IOException {
412412
IndexNumericFieldData numericFieldData = (IndexNumericFieldData) fieldData;
413413
NumericType resolvedType = resolveNumericType(numericType);
414414
field = numericFieldData.sortField(resolvedType, missing, localSortMode(), nested, reverse);
415+
isNanosecond = resolvedType == NumericType.DATE_NANOSECONDS;
415416
} else {
416417
field = fieldData.sortField(missing, localSortMode(), nested, reverse);
417418
if (fieldData instanceof IndexNumericFieldData) {
@@ -452,11 +453,6 @@ public boolean isBottomSortShardDisjoint(QueryShardContext context, SearchSortVa
452453
DocValueFormat docValueFormat = bottomSortValues.getSortValueFormats()[0];
453454
final DateMathParser dateMathParser;
454455
if (docValueFormat instanceof DocValueFormat.DateTime) {
455-
if (fieldType instanceof DateFieldType && ((DateFieldType) fieldType).resolution() == NANOSECONDS) {
456-
// we parse the formatted value with the resolution of the local field because
457-
// the provided format can use a different one (date vs date_nanos).
458-
docValueFormat = DocValueFormat.withNanosecondResolution(docValueFormat);
459-
}
460456
dateMathParser = ((DocValueFormat.DateTime) docValueFormat).getDateMathParser();
461457
} else {
462458
dateMathParser = null;

server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public FieldSortBuilder randomFieldSortBuilder() {
128128
}
129129
}
130130
if (randomBoolean()) {
131-
builder.setNumericType(randomFrom(random(), "long", "double", "date", "date_nanos"));
131+
builder.setNumericType(randomFrom(random(), "long", "double"));
132132
}
133133
return builder;
134134
}
@@ -166,7 +166,7 @@ protected FieldSortBuilder mutate(FieldSortBuilder original) throws IOException
166166
break;
167167
case 5:
168168
mutated.setNumericType(randomValueOtherThan(original.getNumericType(),
169-
() -> randomFrom("long", "double", "date", "date_nanos")));
169+
() -> randomFrom("long", "double")));
170170
break;
171171
default:
172172
throw new IllegalStateException("Unsupported mutation.");

0 commit comments

Comments
 (0)