@@ -1123,199 +1123,6 @@ def __init__(
1123
1123
self .has_next = self .page < self .pages
1124
1124
1125
1125
1126
- class GroupedPageFilter (PageFilter ):
1127
- DEFAULT_MAX_ITEMS = 1000
1128
-
1129
- def __init__ (
1130
- self , name , group_by , group_kwargs = None , alias = None ,
1131
- per_page_param = None , per_page_values = None , max_items = None ,
1132
- ):
1133
- super (GroupedPageFilter , self ).__init__ (
1134
- name , alias = alias ,
1135
- per_page_param = per_page_param ,
1136
- per_page_values = per_page_values ,
1137
- max_items = max_items ,
1138
- )
1139
- self .group_by = group_by
1140
- self .group_kwargs = group_kwargs or {}
1141
-
1142
- @property
1143
- def _agg_name (self ):
1144
- return '{}.{}' .format (self .qf ._name , self .name )
1145
-
1146
- @property
1147
- def _filter_agg_name (self ):
1148
- return '{}.filter' .format (self ._agg_name )
1149
-
1150
- @property
1151
- def _pagination_agg_name (self ):
1152
- return '{}.pagination' .format (self ._agg_name )
1153
-
1154
- _top_hits_agg_name = 'top_items'
1155
-
1156
- def _order_agg_name (self , ix ):
1157
- return 'order_{}' .format (ix )
1158
-
1159
- def _apply_filter (self , search_query , params ):
1160
- self .per_page = self ._get_per_page (params )
1161
- self .page = self ._get_page (params )
1162
-
1163
- return search_query
1164
-
1165
- def _extract_orders (self , search_query ):
1166
- order_aggs = {}
1167
- order_by = []
1168
- if search_query ._order_by :
1169
- for i , o in enumerate (search_query ._order_by ):
1170
- order_name = self ._order_agg_name (i )
1171
- if isinstance (o , Sort ):
1172
- expr = o .expr
1173
- order = o .order
1174
- else :
1175
- expr = o
1176
- order = None
1177
-
1178
- if isinstance (expr , Field ):
1179
- field_name = expr .get_name ()
1180
- elif isinstance (expr , AttributedField ):
1181
- field_name = expr .get_field_name ()
1182
- else :
1183
- field_name = expr
1184
-
1185
- if field_name == '_score' :
1186
- # default ordering for _score is desc
1187
- desc = order is None or order == 'desc'
1188
- else :
1189
- desc = order == 'desc'
1190
-
1191
- if desc :
1192
- if field_name == '_score' :
1193
- order_aggs [order_name ] = agg .Max (script = '_score' )
1194
- else :
1195
- order_aggs [order_name ] = agg .Max (expr )
1196
- order_by .append ({order_name : 'desc' })
1197
- else :
1198
- if field_name == '_score' :
1199
- order_aggs [order_name ] = agg .Min (script = '_score' )
1200
- else :
1201
- order_aggs [order_name ] = agg .Min (expr )
1202
- order_by .append ({order_name : 'asc' })
1203
- else :
1204
- order_aggs = {
1205
- self ._order_agg_name (0 ): agg .Max (script = '_score' )
1206
- }
1207
- order_by = [{self ._order_agg_name (0 ): 'desc' }]
1208
-
1209
- return order_aggs , order_by
1210
-
1211
- def _apply_agg (self , search_query ):
1212
- order_aggs , order_by = self ._extract_orders (search_query )
1213
-
1214
- group_agg = agg .Terms (
1215
- self .group_by ,
1216
- size = self .per_page ,
1217
- order = order_by ,
1218
- aggs = dict (
1219
- {self ._top_hits_agg_name : agg .TopHits (** self .group_kwargs )},
1220
- ** order_aggs
1221
- )
1222
- )
1223
-
1224
- pagination_agg = agg .Terms (
1225
- self .group_by ,
1226
- size = self .max_items ,
1227
- order = order_by ,
1228
- aggs = order_aggs ,
1229
- )
1230
-
1231
- post_filters = list (search_query .get_context ().iter_post_filters ())
1232
-
1233
- if self .page == 1 :
1234
- page_aggs = {
1235
- self ._agg_name : group_agg ,
1236
- self ._pagination_agg_name : pagination_agg ,
1237
- }
1238
- else :
1239
- group_values = self ._get_group_values (search_query , post_filters , pagination_agg )
1240
- post_filters .append (self .group_by .in_ (group_values ))
1241
- page_aggs = {
1242
- self ._agg_name : group_agg ,
1243
- }
1244
-
1245
- if post_filters :
1246
- aggs = {
1247
- self ._filter_agg_name : agg .Filter (
1248
- Bool .must (* post_filters ),
1249
- aggs = page_aggs
1250
- )
1251
- }
1252
- else :
1253
- aggs = page_aggs
1254
-
1255
- search_query = search_query .aggs (aggs )
1256
-
1257
- return search_query
1258
-
1259
- def _get_group_values (self , search_query , post_filters , pagination_agg ):
1260
- if post_filters :
1261
- aggs = {
1262
- self ._filter_agg_name : agg .Filter (
1263
- Bool .must (* post_filters ),
1264
- aggs = {self ._pagination_agg_name : pagination_agg }
1265
- )
1266
- }
1267
- else :
1268
- aggs = {self ._pagination_agg_name : pagination_agg }
1269
-
1270
- sq = (
1271
- search_query
1272
- .with_search_type ('count' )
1273
- .aggs (None )
1274
- .aggs (** aggs )
1275
- )
1276
-
1277
- pagination_agg_res = self ._get_pagination_agg_result (sq .result )
1278
- self ._process_pagination_agg (pagination_agg_res )
1279
- values = [
1280
- group_bucket .key for group_bucket in pagination_agg_res .buckets
1281
- ]
1282
-
1283
- offset = self ._get_offset ()
1284
- return values [offset :offset + self .per_page ]
1285
-
1286
- def _get_offset (self ):
1287
- return (self .page - 1 ) * self .per_page
1288
-
1289
- def _get_pagination_agg_result (self , result ):
1290
- filter_agg = result .get_aggregation (self ._filter_agg_name )
1291
- if filter_agg :
1292
- return filter_agg .get_aggregation (self ._pagination_agg_name )
1293
- return result .get_aggregation (self ._pagination_agg_name )
1294
-
1295
- def _get_groups_agg_result (self , result ):
1296
- filter_agg = result .get_aggregation (self ._filter_agg_name )
1297
- if filter_agg :
1298
- return filter_agg .get_aggregation (self ._agg_name )
1299
- return result .get_aggregation (self ._agg_name )
1300
-
1301
- def _process_result (self , result , params ):
1302
- pagination_agg = self ._get_pagination_agg_result (result )
1303
- if pagination_agg :
1304
- total = len (pagination_agg .buckets )
1305
- else :
1306
- total = 0
1307
-
1308
- groups_agg = self ._get_groups_agg_result (result )
1309
- items = groups_agg .buckets
1310
- return PageFilterResult (
1311
- total = total , hits = items , page = self .page ,
1312
- per_page_param = self .per_page_param ,
1313
- per_page = self .per_page ,
1314
- per_page_values = self .per_page_values ,
1315
- max_items = self .max_items ,
1316
- )
1317
-
1318
-
1319
1126
class NestedFacetFilter (BaseFilter ):
1320
1127
1321
1128
def __init__ (
0 commit comments