|
19 | 19 | import lombok.Getter; |
20 | 20 | import lombok.ToString; |
21 | 21 | import org.opensearch.action.search.*; |
| 22 | +import org.opensearch.cluster.metadata.DataStream; |
| 23 | +import org.opensearch.cluster.metadata.IndexMetadata; |
| 24 | +import org.opensearch.cluster.metadata.Metadata; |
| 25 | +import org.opensearch.common.Nullable; |
22 | 26 | import org.opensearch.common.settings.Settings; |
23 | 27 | import org.opensearch.common.unit.TimeValue; |
24 | 28 | import org.opensearch.common.xcontent.XContentType; |
|
31 | 35 | import org.opensearch.search.SearchModule; |
32 | 36 | import org.opensearch.search.builder.PointInTimeBuilder; |
33 | 37 | import org.opensearch.search.builder.SearchSourceBuilder; |
| 38 | +import org.opensearch.search.sort.SortOrder; |
34 | 39 | import org.opensearch.sql.opensearch.data.value.OpenSearchExprValueFactory; |
35 | 40 | import org.opensearch.sql.opensearch.response.OpenSearchResponse; |
36 | 41 | import org.opensearch.sql.opensearch.storage.OpenSearchIndex; |
@@ -73,6 +78,8 @@ public class OpenSearchQueryRequest implements OpenSearchRequest { |
73 | 78 |
|
74 | 79 | private SearchResponse searchResponse = null; |
75 | 80 |
|
| 81 | + private Metadata metadata; |
| 82 | + |
76 | 83 | /** Constructor of OpenSearchQueryRequest. */ |
77 | 84 | public OpenSearchQueryRequest( |
78 | 85 | String indexName, int size, OpenSearchExprValueFactory factory, List<String> includes) { |
@@ -110,13 +117,15 @@ public OpenSearchQueryRequest( |
110 | 117 | OpenSearchExprValueFactory factory, |
111 | 118 | List<String> includes, |
112 | 119 | TimeValue cursorKeepAlive, |
113 | | - String pitId) { |
| 120 | + String pitId, |
| 121 | + @Nullable Metadata metadata) { |
114 | 122 | this.indexName = indexName; |
115 | 123 | this.sourceBuilder = sourceBuilder; |
116 | 124 | this.exprValueFactory = factory; |
117 | 125 | this.includes = includes; |
118 | 126 | this.cursorKeepAlive = cursorKeepAlive; |
119 | 127 | this.pitId = pitId; |
| 128 | + this.metadata = metadata; |
120 | 129 | } |
121 | 130 |
|
122 | 131 | /** |
@@ -191,10 +200,36 @@ public OpenSearchResponse searchWithPIT(Function<SearchRequest, SearchResponse> |
191 | 200 | } |
192 | 201 | // Set sort field for search_after |
193 | 202 | if (this.sourceBuilder.sorts() == null) { |
194 | | - this.sourceBuilder.sort(DOC_FIELD_NAME, ASC); |
195 | | - // Workaround to preserve sort location more exactly, |
196 | | - // see https://github.com/opensearch-project/sql/pull/3061 |
197 | | - this.sourceBuilder.sort(METADATA_FIELD_ID, ASC); |
| 203 | + boolean specifiedSort = false; |
| 204 | + if (metadata != null) { |
| 205 | + // 1. sort by `index.sort.field` if existed |
| 206 | + IndexMetadata indexMetadata = metadata.index(indexName.toString()); |
| 207 | + if (indexMetadata != null) { |
| 208 | + List<String> sortFields = indexMetadata.getSettings().getAsList("index.sort.field"); |
| 209 | + List<String> sortDirs = indexMetadata.getSettings().getAsList("index.sort.order"); |
| 210 | + for (int i = 0; i < sortFields.size(); i++) { |
| 211 | + this.sourceBuilder.sort(sortFields.get(i), SortOrder.fromString(sortDirs.get(i))); |
| 212 | + specifiedSort = true; |
| 213 | + } |
| 214 | + } |
| 215 | + // 2. sort by `@timestamp` if the data stream is time-series optimized |
| 216 | + if (!specifiedSort) { |
| 217 | + DataStream dataStream = metadata.dataStreams().get(indexName.toString()); |
| 218 | + if (dataStream != null) { |
| 219 | + String timestampField = dataStream.getTimeStampField().getName(); |
| 220 | + if (timestampField.equals("@timestamp")) { |
| 221 | + this.sourceBuilder.sort(timestampField, ASC); |
| 222 | + specifiedSort = true; |
| 223 | + } |
| 224 | + } |
| 225 | + } |
| 226 | + } |
| 227 | + if (!specifiedSort) { |
| 228 | + this.sourceBuilder.sort(DOC_FIELD_NAME, ASC); |
| 229 | + // Workaround to preserve sort location more exactly, |
| 230 | + // see https://github.com/opensearch-project/sql/pull/3061 |
| 231 | + this.sourceBuilder.sort(METADATA_FIELD_ID, ASC); |
| 232 | + } |
198 | 233 | } |
199 | 234 | SearchRequest searchRequest = new SearchRequest().source(this.sourceBuilder); |
200 | 235 | this.searchResponse = searchAction.apply(searchRequest); |
|
0 commit comments