2727import org .elasticsearch .search .sort .SortOrder ;
2828
2929import java .util .ArrayList ;
30- import java .util .Arrays ;
30+ import java .util .Collections ;
3131import java .util .EnumSet ;
3232import java .util .List ;
3333import java .util .Locale ;
@@ -107,31 +107,68 @@ public final class IndexSortConfig {
107107 );
108108
109109 public static class IndexSortConfigDefaults {
110- public static final FieldSortSpec [] TIME_SERIES_SORT , HOSTNAME_TIMESTAMP_BWC_SORT ;
110+ public record SortDefault (List <String > fields , List <String > order , List <String > mode , List <String > missing ) {
111+ public SortDefault {
112+ assert fields .size () == order .size ();
113+ assert fields .size () == mode .size ();
114+ assert fields .size () == missing .size ();
115+ }
116+ }
111117
112- private static final FieldSortSpec HOSTNAME_SPEC , MESSAGE_PATTERN_SPEC , TIMESTAMP_SPEC ;
118+ public static final SortDefault NO_SORT , TIME_SERIES_SORT , TIMESTAMP_SORT , HOSTNAME_TIMESTAMP_SORT , HOSTNAME_TIMESTAMP_BWC_SORT ,
119+ MESSAGE_PATTERN_TIMESTAMP_SORT , HOSTNAME_MESSAGE_PATTERN_TIMESTAMP_SORT ;
113120
114121 static {
115- TIMESTAMP_SPEC = new FieldSortSpec (DataStreamTimestampFieldMapper .DEFAULT_PATH );
116- TIMESTAMP_SPEC .order = SortOrder .DESC ;
117- TIME_SERIES_SORT = new FieldSortSpec [] { new FieldSortSpec (TimeSeriesIdFieldMapper .NAME ), TIMESTAMP_SPEC };
122+ NO_SORT = new SortDefault (Collections .emptyList (), Collections .emptyList (), Collections .emptyList (), Collections .emptyList ());
118123
119- HOSTNAME_SPEC = new FieldSortSpec (IndexMode .HOST_NAME );
120- HOSTNAME_SPEC .order = SortOrder .ASC ;
121- HOSTNAME_SPEC .missingValue = "_last" ;
122- HOSTNAME_SPEC .mode = MultiValueMode .MIN ;
124+ TIME_SERIES_SORT = new SortDefault (
125+ List .of (TimeSeriesIdFieldMapper .NAME , DataStreamTimestampFieldMapper .DEFAULT_PATH ),
126+ List .of ("asc" , "desc" ),
127+ List .of ("min" , "max" ),
128+ List .of ("_last" , "_last" )
129+ );
123130
124- MESSAGE_PATTERN_SPEC = new FieldSortSpec ("message.template_id" );
131+ TIMESTAMP_SORT = new SortDefault (
132+ List .of (DataStreamTimestampFieldMapper .DEFAULT_PATH ),
133+ List .of ("desc" ),
134+ List .of ("max" ),
135+ List .of ("_last" )
136+ );
137+
138+ HOSTNAME_TIMESTAMP_SORT = new SortDefault (
139+ List .of (IndexMode .HOST_NAME , DataStreamTimestampFieldMapper .DEFAULT_PATH ),
140+ List .of ("asc" , "desc" ),
141+ List .of ("min" , "max" ),
142+ List .of ("_last" , "_last" )
143+ );
144+
145+ MESSAGE_PATTERN_TIMESTAMP_SORT = new SortDefault (
146+ List .of ("message.template_id" , DataStreamTimestampFieldMapper .DEFAULT_PATH ),
147+ List .of ("asc" , "desc" ),
148+ List .of ("min" , "max" ),
149+ List .of ("_last" , "_last" )
150+ );
151+
152+ HOSTNAME_MESSAGE_PATTERN_TIMESTAMP_SORT = new SortDefault (
153+ List .of (IndexMode .HOST_NAME , "message.template_id" , DataStreamTimestampFieldMapper .DEFAULT_PATH ),
154+ List .of ("asc" , "asc" , "desc" ),
155+ List .of ("min" , "min" , "max" ),
156+ List .of ("_last" , "_last" , "_last" )
157+ );
125158
126159 // Older indexes use ascending ordering for host name and timestamp.
127- HOSTNAME_TIMESTAMP_BWC_SORT = new FieldSortSpec [] {
128- new FieldSortSpec (IndexMode .HOST_NAME ),
129- new FieldSortSpec (DataStreamTimestampFieldMapper .DEFAULT_PATH ) };
160+ HOSTNAME_TIMESTAMP_BWC_SORT = new SortDefault (
161+ List .of (IndexMode .HOST_NAME , DataStreamTimestampFieldMapper .DEFAULT_PATH ),
162+ List .of ("asc" , "asc" ),
163+ List .of ("min" , "min" ),
164+ List .of ("_last" , "_last" )
165+ );
166+
130167 }
131168
132- public static FieldSortSpec [] getDefaultSortSpecs (Settings settings ) {
169+ static SortDefault getSortDefault (Settings settings ) {
133170 if (settings .isEmpty ()) {
134- return new FieldSortSpec [ 0 ] ;
171+ return NO_SORT ;
135172 }
136173
137174 // Can't use IndexSettings.MODE.get(settings) here because the validation logic for IndexSettings.MODE uses the default value
@@ -152,71 +189,73 @@ public static FieldSortSpec[] getDefaultSortSpecs(Settings settings) {
152189 IndexVersions .UPGRADE_TO_LUCENE_10_0_0
153190 )) {
154191
155- List <FieldSortSpec > sortSpecs = new ArrayList <>(3 );
156- if (IndexSettings .LOGSDB_SORT_ON_HOST_NAME .get (settings )) {
157- sortSpecs .add (HOSTNAME_SPEC );
158- }
159- if (IndexSettings .LOGSDB_SORT_ON_MESSAGE_TEMPLATE .get (settings )) {
160- sortSpecs .add (MESSAGE_PATTERN_SPEC );
192+ boolean sortOnHostName = settings .getAsBoolean (IndexSettings .LOGSDB_SORT_ON_HOST_NAME .getKey (), false );
193+ boolean sortOnMessageTemplate = settings .getAsBoolean (IndexSettings .LOGSDB_SORT_ON_MESSAGE_TEMPLATE .getKey (), false );
194+ if (sortOnHostName && sortOnMessageTemplate ) {
195+ return HOSTNAME_MESSAGE_PATTERN_TIMESTAMP_SORT ;
196+ } else if (sortOnHostName ) {
197+ return HOSTNAME_TIMESTAMP_SORT ;
198+ } else if (sortOnMessageTemplate ) {
199+ return MESSAGE_PATTERN_TIMESTAMP_SORT ;
200+ } else {
201+ return TIMESTAMP_SORT ;
161202 }
162- sortSpecs .add (TIMESTAMP_SPEC );
163-
164- return sortSpecs .toArray (FieldSortSpec []::new );
165203 } else {
166204 return HOSTNAME_TIMESTAMP_BWC_SORT ;
167205 }
168206 }
169207
170- return new FieldSortSpec [0 ];
171- }
172-
173- public static FieldSortSpec [] getSortSpecs (Settings settings ) {
174- if (INDEX_SORT_FIELD_SETTING .exists (settings ) == false ) {
175- return IndexSortConfigDefaults .getDefaultSortSpecs (settings );
176- }
177-
178- List <String > fields = INDEX_SORT_FIELD_SETTING .get (settings );
179- FieldSortSpec [] sortSpecs = fields .stream ().map (FieldSortSpec ::new ).toArray (FieldSortSpec []::new );
180-
181- // Need to populate `order` because the default value of `mode` depends on it
182- if (INDEX_SORT_ORDER_SETTING .exists (settings )) {
183- List <SortOrder > orders = INDEX_SORT_ORDER_SETTING .get (settings );
184- for (int i = 0 ; i < sortSpecs .length ; i ++) {
185- sortSpecs [i ].order = orders .get (i );
186- }
187- }
188-
189- return sortSpecs ;
208+ return NO_SORT ;
190209 }
191210
192211 public static List <String > getDefaultSortFields (Settings settings ) {
193- return Arrays . stream ( getDefaultSortSpecs ( settings )). map ( sortSpec -> sortSpec . field ). toList ();
212+ return getSortDefault ( settings ). fields ();
194213 }
195214
196215 public static List <String > getDefaultSortOrder (Settings settings ) {
197- return Arrays .stream (getSortSpecs (settings ))
198- .map (sortSpec -> sortSpec .order != null ? sortSpec .order : SortOrder .ASC )
199- .map (Enum ::toString )
200- .toList ();
216+ if (settings .hasValue (INDEX_SORT_FIELD_SETTING .getKey ()) == false ) {
217+ return getSortDefault (settings ).order ();
218+ }
219+
220+ List <String > sortFields = settings .getAsList (INDEX_SORT_FIELD_SETTING .getKey ());
221+ List <String > order = new ArrayList <>(sortFields .size ());
222+ for (int i = 0 ; i < sortFields .size (); ++i ) {
223+ order .add ("asc" );
224+ }
225+ return order ;
201226 }
202227
203228 public static List <String > getDefaultSortMode (Settings settings ) {
204- return Arrays .stream (getSortSpecs (settings )).map (sortSpec -> {
205- if (sortSpec .mode != null ) {
206- return sortSpec .mode ;
207- } else if (sortSpec .order == SortOrder .DESC ) {
208- return MultiValueMode .MAX ;
229+ if (settings .hasValue (INDEX_SORT_FIELD_SETTING .getKey ()) == false ) {
230+ return getSortDefault (settings ).mode ();
231+ }
232+
233+ List <String > sortFields = settings .getAsList (INDEX_SORT_FIELD_SETTING .getKey ());
234+ List <String > sortOrder = settings .getAsList (INDEX_SORT_ORDER_SETTING .getKey (), null );
235+
236+ List <String > mode = new ArrayList <>(sortFields .size ());
237+ for (int i = 0 ; i < sortFields .size (); ++i ) {
238+ if (sortOrder != null && sortOrder .get (i ).equals (SortOrder .DESC .toString ())) {
239+ mode .add ("max" );
209240 } else {
210- return MultiValueMode . MIN ;
241+ mode . add ( "min" ) ;
211242 }
212- }).map (order -> order .toString ().toLowerCase (Locale .ROOT )).toList ();
243+ }
244+ return mode ;
213245 }
214246
215247 public static List <String > getDefaultSortMissing (Settings settings ) {
216- // _last is the default per IndexFieldData.XFieldComparatorSource.Nested#sortMissingLast
217- return Arrays .stream (getSortSpecs (settings ))
218- .map (sortSpec -> sortSpec .missingValue != null ? sortSpec .missingValue : "_last" )
219- .toList ();
248+ if (settings .hasValue (INDEX_SORT_FIELD_SETTING .getKey ()) == false ) {
249+ return getSortDefault (settings ).missing ();
250+ }
251+
252+ List <String > sortFields = settings .getAsList (INDEX_SORT_FIELD_SETTING .getKey ());
253+ List <String > missing = new ArrayList <>(sortFields .size ());
254+ for (int i = 0 ; i < sortFields .size (); ++i ) {
255+ // _last is the default per IndexFieldData.XFieldComparatorSource.Nested#sortMissingLast
256+ missing .add ("_last" );
257+ }
258+ return missing ;
220259 }
221260 }
222261
0 commit comments