searchkick 5.5.2 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,7 @@ module Searchkick
5
5
  # note: modifying body directly is not supported
6
6
  # and has no impact on query after being executed
7
7
  # TODO freeze body object?
8
- delegate :body, :params, to: :query
8
+ delegate :params, to: :query
9
9
  delegate_missing_to :private_execute
10
10
 
11
11
  attr_reader :model
@@ -27,26 +27,313 @@ module Searchkick
27
27
  "#<#{self.class.name} [#{entries.join(', ')}]>"
28
28
  end
29
29
 
30
- def execute
31
- Searchkick.warn("The execute method is no longer needed")
32
- load
30
+ def aggs(value = NO_DEFAULT_VALUE)
31
+ if value == NO_DEFAULT_VALUE
32
+ private_execute.aggs
33
+ else
34
+ clone.aggs!(value)
35
+ end
36
+ end
37
+
38
+ def aggs!(value)
39
+ check_loaded
40
+ (@options[:aggs] ||= {}).merge!(value)
41
+ self
42
+ end
43
+
44
+ def body(value = NO_DEFAULT_VALUE)
45
+ if value == NO_DEFAULT_VALUE
46
+ query.body
47
+ else
48
+ clone.body!(value)
49
+ end
50
+ end
51
+
52
+ def body!(value)
53
+ check_loaded
54
+ @options[:body] = value
55
+ self
56
+ end
57
+
58
+ def body_options(value)
59
+ clone.body_options!(value)
60
+ end
61
+
62
+ def body_options!(value)
63
+ check_loaded
64
+ (@options[:body_options] ||= {}).merge!(value)
65
+ self
66
+ end
67
+
68
+ def boost(value)
69
+ clone.boost!(value)
70
+ end
71
+
72
+ def boost!(value)
73
+ check_loaded
74
+ @options[:boost] = value
75
+ self
76
+ end
77
+
78
+ def boost_by(value)
79
+ clone.boost_by!(value)
80
+ end
81
+
82
+ def boost_by!(value)
83
+ check_loaded
84
+ if value.is_a?(Array)
85
+ value = value.to_h { |f| [f, {factor: 1}] }
86
+ elsif !value.is_a?(Hash)
87
+ value = {value => {factor: 1}}
88
+ end
89
+ (@options[:boost_by] ||= {}).merge!(value)
90
+ self
91
+ end
92
+
93
+ def boost_by_distance(value)
94
+ clone.boost_by_distance!(value)
95
+ end
96
+
97
+ def boost_by_distance!(value)
98
+ check_loaded
99
+ # legacy format
100
+ value = {value[:field] => value.except(:field)} if value[:field]
101
+ (@options[:boost_by_distance] ||= {}).merge!(value)
102
+ self
103
+ end
104
+
105
+ def boost_by_recency(value)
106
+ clone.boost_by_recency!(value)
107
+ end
108
+
109
+ def boost_by_recency!(value)
110
+ check_loaded
111
+ (@options[:boost_by_recency] ||= {}).merge!(value)
112
+ self
113
+ end
114
+
115
+ def boost_where(value)
116
+ clone.boost_where!(value)
117
+ end
118
+
119
+ def boost_where!(value)
120
+ check_loaded
121
+ # TODO merge duplicate fields
122
+ (@options[:boost_where] ||= {}).merge!(value)
123
+ self
124
+ end
125
+
126
+ def conversions(value)
127
+ clone.conversions!(value)
128
+ end
129
+
130
+ def conversions!(value)
131
+ check_loaded
132
+ @options[:conversions] = value
133
+ self
134
+ end
135
+
136
+ def conversions_v1(value)
137
+ clone.conversions_v1!(value)
138
+ end
139
+
140
+ def conversions_v1!(value)
141
+ check_loaded
142
+ @options[:conversions_v1] = value
143
+ self
144
+ end
145
+
146
+ def conversions_v2(value)
147
+ clone.conversions_v2!(value)
148
+ end
149
+
150
+ def conversions_v2!(value)
151
+ check_loaded
152
+ @options[:conversions_v2] = value
153
+ self
154
+ end
155
+
156
+ def conversions_term(value)
157
+ clone.conversions_term!(value)
158
+ end
159
+
160
+ def conversions_term!(value)
161
+ check_loaded
162
+ @options[:conversions_term] = value
163
+ self
164
+ end
165
+
166
+ def debug(value = true)
167
+ clone.debug!(value)
168
+ end
169
+
170
+ def debug!(value = true)
171
+ check_loaded
172
+ @options[:debug] = value
173
+ self
174
+ end
175
+
176
+ def emoji(value = true)
177
+ clone.emoji!(value)
178
+ end
179
+
180
+ def emoji!(value = true)
181
+ check_loaded
182
+ @options[:emoji] = value
183
+ self
184
+ end
185
+
186
+ def exclude(*values)
187
+ clone.exclude!(*values)
188
+ end
189
+
190
+ def exclude!(*values)
191
+ check_loaded
192
+ (@options[:exclude] ||= []).concat(values.flatten)
193
+ self
194
+ end
195
+
196
+ def explain(value = true)
197
+ clone.explain!(value)
198
+ end
199
+
200
+ def explain!(value = true)
201
+ check_loaded
202
+ @options[:explain] = value
203
+ self
204
+ end
205
+
206
+ def fields(*values)
207
+ clone.fields!(*values)
208
+ end
209
+
210
+ def fields!(*values)
211
+ check_loaded
212
+ (@options[:fields] ||= []).concat(values.flatten)
213
+ self
214
+ end
215
+
216
+ def highlight(value)
217
+ clone.highlight!(value)
218
+ end
219
+
220
+ def highlight!(value)
221
+ check_loaded
222
+ @options[:highlight] = value
223
+ self
224
+ end
225
+
226
+ def includes(*values)
227
+ clone.includes!(*values)
228
+ end
229
+
230
+ def includes!(*values)
231
+ check_loaded
232
+ (@options[:includes] ||= []).concat(values.flatten)
233
+ self
234
+ end
235
+
236
+ def index_name(*values)
237
+ clone.index_name!(*values)
238
+ end
239
+
240
+ def index_name!(*values)
241
+ check_loaded
242
+ values = values.flatten
243
+ if values.all? { |v| v.respond_to?(:searchkick_index) }
244
+ models!(*values)
245
+ else
246
+ (@options[:index_name] ||= []).concat(values)
247
+ self
248
+ end
249
+ end
250
+
251
+ def indices_boost(value)
252
+ clone.indices_boost!(value)
253
+ end
254
+
255
+ def indices_boost!(value)
256
+ check_loaded
257
+ (@options[:indices_boost] ||= {}).merge!(value)
258
+ self
259
+ end
260
+
261
+ def knn(value)
262
+ clone.knn!(value)
263
+ end
264
+
265
+ def knn!(value)
266
+ check_loaded
267
+ @options[:knn] = value
268
+ self
33
269
  end
34
270
 
35
- # experimental
36
271
  def limit(value)
37
272
  clone.limit!(value)
38
273
  end
39
274
 
40
- # experimental
41
275
  def limit!(value)
42
276
  check_loaded
43
277
  @options[:limit] = value
44
278
  self
45
279
  end
46
280
 
47
- # experimental
281
+ def load(value = NO_DEFAULT_VALUE)
282
+ if value == NO_DEFAULT_VALUE
283
+ private_execute
284
+ self
285
+ else
286
+ clone.load!(value)
287
+ end
288
+ end
289
+
290
+ def load!(value)
291
+ check_loaded
292
+ @options[:load] = value
293
+ self
294
+ end
295
+
296
+ def match(value)
297
+ clone.match!(value)
298
+ end
299
+
300
+ def match!(value)
301
+ check_loaded
302
+ @options[:match] = value
303
+ self
304
+ end
305
+
306
+ def misspellings(value)
307
+ clone.misspellings!(value)
308
+ end
309
+
310
+ def misspellings!(value)
311
+ check_loaded
312
+ @options[:misspellings] = value
313
+ self
314
+ end
315
+
316
+ def models(*values)
317
+ clone.models!(*values)
318
+ end
319
+
320
+ def models!(*values)
321
+ check_loaded
322
+ (@options[:models] ||= []).concat(values.flatten)
323
+ self
324
+ end
325
+
326
+ def model_includes(*values)
327
+ clone.model_includes!(*values)
328
+ end
329
+
330
+ def model_includes!(*values)
331
+ check_loaded
332
+ (@options[:model_includes] ||= []).concat(values.flatten)
333
+ self
334
+ end
335
+
48
336
  def offset(value = NO_DEFAULT_VALUE)
49
- # TODO remove in Searchkick 6
50
337
  if value == NO_DEFAULT_VALUE
51
338
  private_execute.offset
52
339
  else
@@ -54,28 +341,67 @@ module Searchkick
54
341
  end
55
342
  end
56
343
 
57
- # experimental
58
344
  def offset!(value)
59
345
  check_loaded
60
346
  @options[:offset] = value
61
347
  self
62
348
  end
63
349
 
64
- # experimental
350
+ def opaque_id(value)
351
+ clone.opaque_id!(value)
352
+ end
353
+
354
+ def opaque_id!(value)
355
+ check_loaded
356
+ @options[:opaque_id] = value
357
+ self
358
+ end
359
+
360
+ def operator(value)
361
+ clone.operator!(value)
362
+ end
363
+
364
+ def operator!(value)
365
+ check_loaded
366
+ @options[:operator] = value
367
+ self
368
+ end
369
+
370
+ def order(*values)
371
+ clone.order!(*values)
372
+ end
373
+
374
+ def order!(*values)
375
+ check_loaded
376
+ (@options[:order] ||= []).concat(values.flatten)
377
+ self
378
+ end
379
+
380
+ def padding(value = NO_DEFAULT_VALUE)
381
+ if value == NO_DEFAULT_VALUE
382
+ private_execute.padding
383
+ else
384
+ clone.padding!(value)
385
+ end
386
+ end
387
+
388
+ def padding!(value)
389
+ check_loaded
390
+ @options[:padding] = value
391
+ self
392
+ end
393
+
65
394
  def page(value)
66
395
  clone.page!(value)
67
396
  end
68
397
 
69
- # experimental
70
398
  def page!(value)
71
399
  check_loaded
72
400
  @options[:page] = value
73
401
  self
74
402
  end
75
403
 
76
- # experimental
77
404
  def per_page(value = NO_DEFAULT_VALUE)
78
- # TODO remove in Searchkick 6
79
405
  if value == NO_DEFAULT_VALUE
80
406
  private_execute.per_page
81
407
  else
@@ -83,71 +409,69 @@ module Searchkick
83
409
  end
84
410
  end
85
411
 
86
- # experimental
87
412
  def per_page!(value)
88
413
  check_loaded
414
+ # TODO set limit?
89
415
  @options[:per_page] = value
90
416
  self
91
417
  end
92
418
 
93
- # experimental
94
- def where(value = NO_DEFAULT_VALUE)
95
- if value == NO_DEFAULT_VALUE
96
- Where.new(self)
97
- else
98
- clone.where!(value)
99
- end
419
+ def profile(value = true)
420
+ clone.profile!(value)
100
421
  end
101
422
 
102
- # experimental
103
- def where!(value)
423
+ def profile!(value = true)
104
424
  check_loaded
105
- if @options[:where]
106
- @options[:where] = {_and: [@options[:where], ensure_permitted(value)]}
107
- else
108
- @options[:where] = ensure_permitted(value)
109
- end
425
+ @options[:profile] = value
110
426
  self
111
427
  end
112
428
 
113
- # experimental
114
- def rewhere(value)
115
- clone.rewhere!(value)
429
+ def request_params(value)
430
+ clone.request_params!(value)
116
431
  end
117
432
 
118
- # experimental
119
- def rewhere!(value)
433
+ def request_params!(value)
120
434
  check_loaded
121
- @options[:where] = ensure_permitted(value)
435
+ (@options[:request_params] ||= {}).merge!(value)
122
436
  self
123
437
  end
124
438
 
125
- # experimental
126
- def order(*values)
127
- clone.order!(*values)
439
+ def routing(value)
440
+ clone.routing!(value)
128
441
  end
129
442
 
130
- # experimental
131
- def order!(*values)
132
- values = values.first if values.size == 1 && values.first.is_a?(Array)
443
+ def routing!(value)
133
444
  check_loaded
134
- (@options[:order] ||= []).concat(values)
445
+ @options[:routing] = value
135
446
  self
136
447
  end
137
448
 
138
- # experimental
139
- def reorder(*values)
140
- clone.reorder!(*values)
449
+ def scope_results(value)
450
+ clone.scope_results!(value)
141
451
  end
142
452
 
143
- # experimental
144
- def reorder!(*values)
453
+ def scope_results!(value)
145
454
  check_loaded
146
- @options[:order] = values
455
+ @options[:scope_results] = value
456
+ self
457
+ end
458
+
459
+ def scroll(value = NO_DEFAULT_VALUE, &block)
460
+ if value == NO_DEFAULT_VALUE
461
+ private_execute.scroll(&block)
462
+ elsif block_given?
463
+ clone.scroll!(value).scroll(&block)
464
+ else
465
+ clone.scroll!(value)
466
+ end
467
+ end
468
+
469
+ def scroll!(value)
470
+ check_loaded
471
+ @options[:scroll] = value
147
472
  self
148
473
  end
149
474
 
150
- # experimental
151
475
  def select(*values, &block)
152
476
  if block_given?
153
477
  private_execute.select(*values, &block)
@@ -156,65 +480,173 @@ module Searchkick
156
480
  end
157
481
  end
158
482
 
159
- # experimental
160
483
  def select!(*values)
161
484
  check_loaded
162
- (@options[:select] ||= []).concat(values)
485
+ (@options[:select] ||= []).concat(values.flatten)
486
+ self
487
+ end
488
+
489
+ def similar(value = true)
490
+ clone.similar!(value)
491
+ end
492
+
493
+ def similar!(value = true)
494
+ check_loaded
495
+ @options[:similar] = value
496
+ self
497
+ end
498
+
499
+ def smart_aggs(value)
500
+ clone.smart_aggs!(value)
501
+ end
502
+
503
+ def smart_aggs!(value)
504
+ check_loaded
505
+ @options[:smart_aggs] = value
506
+ self
507
+ end
508
+
509
+ def suggest(value = true)
510
+ clone.suggest!(value)
511
+ end
512
+
513
+ def suggest!(value = true)
514
+ check_loaded
515
+ @options[:suggest] = value
516
+ self
517
+ end
518
+
519
+ def total_entries(value = NO_DEFAULT_VALUE)
520
+ if value == NO_DEFAULT_VALUE
521
+ private_execute.total_entries
522
+ else
523
+ clone.total_entries!(value)
524
+ end
525
+ end
526
+
527
+ def total_entries!(value)
528
+ check_loaded
529
+ @options[:total_entries] = value
530
+ self
531
+ end
532
+
533
+ def track(value = true)
534
+ clone.track!(value)
535
+ end
536
+
537
+ def track!(value = true)
538
+ check_loaded
539
+ @options[:track] = value
540
+ self
541
+ end
542
+
543
+ def type(*values)
544
+ clone.type!(*values)
545
+ end
546
+
547
+ def type!(*values)
548
+ check_loaded
549
+ (@options[:type] ||= []).concat(values.flatten)
550
+ self
551
+ end
552
+
553
+ def where(value = NO_DEFAULT_VALUE)
554
+ if value == NO_DEFAULT_VALUE
555
+ Where.new(self)
556
+ else
557
+ clone.where!(value)
558
+ end
559
+ end
560
+
561
+ def where!(value)
562
+ check_loaded
563
+ if @options[:where]
564
+ @options[:where] = {_and: [@options[:where], ensure_permitted(value)]}
565
+ else
566
+ @options[:where] = ensure_permitted(value)
567
+ end
568
+ self
569
+ end
570
+
571
+ def first(value = NO_DEFAULT_VALUE)
572
+ result =
573
+ if loaded?
574
+ private_execute
575
+ else
576
+ limit = value == NO_DEFAULT_VALUE ? 1 : value
577
+ previous_limit = (@options[:limit] || @options[:per_page])&.to_i
578
+ if previous_limit && previous_limit < limit
579
+ limit = previous_limit
580
+ end
581
+ limit(limit).load
582
+ end
583
+
584
+ if value == NO_DEFAULT_VALUE
585
+ result.first
586
+ else
587
+ result.first(value)
588
+ end
589
+ end
590
+
591
+ def pluck(*keys)
592
+ if @options[:load] == false
593
+ select(*keys).send(:private_execute).pluck(*keys)
594
+ else
595
+ private_execute.pluck(*keys)
596
+ end
597
+ end
598
+
599
+ def reorder(*values)
600
+ clone.reorder!(*values)
601
+ end
602
+
603
+ def reorder!(*values)
604
+ check_loaded
605
+ @options[:order] = values
163
606
  self
164
607
  end
165
608
 
166
- # experimental
167
609
  def reselect(*values)
168
610
  clone.reselect!(*values)
169
611
  end
170
612
 
171
- # experimental
172
613
  def reselect!(*values)
173
614
  check_loaded
174
615
  @options[:select] = values
175
616
  self
176
617
  end
177
618
 
178
- # experimental
179
- def includes(*values)
180
- clone.includes!(*values)
619
+ def rewhere(value)
620
+ clone.rewhere!(value)
181
621
  end
182
622
 
183
- # experimental
184
- def includes!(*values)
623
+ def rewhere!(value)
185
624
  check_loaded
186
- (@options[:includes] ||= []).concat(values)
625
+ @options[:where] = ensure_permitted(value)
187
626
  self
188
627
  end
189
628
 
190
- # experimental
191
629
  def only(*keys)
192
630
  Relation.new(@model, @term, **@options.slice(*keys))
193
631
  end
194
632
 
195
- # experimental
196
633
  def except(*keys)
197
634
  Relation.new(@model, @term, **@options.except(*keys))
198
635
  end
199
636
 
200
- # experimental
201
- def load
202
- private_execute
203
- self
204
- end
205
-
206
637
  def loaded?
207
638
  !@execute.nil?
208
639
  end
209
640
 
210
- def respond_to_missing?(method_name, include_all)
211
- Results.new(nil, nil, nil).respond_to?(method_name, include_all) || super
641
+ undef_method :respond_to_missing?
642
+
643
+ def respond_to_missing?(...)
644
+ Results.new(nil, nil, nil).respond_to?(...) || super
212
645
  end
213
646
 
214
- # TODO uncomment in 6.0
215
- # def to_yaml
216
- # private_execute.to_a.to_yaml
217
- # end
647
+ def to_yaml
648
+ private_execute.to_a.to_yaml
649
+ end
218
650
 
219
651
  private
220
652