Skip to content

Commit

Permalink
Handle canMatchSearchAfter for frozen context scenario (#11249)
Browse files Browse the repository at this point in the history
* Handle canMatchSearchAfter for frozen context scenario

Signed-off-by: Chaitanya Gohel <[email protected]>

* Addressig review comments

Signed-off-by: Chaitanya Gohel <[email protected]>

* Enable test for 2.12.0 for nano date now

Signed-off-by: Chaitanya Gohel <[email protected]>

---------

Signed-off-by: Chaitanya Gohel <[email protected]>
Signed-off-by: Chaitanya Gohel <[email protected]>
  • Loading branch information
gashutos committed Nov 21, 2023
1 parent 2c02a9c commit 743345d
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Fix per request latency last phase not tracked ([#10934](https://github.com/opensearch-project/OpenSearch/pull/10934))
- Adding version condition while adding geoshape doc values to the index, to ensure backward compatibility.([#11095](https://github.com/opensearch-project/OpenSearch/pull/11095))
- Fix SuggestSearch.testSkipDuplicates by forcing refresh when indexing its test documents ([#11068](https://github.com/opensearch-project/OpenSearch/pull/11068))
- Handle canMatchSearchAfter for frozen context scenario ([#11249](https://github.com/opensearch-project/OpenSearch/pull/11249))

### Security

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,99 @@ setup:
- match: { aggregations.date.buckets.1.key: 1540857600000 }
- match: { aggregations.date.buckets.1.key_as_string: "2018-10-30T00:00:00.000Z" }
- match: { aggregations.date.buckets.1.doc_count: 2 }


---
"date with nested sort now":
- skip:
version: " - 2.11.99"
reason: fixed in 2.12.0

# This tests cover scenario where nested sort have now() in date field type.
# For this test, we have date field as nested field and we trigger asc/desc sort
# on that nested field. `filter` clause is needed when we sort any nested field,
# like in this case, "gte": "now/h" says sort nested field date_field only where
# document is having value greater than current time now().
# Nested field sort query doesn't sort documents if it is not qualified through
# `filter` clause.
# Only adding tests for `gte` as `lte` would be same behaviour

- do:
indices.create:
index: test
body:
mappings:
properties:
nested_field:
type: nested
properties:
date_field:
type: date
format: date_optional_time
- do:
bulk:
refresh: true
index: test
body: |
{"index":{}}
{"nested_field": [{"date_field": "3023-10-26T12:00:00+09:00"}]}
{"index":{}}
{"nested_field": [{"date_field": "3024-10-26T12:00:00+09:00"}]}
{"index":{}}
{"nested_field": [{"date_field": "3025-10-26T12:00:00+09:00"}]}
{"index":{}}
{"nested_field": [{"date_field": "3026-10-26T12:00:00+09:00"}]}
{"index":{}}
{"nested_field": [{"date_field": "3027-10-26T12:00:00+09:00"}]}
{"index":{}}
{"nested_field": [{"date_field": "2022-10-26T12:00:00+09:00"}]}
{"index":{}}
{"nested_field": [{"date_field": "2023-10-26T12:00:00+09:00"}]}
{"index":{}}
{"nested_field": [{"date_field": "2021-10-26T12:00:00+09:00"}]}
{"index":{}}
{"nested_field": [{"date_field": "2020-10-26T12:00:00+09:00"}]}
{"index":{}}
{"nested_field": [{"date_field": "2019-10-26T12:00:00+09:00"}]}
# gte: now/h with the desc sort
- do:
search:
index: test
body:
size: 5
sort: [{ nested_field.date_field: { mode: max, order: desc, nested: { path: nested_field, filter: { bool: { filter : [{ range : { nested_field.date_field: { gte: now/h, time_zone: +09:00} } }] } } } } } ]
- match: {hits.total.value: 10 }
- length: {hits.hits: 5 }
- match: { hits.hits.0._index: test }
- match: { hits.hits.0._source.nested_field.0.date_field: "3027-10-26T12:00:00+09:00" }
- match: { hits.hits.0.sort: [33381428400000] }
- match: { hits.hits.1._source.nested_field.0.date_field: "3026-10-26T12:00:00+09:00" }
- match: { hits.hits.1.sort: [ 33349892400000 ] }
- match: { hits.hits.2._source.nested_field.0.date_field: "3025-10-26T12:00:00+09:00" }
- match: { hits.hits.2.sort: [ 33318356400000 ] }
- match: { hits.hits.3._source.nested_field.0.date_field: "3024-10-26T12:00:00+09:00" }
- match: { hits.hits.3.sort: [ 33286820400000 ] }
- match: { hits.hits.4._source.nested_field.0.date_field: "3023-10-26T12:00:00+09:00" }
- match: { hits.hits.4.sort: [ 33255198000000 ] }

# gte: now/h with the asc sort
- do:
search:
index: test
body:
size: 5
sort: [ { nested_field.date_field: { mode: max, order: asc, nested: { path: nested_field, filter: { bool: { filter: [ { range: { nested_field.date_field: { gte: now/h, time_zone: +09:00 } } } ] } } } } } ]
- match: { hits.total.value: 10 }
- length: { hits.hits: 5 }
- match: { hits.hits.0._index: test }
- match: { hits.hits.0._source.nested_field.0.date_field: "3023-10-26T12:00:00+09:00" }
- match: { hits.hits.0.sort: [ 33255198000000 ] }
- match: { hits.hits.1._source.nested_field.0.date_field: "3024-10-26T12:00:00+09:00" }
- match: { hits.hits.1.sort: [ 33286820400000 ] }
- match: { hits.hits.2._source.nested_field.0.date_field: "3025-10-26T12:00:00+09:00" }
- match: { hits.hits.2.sort: [ 33318356400000 ] }
- match: { hits.hits.3._source.nested_field.0.date_field: "3026-10-26T12:00:00+09:00" }
- match: { hits.hits.3.sort: [ 33349892400000 ] }
- match: { hits.hits.4._source.nested_field.0.date_field: "3027-10-26T12:00:00+09:00" }
- match: { hits.hits.4.sort: [ 33381428400000 ] }
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@
- match: {hits.hits.0._source.timestamp: "2019-10-21 08:30:04.828733" }
- match: {hits.hits.0.sort: [1571646604828733000] }

# search_after with the sort
# search_after with the asc sort
- do:
search:
index: test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -507,14 +507,15 @@ private boolean canMatch(LeafReaderContext ctx) throws IOException {
}

private boolean canMatchSearchAfter(LeafReaderContext ctx) throws IOException {
if (searchContext.request() != null && searchContext.request().source() != null) {
if (searchContext.searchAfter() != null && searchContext.request() != null && searchContext.request().source() != null) {
// Only applied on primary sort field and primary search_after.
FieldSortBuilder primarySortField = FieldSortBuilder.getPrimaryFieldSortOrNull(searchContext.request().source());
if (primarySortField != null) {
MinAndMax<?> minMax = FieldSortBuilder.getMinMaxOrNullForSegment(
this.searchContext.getQueryShardContext(),
ctx,
primarySortField
primarySortField,
searchContext.sort()
);
return SearchService.canMatchSearchAfter(
searchContext.searchAfter(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,22 +616,30 @@ public static FieldSortBuilder getPrimaryFieldSortOrNull(SearchSourceBuilder sou
* and configurations return <code>null</code>.
*/
public static MinAndMax<?> getMinMaxOrNull(QueryShardContext context, FieldSortBuilder sortBuilder) throws IOException {
return getMinMaxOrNullInternal(context.getIndexReader(), context, sortBuilder);
final SortAndFormats sort = SortBuilder.buildSort(Collections.singletonList(sortBuilder), context).get();
return getMinMaxOrNullInternal(context.getIndexReader(), context, sortBuilder, sort);
}

/**
* Return the {@link MinAndMax} indexed value for segment from the provided {@link FieldSortBuilder} or <code>null</code> if unknown.
* The value can be extracted on non-nested indexed mapped fields of type keyword, numeric or date, other fields
* and configurations return <code>null</code>.
*/
public static MinAndMax<?> getMinMaxOrNullForSegment(QueryShardContext context, LeafReaderContext ctx, FieldSortBuilder sortBuilder)
throws IOException {
return getMinMaxOrNullInternal(ctx.reader(), context, sortBuilder);
public static MinAndMax<?> getMinMaxOrNullForSegment(
QueryShardContext context,
LeafReaderContext ctx,
FieldSortBuilder sortBuilder,
SortAndFormats sort
) throws IOException {
return getMinMaxOrNullInternal(ctx.reader(), context, sortBuilder, sort);
}

private static MinAndMax<?> getMinMaxOrNullInternal(IndexReader reader, QueryShardContext context, FieldSortBuilder sortBuilder)
throws IOException {
SortAndFormats sort = SortBuilder.buildSort(Collections.singletonList(sortBuilder), context).get();
private static MinAndMax<?> getMinMaxOrNullInternal(
IndexReader reader,
QueryShardContext context,
FieldSortBuilder sortBuilder,
SortAndFormats sort
) throws IOException {
SortField sortField = sort.sort.getSort()[0];
if (sortField.getField() == null) {
return null;
Expand Down

0 comments on commit 743345d

Please sign in to comment.