47
47
import co .elastic .clients .elasticsearch .core .bulk .IndexOperation ;
48
48
import co .elastic .clients .elasticsearch .core .bulk .UpdateOperation ;
49
49
import co .elastic .clients .elasticsearch .core .mget .MultiGetOperation ;
50
+ import co .elastic .clients .elasticsearch .core .msearch .MultisearchBody ;
50
51
import co .elastic .clients .elasticsearch .core .search .Highlight ;
51
52
import co .elastic .clients .elasticsearch .core .search .Rescore ;
52
53
import co .elastic .clients .elasticsearch .core .search .SourceConfig ;
@@ -1047,26 +1048,120 @@ public <T> SearchRequest searchRequest(Query query, @Nullable Class<T> clazz, In
1047
1048
public MsearchRequest searchMsearchRequest (
1048
1049
List <ElasticsearchTemplate .MultiSearchQueryParameter > multiSearchQueryParameters ) {
1049
1050
1051
+ // basically the same stuff as in prepareSearchRequest, but the new Elasticsearch has different builders for a
1052
+ // normal search and msearch
1050
1053
return MsearchRequest .of (mrb -> {
1051
1054
multiSearchQueryParameters .forEach (param -> {
1052
1055
ElasticsearchPersistentEntity <?> persistentEntity = getPersistentEntity (param .clazz );
1053
1056
1057
+ var query = param .query ;
1054
1058
mrb .searches (sb -> sb //
1055
- .header (h -> h //
1056
- .index (Arrays .asList (param .index .getIndexNames ())) //
1057
- // todo #2156 add remaining flags for header
1058
- ) //
1059
- .body (bb -> bb //
1060
- .query (getQuery (param .query , param .clazz ))//
1061
- .seqNoPrimaryTerm (persistentEntity .hasSeqNoPrimaryTermProperty ()).version (true )
1062
- // todo #2156 add remaining flags for body
1059
+ .header (h -> {
1060
+ h //
1061
+ .index (Arrays .asList (param .index .getIndexNames ())) //
1062
+ .routing (query .getRoute ()) //
1063
+ .searchType (searchType (query .getSearchType ())) //
1064
+ .requestCache (query .getRequestCache ()) //
1065
+ ;
1066
+
1067
+ if (query .getPreference () != null ) {
1068
+ h .preference (query .getPreference ());
1069
+ }
1070
+
1071
+ return h ;
1072
+ }) //
1073
+ .body (bb -> {
1074
+ bb //
1075
+ .query (getQuery (query , param .clazz ))//
1076
+ .seqNoPrimaryTerm (persistentEntity != null ? persistentEntity .hasSeqNoPrimaryTermProperty () : null ) //
1077
+ .version (true ) //
1078
+ .trackScores (query .getTrackScores ()) //
1079
+ .source (getSourceConfig (query )) //
1080
+ .timeout (timeStringMs (query .getTimeout ())) //
1081
+ ;
1082
+
1083
+ if (query .getPageable ().isPaged ()) {
1084
+ bb //
1085
+ .from ((int ) query .getPageable ().getOffset ()) //
1086
+ .size (query .getPageable ().getPageSize ());
1087
+ }
1088
+
1089
+ if (!isEmpty (query .getFields ())) {
1090
+ bb .fields (fb -> {
1091
+ query .getFields ().forEach (fb ::field );
1092
+ return fb ;
1093
+ });
1094
+ }
1095
+
1096
+ if (!isEmpty (query .getStoredFields ())) {
1097
+ bb .storedFields (query .getStoredFields ());
1098
+ }
1099
+
1100
+ if (query .isLimiting ()) {
1101
+ bb .size (query .getMaxResults ());
1102
+ }
1103
+
1104
+ if (query .getMinScore () > 0 ) {
1105
+ bb .minScore ((double ) query .getMinScore ());
1106
+ }
1107
+
1108
+ if (query .getSort () != null ) {
1109
+ List <SortOptions > sortOptions = getSortOptions (query .getSort (), persistentEntity );
1110
+
1111
+ if (!sortOptions .isEmpty ()) {
1112
+ bb .sort (sortOptions );
1113
+ }
1114
+ }
1115
+
1116
+ addHighlight (query , bb );
1117
+
1118
+ if (query .getExplain ()) {
1119
+ bb .explain (true );
1120
+ }
1121
+
1122
+ if (!isEmpty (query .getSearchAfter ())) {
1123
+ bb .searchAfter (query .getSearchAfter ().stream ().map (Object ::toString ).collect (Collectors .toList ()));
1124
+ }
1125
+
1126
+ query .getRescorerQueries ().forEach (rescorerQuery -> {
1127
+ bb .rescore (getRescore (rescorerQuery ));
1128
+ });
1129
+
1130
+ if (!query .getRuntimeFields ().isEmpty ()) {
1131
+
1132
+ Map <String , List <RuntimeField >> runtimeMappings = new HashMap <>();
1133
+ query .getRuntimeFields ().forEach (runtimeField -> {
1134
+ runtimeMappings .put (runtimeField .getName (), Collections .singletonList (RuntimeField .of (rt -> rt //
1135
+ .type (RuntimeFieldType ._DESERIALIZER .parse (runtimeField .getType ())) //
1136
+ .script (s -> s .inline (is -> is .source (runtimeField .getScript ()))))));
1137
+ });
1138
+ bb .runtimeMappings (runtimeMappings );
1139
+ }
1140
+
1141
+ if (!isEmpty (query .getIndicesBoost ())) {
1142
+ Map <String , Double > boosts = new LinkedHashMap <>();
1143
+ query .getIndicesBoost ().forEach (indexBoost -> {
1144
+ boosts .put (indexBoost .getIndexName (), (double ) indexBoost .getBoost ());
1145
+ });
1146
+ // noinspection unchecked
1147
+ bb .indicesBoost (boosts );
1148
+ }
1149
+
1150
+ if (query instanceof NativeQuery ) {
1151
+ prepareNativeSearch ((NativeQuery ) query , bb );
1152
+ }
1153
+ return bb ;
1154
+ } //
1063
1155
) //
1064
1156
);
1157
+
1065
1158
});
1159
+
1066
1160
return mrb ;
1067
1161
});
1068
1162
}
1069
1163
1164
+
1070
1165
private <T > void prepareSearchRequest (Query query , @ Nullable Class <T > clazz , IndexCoordinates indexCoordinates ,
1071
1166
SearchRequest .Builder builder , boolean forCount , boolean useScroll ) {
1072
1167
@@ -1225,6 +1320,16 @@ private void addHighlight(Query query, SearchRequest.Builder builder) {
1225
1320
builder .highlight (highlight );
1226
1321
}
1227
1322
1323
+ private void addHighlight (Query query , MultisearchBody .Builder builder ) {
1324
+
1325
+ Highlight highlight = query .getHighlightQuery ()
1326
+ .map (highlightQuery -> new HighlightQueryBuilder (elasticsearchConverter .getMappingContext ())
1327
+ .getHighlight (highlightQuery .getHighlight (), highlightQuery .getType ()))
1328
+ .orElse (null );
1329
+
1330
+ builder .highlight (highlight );
1331
+ }
1332
+
1228
1333
private List <SortOptions > getSortOptions (Sort sort , @ Nullable ElasticsearchPersistentEntity <?> persistentEntity ) {
1229
1334
return sort .stream ().map (order -> getSortOptions (order , persistentEntity )).collect (Collectors .toList ());
1230
1335
}
@@ -1289,6 +1394,7 @@ private SortOptions getSortOptions(Sort.Order order, @Nullable ElasticsearchPers
1289
1394
}
1290
1395
}
1291
1396
1397
+ @ SuppressWarnings ("DuplicatedCode" )
1292
1398
private void prepareNativeSearch (NativeQuery query , SearchRequest .Builder builder ) {
1293
1399
1294
1400
query .getScriptedFields ().forEach (scriptedField -> {
@@ -1307,6 +1413,25 @@ private void prepareNativeSearch(NativeQuery query, SearchRequest.Builder builde
1307
1413
// todo #2150 searchExt, currently not supported by the new client
1308
1414
}
1309
1415
1416
+ @ SuppressWarnings ("DuplicatedCode" )
1417
+ private void prepareNativeSearch (NativeQuery query , MultisearchBody .Builder builder ) {
1418
+
1419
+ query .getScriptedFields ().forEach (scriptedField -> {
1420
+ builder .scriptFields (scriptedField .getFieldName (), sf -> sf .script (getScript (scriptedField .getScriptData ())));
1421
+ });
1422
+
1423
+ builder //
1424
+ .suggest (query .getSuggester ()) //
1425
+ .collapse (query .getFieldCollapse ()) //
1426
+ ;
1427
+
1428
+ if (!isEmpty (query .getAggregations ())) {
1429
+ builder .aggregations (query .getAggregations ());
1430
+ }
1431
+
1432
+ // todo #2150 searchExt, currently not supported by the new client
1433
+ }
1434
+
1310
1435
@ Nullable
1311
1436
private co .elastic .clients .elasticsearch ._types .query_dsl .Query getQuery (@ Nullable Query query ,
1312
1437
@ Nullable Class <?> clazz ) {
0 commit comments