tiny-quick-gem 0.0.1

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.
Files changed (34) hide show
  1. checksums.yaml +7 -0
  2. data/searchkick-6.1.2/CHANGELOG.md +919 -0
  3. data/searchkick-6.1.2/LICENSE.txt +22 -0
  4. data/searchkick-6.1.2/README.md +2348 -0
  5. data/searchkick-6.1.2/lib/searchkick/bulk_reindex_job.rb +19 -0
  6. data/searchkick-6.1.2/lib/searchkick/controller_runtime.rb +40 -0
  7. data/searchkick-6.1.2/lib/searchkick/hash_wrapper.rb +41 -0
  8. data/searchkick-6.1.2/lib/searchkick/index.rb +480 -0
  9. data/searchkick-6.1.2/lib/searchkick/index_cache.rb +30 -0
  10. data/searchkick-6.1.2/lib/searchkick/index_options.rb +652 -0
  11. data/searchkick-6.1.2/lib/searchkick/indexer.rb +43 -0
  12. data/searchkick-6.1.2/lib/searchkick/log_subscriber.rb +57 -0
  13. data/searchkick-6.1.2/lib/searchkick/middleware.rb +19 -0
  14. data/searchkick-6.1.2/lib/searchkick/model.rb +120 -0
  15. data/searchkick-6.1.2/lib/searchkick/multi_search.rb +46 -0
  16. data/searchkick-6.1.2/lib/searchkick/process_batch_job.rb +20 -0
  17. data/searchkick-6.1.2/lib/searchkick/process_queue_job.rb +33 -0
  18. data/searchkick-6.1.2/lib/searchkick/query.rb +1372 -0
  19. data/searchkick-6.1.2/lib/searchkick/railtie.rb +7 -0
  20. data/searchkick-6.1.2/lib/searchkick/record_data.rb +147 -0
  21. data/searchkick-6.1.2/lib/searchkick/record_indexer.rb +174 -0
  22. data/searchkick-6.1.2/lib/searchkick/reindex_queue.rb +57 -0
  23. data/searchkick-6.1.2/lib/searchkick/reindex_v2_job.rb +17 -0
  24. data/searchkick-6.1.2/lib/searchkick/relation.rb +728 -0
  25. data/searchkick-6.1.2/lib/searchkick/relation_indexer.rb +184 -0
  26. data/searchkick-6.1.2/lib/searchkick/reranking.rb +28 -0
  27. data/searchkick-6.1.2/lib/searchkick/results.rb +359 -0
  28. data/searchkick-6.1.2/lib/searchkick/script.rb +11 -0
  29. data/searchkick-6.1.2/lib/searchkick/version.rb +3 -0
  30. data/searchkick-6.1.2/lib/searchkick/where.rb +11 -0
  31. data/searchkick-6.1.2/lib/searchkick.rb +388 -0
  32. data/searchkick-6.1.2/lib/tasks/searchkick.rake +37 -0
  33. data/tiny-quick-gem.gemspec +12 -0
  34. metadata +73 -0
@@ -0,0 +1,728 @@
1
+ module Searchkick
2
+ class Relation
3
+ NO_DEFAULT_VALUE = Object.new
4
+
5
+ # note: modifying body directly is not supported
6
+ # and has no impact on query after being executed
7
+ # TODO freeze body object?
8
+ delegate :params, to: :query
9
+ delegate_missing_to :private_execute
10
+
11
+ attr_reader :model
12
+ alias_method :klass, :model
13
+
14
+ def initialize(model, term = "*", **options)
15
+ @model = model
16
+ @term = term
17
+ @options = options
18
+
19
+ # generate query to validate options
20
+ query if options.any?
21
+ end
22
+
23
+ # same as Active Record
24
+ def inspect
25
+ entries = private_execute.first(11).map!(&:inspect)
26
+ entries[10] = "..." if entries.size == 11
27
+ "#<#{self.class.name} [#{entries.join(', ')}]>"
28
+ end
29
+
30
+ def aggs(*args, **kwargs)
31
+ if args.empty? && kwargs.empty?
32
+ private_execute.aggs
33
+ else
34
+ clone.aggs!(*args, **kwargs)
35
+ end
36
+ end
37
+
38
+ def aggs!(*args, **kwargs)
39
+ check_loaded
40
+ aggs = {}
41
+ args.flatten.each do |arg|
42
+ if arg.is_a?(Hash)
43
+ aggs.merge!(arg)
44
+ else
45
+ aggs[arg] = {}
46
+ end
47
+ end
48
+ aggs.merge!(kwargs)
49
+ merge_option(:aggs, aggs)
50
+ self
51
+ end
52
+
53
+ def body(value = NO_DEFAULT_VALUE)
54
+ if value == NO_DEFAULT_VALUE
55
+ query.body
56
+ else
57
+ clone.body!(value)
58
+ end
59
+ end
60
+
61
+ def body!(value)
62
+ check_loaded
63
+ @options[:body] = value
64
+ self
65
+ end
66
+
67
+ def body_options(value)
68
+ clone.body_options!(value)
69
+ end
70
+
71
+ def body_options!(value)
72
+ check_loaded
73
+ merge_option(:body_options, value)
74
+ self
75
+ end
76
+
77
+ def boost(value)
78
+ clone.boost!(value)
79
+ end
80
+
81
+ def boost!(value)
82
+ check_loaded
83
+ @options[:boost] = value
84
+ self
85
+ end
86
+
87
+ def boost_by(value)
88
+ clone.boost_by!(value)
89
+ end
90
+
91
+ def boost_by!(value)
92
+ check_loaded
93
+ if value.is_a?(Array)
94
+ value = value.to_h { |f| [f, {factor: 1}] }
95
+ elsif !value.is_a?(Hash)
96
+ value = {value => {factor: 1}}
97
+ end
98
+ merge_option(:boost_by, value)
99
+ self
100
+ end
101
+
102
+ def boost_by_distance(value)
103
+ clone.boost_by_distance!(value)
104
+ end
105
+
106
+ def boost_by_distance!(value)
107
+ check_loaded
108
+ # legacy format
109
+ value = {value[:field] => value.except(:field)} if value[:field]
110
+ merge_option(:boost_by_distance, value)
111
+ self
112
+ end
113
+
114
+ def boost_by_recency(value)
115
+ clone.boost_by_recency!(value)
116
+ end
117
+
118
+ def boost_by_recency!(value)
119
+ check_loaded
120
+ merge_option(:boost_by_recency, value)
121
+ self
122
+ end
123
+
124
+ def boost_where(value)
125
+ clone.boost_where!(value)
126
+ end
127
+
128
+ def boost_where!(value)
129
+ check_loaded
130
+ # TODO merge duplicate fields
131
+ merge_option(:boost_where, value)
132
+ self
133
+ end
134
+
135
+ def conversions(value)
136
+ clone.conversions!(value)
137
+ end
138
+
139
+ def conversions!(value)
140
+ check_loaded
141
+ @options[:conversions] = value
142
+ self
143
+ end
144
+
145
+ def conversions_v1(value)
146
+ clone.conversions_v1!(value)
147
+ end
148
+
149
+ def conversions_v1!(value)
150
+ check_loaded
151
+ @options[:conversions_v1] = value
152
+ self
153
+ end
154
+
155
+ def conversions_v2(value)
156
+ clone.conversions_v2!(value)
157
+ end
158
+
159
+ def conversions_v2!(value)
160
+ check_loaded
161
+ @options[:conversions_v2] = value
162
+ self
163
+ end
164
+
165
+ def conversions_term(value)
166
+ clone.conversions_term!(value)
167
+ end
168
+
169
+ def conversions_term!(value)
170
+ check_loaded
171
+ @options[:conversions_term] = value
172
+ self
173
+ end
174
+
175
+ def debug(value = true)
176
+ clone.debug!(value)
177
+ end
178
+
179
+ def debug!(value = true)
180
+ check_loaded
181
+ @options[:debug] = value
182
+ self
183
+ end
184
+
185
+ def emoji(value = true)
186
+ clone.emoji!(value)
187
+ end
188
+
189
+ def emoji!(value = true)
190
+ check_loaded
191
+ @options[:emoji] = value
192
+ self
193
+ end
194
+
195
+ def exclude(*values)
196
+ clone.exclude!(*values)
197
+ end
198
+
199
+ def exclude!(*values)
200
+ check_loaded
201
+ concat_option(:exclude, values.flatten)
202
+ self
203
+ end
204
+
205
+ def explain(value = true)
206
+ clone.explain!(value)
207
+ end
208
+
209
+ def explain!(value = true)
210
+ check_loaded
211
+ @options[:explain] = value
212
+ self
213
+ end
214
+
215
+ def fields(*values)
216
+ clone.fields!(*values)
217
+ end
218
+
219
+ def fields!(*values)
220
+ check_loaded
221
+ concat_option(:fields, values.flatten)
222
+ self
223
+ end
224
+
225
+ def highlight(value)
226
+ clone.highlight!(value)
227
+ end
228
+
229
+ def highlight!(value)
230
+ check_loaded
231
+ @options[:highlight] = value
232
+ self
233
+ end
234
+
235
+ def includes(*values)
236
+ clone.includes!(*values)
237
+ end
238
+
239
+ def includes!(*values)
240
+ check_loaded
241
+ concat_option(:includes, values.flatten)
242
+ self
243
+ end
244
+
245
+ def index_name(*values)
246
+ clone.index_name!(*values)
247
+ end
248
+
249
+ def index_name!(*values)
250
+ check_loaded
251
+ values = values.flatten
252
+ if values.all? { |v| v.respond_to?(:searchkick_index) }
253
+ models!(*values)
254
+ else
255
+ concat_option(:index_name, values)
256
+ self
257
+ end
258
+ end
259
+
260
+ def indices_boost(value)
261
+ clone.indices_boost!(value)
262
+ end
263
+
264
+ def indices_boost!(value)
265
+ check_loaded
266
+ merge_option(:indices_boost, value)
267
+ self
268
+ end
269
+
270
+ def knn(value)
271
+ clone.knn!(value)
272
+ end
273
+
274
+ def knn!(value)
275
+ check_loaded
276
+ @options[:knn] = value
277
+ self
278
+ end
279
+
280
+ def limit(value)
281
+ clone.limit!(value)
282
+ end
283
+
284
+ def limit!(value)
285
+ check_loaded
286
+ @options[:limit] = value
287
+ self
288
+ end
289
+
290
+ def load(value = NO_DEFAULT_VALUE)
291
+ if value == NO_DEFAULT_VALUE
292
+ private_execute
293
+ self
294
+ else
295
+ clone.load!(value)
296
+ end
297
+ end
298
+
299
+ def load!(value)
300
+ check_loaded
301
+ @options[:load] = value
302
+ self
303
+ end
304
+
305
+ def match(value)
306
+ clone.match!(value)
307
+ end
308
+
309
+ def match!(value)
310
+ check_loaded
311
+ @options[:match] = value
312
+ self
313
+ end
314
+
315
+ def misspellings(value)
316
+ clone.misspellings!(value)
317
+ end
318
+
319
+ def misspellings!(value)
320
+ check_loaded
321
+ @options[:misspellings] = value
322
+ self
323
+ end
324
+
325
+ def models(*values)
326
+ clone.models!(*values)
327
+ end
328
+
329
+ def models!(*values)
330
+ check_loaded
331
+ concat_option(:models, values.flatten)
332
+ self
333
+ end
334
+
335
+ def model_includes(*values)
336
+ clone.model_includes!(*values)
337
+ end
338
+
339
+ def model_includes!(*values)
340
+ check_loaded
341
+ concat_option(:model_includes, values.flatten)
342
+ self
343
+ end
344
+
345
+ def offset(value = NO_DEFAULT_VALUE)
346
+ if value == NO_DEFAULT_VALUE
347
+ private_execute.offset
348
+ else
349
+ clone.offset!(value)
350
+ end
351
+ end
352
+
353
+ def offset!(value)
354
+ check_loaded
355
+ @options[:offset] = value
356
+ self
357
+ end
358
+
359
+ def opaque_id(value)
360
+ clone.opaque_id!(value)
361
+ end
362
+
363
+ def opaque_id!(value)
364
+ check_loaded
365
+ @options[:opaque_id] = value
366
+ self
367
+ end
368
+
369
+ def operator(value)
370
+ clone.operator!(value)
371
+ end
372
+
373
+ def operator!(value)
374
+ check_loaded
375
+ @options[:operator] = value
376
+ self
377
+ end
378
+
379
+ def order(*values)
380
+ clone.order!(*values)
381
+ end
382
+
383
+ def order!(*values)
384
+ check_loaded
385
+ concat_option(:order, values.flatten)
386
+ self
387
+ end
388
+
389
+ def padding(value = NO_DEFAULT_VALUE)
390
+ if value == NO_DEFAULT_VALUE
391
+ private_execute.padding
392
+ else
393
+ clone.padding!(value)
394
+ end
395
+ end
396
+
397
+ def padding!(value)
398
+ check_loaded
399
+ @options[:padding] = value
400
+ self
401
+ end
402
+
403
+ def page(value)
404
+ clone.page!(value)
405
+ end
406
+
407
+ def page!(value)
408
+ check_loaded
409
+ @options[:page] = value
410
+ self
411
+ end
412
+
413
+ def per_page(value = NO_DEFAULT_VALUE)
414
+ if value == NO_DEFAULT_VALUE
415
+ private_execute.per_page
416
+ else
417
+ clone.per_page!(value)
418
+ end
419
+ end
420
+
421
+ def per(value)
422
+ per_page(value)
423
+ end
424
+
425
+ def per_page!(value)
426
+ check_loaded
427
+ # TODO set limit?
428
+ @options[:per_page] = value
429
+ self
430
+ end
431
+
432
+ def profile(value = true)
433
+ clone.profile!(value)
434
+ end
435
+
436
+ def profile!(value = true)
437
+ check_loaded
438
+ @options[:profile] = value
439
+ self
440
+ end
441
+
442
+ def request_params(value)
443
+ clone.request_params!(value)
444
+ end
445
+
446
+ def request_params!(value)
447
+ check_loaded
448
+ merge_option(:request_params, value)
449
+ self
450
+ end
451
+
452
+ def routing(value)
453
+ clone.routing!(value)
454
+ end
455
+
456
+ def routing!(value)
457
+ check_loaded
458
+ @options[:routing] = value
459
+ self
460
+ end
461
+
462
+ def scope_results(value)
463
+ clone.scope_results!(value)
464
+ end
465
+
466
+ def scope_results!(value)
467
+ check_loaded
468
+ @options[:scope_results] = value
469
+ self
470
+ end
471
+
472
+ def scroll(value = NO_DEFAULT_VALUE, &block)
473
+ if value == NO_DEFAULT_VALUE
474
+ private_execute.scroll(&block)
475
+ elsif block_given?
476
+ clone.scroll!(value).scroll(&block)
477
+ else
478
+ clone.scroll!(value)
479
+ end
480
+ end
481
+
482
+ def scroll!(value)
483
+ check_loaded
484
+ @options[:scroll] = value
485
+ self
486
+ end
487
+
488
+ def select(*values, &block)
489
+ if block_given?
490
+ private_execute.select(*values, &block)
491
+ else
492
+ clone.select!(*values)
493
+ end
494
+ end
495
+
496
+ def select!(*values)
497
+ check_loaded
498
+ concat_option(:select, values.flatten)
499
+ self
500
+ end
501
+
502
+ def similar(value = true)
503
+ clone.similar!(value)
504
+ end
505
+
506
+ def similar!(value = true)
507
+ check_loaded
508
+ @options[:similar] = value
509
+ self
510
+ end
511
+
512
+ def smart_aggs(value)
513
+ clone.smart_aggs!(value)
514
+ end
515
+
516
+ def smart_aggs!(value)
517
+ check_loaded
518
+ @options[:smart_aggs] = value
519
+ self
520
+ end
521
+
522
+ def suggest(value = true)
523
+ clone.suggest!(value)
524
+ end
525
+
526
+ def suggest!(value = true)
527
+ check_loaded
528
+ @options[:suggest] = value
529
+ self
530
+ end
531
+
532
+ def total_entries(value = NO_DEFAULT_VALUE)
533
+ if value == NO_DEFAULT_VALUE
534
+ private_execute.total_entries
535
+ else
536
+ clone.total_entries!(value)
537
+ end
538
+ end
539
+
540
+ def total_entries!(value)
541
+ check_loaded
542
+ @options[:total_entries] = value
543
+ self
544
+ end
545
+
546
+ def track(value = true)
547
+ clone.track!(value)
548
+ end
549
+
550
+ def track!(value = true)
551
+ check_loaded
552
+ @options[:track] = value
553
+ self
554
+ end
555
+
556
+ def type(*values)
557
+ clone.type!(*values)
558
+ end
559
+
560
+ def type!(*values)
561
+ check_loaded
562
+ concat_option(:type, values.flatten)
563
+ self
564
+ end
565
+
566
+ def where(value = NO_DEFAULT_VALUE)
567
+ if value == NO_DEFAULT_VALUE
568
+ Where.new(self)
569
+ else
570
+ clone.where!(value)
571
+ end
572
+ end
573
+
574
+ def where!(value)
575
+ check_loaded
576
+ value = ensure_permitted(value)
577
+ if @options[:where]
578
+ # keep simple when possible for smart aggs
579
+ if !@options[:where].keys.intersect?(value.keys)
580
+ merge_option(:where, value)
581
+ elsif @options[:where][:_and].is_a?(Array)
582
+ merge_option(:where, {_and: @options[:where][:_and] + [value]})
583
+ else
584
+ @options[:where] = {_and: [@options[:where], value]}
585
+ end
586
+ else
587
+ @options[:where] = value
588
+ end
589
+ self
590
+ end
591
+
592
+ def first(value = NO_DEFAULT_VALUE)
593
+ result =
594
+ if loaded?
595
+ private_execute
596
+ else
597
+ limit = value == NO_DEFAULT_VALUE ? 1 : value
598
+ previous_limit = (@options[:limit] || @options[:per_page])&.to_i
599
+ if previous_limit && previous_limit < limit
600
+ limit = previous_limit
601
+ end
602
+ limit(limit).load
603
+ end
604
+
605
+ if value == NO_DEFAULT_VALUE
606
+ result.first
607
+ else
608
+ result.first(value)
609
+ end
610
+ end
611
+
612
+ def pluck(*keys)
613
+ if !loaded? && @options[:load] == false
614
+ select(*keys).send(:private_execute).pluck(*keys)
615
+ else
616
+ private_execute.pluck(*keys)
617
+ end
618
+ end
619
+
620
+ def reorder(*values)
621
+ clone.reorder!(*values)
622
+ end
623
+
624
+ def reorder!(*values)
625
+ check_loaded
626
+ @options[:order] = values
627
+ self
628
+ end
629
+
630
+ def reselect(*values)
631
+ clone.reselect!(*values)
632
+ end
633
+
634
+ def reselect!(*values)
635
+ check_loaded
636
+ @options[:select] = values
637
+ self
638
+ end
639
+
640
+ def rewhere(value)
641
+ clone.rewhere!(value)
642
+ end
643
+
644
+ def rewhere!(value)
645
+ check_loaded
646
+ @options[:where] = ensure_permitted(value)
647
+ self
648
+ end
649
+
650
+ def only(*keys)
651
+ Relation.new(@model, @term, **@options.slice(*keys))
652
+ end
653
+
654
+ def except(*keys)
655
+ Relation.new(@model, @term, **@options.except(*keys))
656
+ end
657
+
658
+ def loaded?
659
+ !@execute.nil?
660
+ end
661
+
662
+ undef_method :respond_to_missing?
663
+
664
+ def respond_to_missing?(...)
665
+ Results.new(nil, nil, nil).respond_to?(...) || super
666
+ end
667
+
668
+ # TODO uncomment in 7.0
669
+ # def to_json(...)
670
+ # private_execute.to_a.to_json(...)
671
+ # end
672
+
673
+ # TODO uncomment in 7.0
674
+ # def as_json(...)
675
+ # private_execute.to_a.as_json(...)
676
+ # end
677
+
678
+ def to_yaml
679
+ private_execute.to_a.to_yaml
680
+ end
681
+
682
+ private
683
+
684
+ def private_execute
685
+ @execute ||= query.execute
686
+ end
687
+
688
+ def query
689
+ @query ||= Query.new(@model, @term, **@options)
690
+ end
691
+
692
+ def check_loaded
693
+ raise Error, "Relation loaded" if loaded?
694
+
695
+ # reset query since options will change
696
+ @query = nil
697
+ end
698
+
699
+ # provides *very* basic protection from unfiltered parameters
700
+ # this is not meant to be comprehensive and may be expanded in the future
701
+ def ensure_permitted(obj)
702
+ obj.to_h
703
+ end
704
+
705
+ def initialize_copy(other)
706
+ super
707
+ # shallow dup and avoid updating values in-place
708
+ @options = @options.dup
709
+ @execute = nil
710
+ end
711
+
712
+ def concat_option(key, value)
713
+ if @options[key]
714
+ @options[key] += value
715
+ else
716
+ @options[key] = value.to_ary
717
+ end
718
+ end
719
+
720
+ def merge_option(key, value)
721
+ if @options[key]
722
+ @options[key] = @options[key].merge(value)
723
+ else
724
+ @options[key] = value.to_hash
725
+ end
726
+ end
727
+ end
728
+ end