Class: Searchkick::Relation

Inherits:
Object
  • Object
show all
Defined in:
lib/searchkick/relation.rb

Constant Summary collapse

NO_DEFAULT_VALUE =
Object.new

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, term = "*", **options) ⇒ Relation

Returns a new instance of Relation.



14
15
16
17
18
19
20
21
# File 'lib/searchkick/relation.rb', line 14

def initialize(model, term = "*", **options)
  @model = model
  @term = term
  @options = options

  # generate query to validate options
  query if options.any?
end

Instance Attribute Details

#modelObject (readonly) Also known as: klass

Returns the value of attribute model.



11
12
13
# File 'lib/searchkick/relation.rb', line 11

def model
  @model
end

Instance Method Details

#aggs(*args, **kwargs) ⇒ Object



30
31
32
33
34
35
36
# File 'lib/searchkick/relation.rb', line 30

def aggs(*args, **kwargs)
  if args.empty? && kwargs.empty?
    private_execute.aggs
  else
    clone.aggs!(*args, **kwargs)
  end
end

#aggs!(*args, **kwargs) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/searchkick/relation.rb', line 38

def aggs!(*args, **kwargs)
  check_loaded
  aggs = {}
  args.flatten.each do |arg|
    if arg.is_a?(Hash)
      aggs.merge!(arg)
    else
      aggs[arg] = {}
    end
  end
  aggs.merge!(kwargs)
  merge_option(:aggs, aggs)
  self
end

#body(value = NO_DEFAULT_VALUE) ⇒ Object



53
54
55
56
57
58
59
# File 'lib/searchkick/relation.rb', line 53

def body(value = NO_DEFAULT_VALUE)
  if value == NO_DEFAULT_VALUE
    query.body
  else
    clone.body!(value)
  end
end

#body!(value) ⇒ Object



61
62
63
64
65
# File 'lib/searchkick/relation.rb', line 61

def body!(value)
  check_loaded
  @options[:body] = value
  self
end

#body_options(value) ⇒ Object



67
68
69
# File 'lib/searchkick/relation.rb', line 67

def body_options(value)
  clone.body_options!(value)
end

#body_options!(value) ⇒ Object



71
72
73
74
75
# File 'lib/searchkick/relation.rb', line 71

def body_options!(value)
  check_loaded
  merge_option(:body_options, value)
  self
end

#boost(value) ⇒ Object



77
78
79
# File 'lib/searchkick/relation.rb', line 77

def boost(value)
  clone.boost!(value)
end

#boost!(value) ⇒ Object



81
82
83
84
85
# File 'lib/searchkick/relation.rb', line 81

def boost!(value)
  check_loaded
  @options[:boost] = value
  self
end

#boost_by(value) ⇒ Object



87
88
89
# File 'lib/searchkick/relation.rb', line 87

def boost_by(value)
  clone.boost_by!(value)
end

#boost_by!(value) ⇒ Object



91
92
93
94
95
96
97
98
99
100
# File 'lib/searchkick/relation.rb', line 91

def boost_by!(value)
  check_loaded
  if value.is_a?(Array)
    value = value.to_h { |f| [f, {factor: 1}] }
  elsif !value.is_a?(Hash)
    value = {value => {factor: 1}}
  end
  merge_option(:boost_by, value)
  self
end

#boost_by_distance(value) ⇒ Object



102
103
104
# File 'lib/searchkick/relation.rb', line 102

def boost_by_distance(value)
  clone.boost_by_distance!(value)
end

#boost_by_distance!(value) ⇒ Object



106
107
108
109
110
111
112
# File 'lib/searchkick/relation.rb', line 106

def boost_by_distance!(value)
  check_loaded
  # legacy format
  value = {value[:field] => value.except(:field)} if value[:field]
  merge_option(:boost_by_distance, value)
  self
end

#boost_by_recency(value) ⇒ Object



114
115
116
# File 'lib/searchkick/relation.rb', line 114

def boost_by_recency(value)
  clone.boost_by_recency!(value)
end

#boost_by_recency!(value) ⇒ Object



118
119
120
121
122
# File 'lib/searchkick/relation.rb', line 118

def boost_by_recency!(value)
  check_loaded
  merge_option(:boost_by_recency, value)
  self
end

#boost_where(value) ⇒ Object



124
125
126
# File 'lib/searchkick/relation.rb', line 124

def boost_where(value)
  clone.boost_where!(value)
end

#boost_where!(value) ⇒ Object



128
129
130
131
132
133
# File 'lib/searchkick/relation.rb', line 128

def boost_where!(value)
  check_loaded
  # TODO merge duplicate fields
  merge_option(:boost_where, value)
  self
end

#conversions(value) ⇒ Object



135
136
137
# File 'lib/searchkick/relation.rb', line 135

def conversions(value)
  clone.conversions!(value)
end

#conversions!(value) ⇒ Object



139
140
141
142
143
# File 'lib/searchkick/relation.rb', line 139

def conversions!(value)
  check_loaded
  @options[:conversions] = value
  self
end

#conversions_term(value) ⇒ Object



165
166
167
# File 'lib/searchkick/relation.rb', line 165

def conversions_term(value)
  clone.conversions_term!(value)
end

#conversions_term!(value) ⇒ Object



169
170
171
172
173
# File 'lib/searchkick/relation.rb', line 169

def conversions_term!(value)
  check_loaded
  @options[:conversions_term] = value
  self
end

#conversions_v1(value) ⇒ Object



145
146
147
# File 'lib/searchkick/relation.rb', line 145

def conversions_v1(value)
  clone.conversions_v1!(value)
end

#conversions_v1!(value) ⇒ Object



149
150
151
152
153
# File 'lib/searchkick/relation.rb', line 149

def conversions_v1!(value)
  check_loaded
  @options[:conversions_v1] = value
  self
end

#conversions_v2(value) ⇒ Object



155
156
157
# File 'lib/searchkick/relation.rb', line 155

def conversions_v2(value)
  clone.conversions_v2!(value)
end

#conversions_v2!(value) ⇒ Object



159
160
161
162
163
# File 'lib/searchkick/relation.rb', line 159

def conversions_v2!(value)
  check_loaded
  @options[:conversions_v2] = value
  self
end

#debug(value = true) ⇒ Object



175
176
177
# File 'lib/searchkick/relation.rb', line 175

def debug(value = true)
  clone.debug!(value)
end

#debug!(value = true) ⇒ Object



179
180
181
182
183
# File 'lib/searchkick/relation.rb', line 179

def debug!(value = true)
  check_loaded
  @options[:debug] = value
  self
end

#emoji(value = true) ⇒ Object



185
186
187
# File 'lib/searchkick/relation.rb', line 185

def emoji(value = true)
  clone.emoji!(value)
end

#emoji!(value = true) ⇒ Object



189
190
191
192
193
# File 'lib/searchkick/relation.rb', line 189

def emoji!(value = true)
  check_loaded
  @options[:emoji] = value
  self
end

#except(*keys) ⇒ Object



654
655
656
# File 'lib/searchkick/relation.rb', line 654

def except(*keys)
  Relation.new(@model, @term, **@options.except(*keys))
end

#exclude(*values) ⇒ Object



195
196
197
# File 'lib/searchkick/relation.rb', line 195

def exclude(*values)
  clone.exclude!(*values)
end

#exclude!(*values) ⇒ Object



199
200
201
202
203
# File 'lib/searchkick/relation.rb', line 199

def exclude!(*values)
  check_loaded
  concat_option(:exclude, values.flatten)
  self
end

#explain(value = true) ⇒ Object



205
206
207
# File 'lib/searchkick/relation.rb', line 205

def explain(value = true)
  clone.explain!(value)
end

#explain!(value = true) ⇒ Object



209
210
211
212
213
# File 'lib/searchkick/relation.rb', line 209

def explain!(value = true)
  check_loaded
  @options[:explain] = value
  self
end

#fields(*values) ⇒ Object



215
216
217
# File 'lib/searchkick/relation.rb', line 215

def fields(*values)
  clone.fields!(*values)
end

#fields!(*values) ⇒ Object



219
220
221
222
223
# File 'lib/searchkick/relation.rb', line 219

def fields!(*values)
  check_loaded
  concat_option(:fields, values.flatten)
  self
end

#first(value = NO_DEFAULT_VALUE) ⇒ Object



592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
# File 'lib/searchkick/relation.rb', line 592

def first(value = NO_DEFAULT_VALUE)
  result =
    if loaded?
      private_execute
    else
      limit = value == NO_DEFAULT_VALUE ? 1 : value
      previous_limit = (@options[:limit] || @options[:per_page])&.to_i
      if previous_limit && previous_limit < limit
        limit = previous_limit
      end
      limit(limit).load
    end

  if value == NO_DEFAULT_VALUE
    result.first
  else
    result.first(value)
  end
end

#highlight(value) ⇒ Object



225
226
227
# File 'lib/searchkick/relation.rb', line 225

def highlight(value)
  clone.highlight!(value)
end

#highlight!(value) ⇒ Object



229
230
231
232
233
# File 'lib/searchkick/relation.rb', line 229

def highlight!(value)
  check_loaded
  @options[:highlight] = value
  self
end

#includes(*values) ⇒ Object



235
236
237
# File 'lib/searchkick/relation.rb', line 235

def includes(*values)
  clone.includes!(*values)
end

#includes!(*values) ⇒ Object



239
240
241
242
243
# File 'lib/searchkick/relation.rb', line 239

def includes!(*values)
  check_loaded
  concat_option(:includes, values.flatten)
  self
end

#index_name(*values) ⇒ Object



245
246
247
# File 'lib/searchkick/relation.rb', line 245

def index_name(*values)
  clone.index_name!(*values)
end

#index_name!(*values) ⇒ Object



249
250
251
252
253
254
255
256
257
258
# File 'lib/searchkick/relation.rb', line 249

def index_name!(*values)
  check_loaded
  values = values.flatten
  if values.all? { |v| v.respond_to?(:searchkick_index) }
    models!(*values)
  else
    concat_option(:index_name, values)
    self
  end
end

#indices_boost(value) ⇒ Object



260
261
262
# File 'lib/searchkick/relation.rb', line 260

def indices_boost(value)
  clone.indices_boost!(value)
end

#indices_boost!(value) ⇒ Object



264
265
266
267
268
# File 'lib/searchkick/relation.rb', line 264

def indices_boost!(value)
  check_loaded
  merge_option(:indices_boost, value)
  self
end

#inspectObject

same as Active Record



24
25
26
27
28
# File 'lib/searchkick/relation.rb', line 24

def inspect
  entries = private_execute.first(11).map!(&:inspect)
  entries[10] = "..." if entries.size == 11
  "#<#{self.class.name} [#{entries.join(', ')}]>"
end

#knn(value) ⇒ Object



270
271
272
# File 'lib/searchkick/relation.rb', line 270

def knn(value)
  clone.knn!(value)
end

#knn!(value) ⇒ Object



274
275
276
277
278
# File 'lib/searchkick/relation.rb', line 274

def knn!(value)
  check_loaded
  @options[:knn] = value
  self
end

#limit(value) ⇒ Object



280
281
282
# File 'lib/searchkick/relation.rb', line 280

def limit(value)
  clone.limit!(value)
end

#limit!(value) ⇒ Object



284
285
286
287
288
# File 'lib/searchkick/relation.rb', line 284

def limit!(value)
  check_loaded
  @options[:limit] = value
  self
end

#load(value = NO_DEFAULT_VALUE) ⇒ Object



290
291
292
293
294
295
296
297
# File 'lib/searchkick/relation.rb', line 290

def load(value = NO_DEFAULT_VALUE)
  if value == NO_DEFAULT_VALUE
    private_execute
    self
  else
    clone.load!(value)
  end
end

#load!(value) ⇒ Object



299
300
301
302
303
# File 'lib/searchkick/relation.rb', line 299

def load!(value)
  check_loaded
  @options[:load] = value
  self
end

#loaded?Boolean

Returns:

  • (Boolean)


658
659
660
# File 'lib/searchkick/relation.rb', line 658

def loaded?
  !@execute.nil?
end

#match(value) ⇒ Object



305
306
307
# File 'lib/searchkick/relation.rb', line 305

def match(value)
  clone.match!(value)
end

#match!(value) ⇒ Object



309
310
311
312
313
# File 'lib/searchkick/relation.rb', line 309

def match!(value)
  check_loaded
  @options[:match] = value
  self
end

#misspellings(value) ⇒ Object



315
316
317
# File 'lib/searchkick/relation.rb', line 315

def misspellings(value)
  clone.misspellings!(value)
end

#misspellings!(value) ⇒ Object



319
320
321
322
323
# File 'lib/searchkick/relation.rb', line 319

def misspellings!(value)
  check_loaded
  @options[:misspellings] = value
  self
end

#model_includes(*values) ⇒ Object



335
336
337
# File 'lib/searchkick/relation.rb', line 335

def model_includes(*values)
  clone.model_includes!(*values)
end

#model_includes!(*values) ⇒ Object



339
340
341
342
343
# File 'lib/searchkick/relation.rb', line 339

def model_includes!(*values)
  check_loaded
  concat_option(:model_includes, values.flatten)
  self
end

#models(*values) ⇒ Object



325
326
327
# File 'lib/searchkick/relation.rb', line 325

def models(*values)
  clone.models!(*values)
end

#models!(*values) ⇒ Object



329
330
331
332
333
# File 'lib/searchkick/relation.rb', line 329

def models!(*values)
  check_loaded
  concat_option(:models, values.flatten)
  self
end

#offset(value = NO_DEFAULT_VALUE) ⇒ Object



345
346
347
348
349
350
351
# File 'lib/searchkick/relation.rb', line 345

def offset(value = NO_DEFAULT_VALUE)
  if value == NO_DEFAULT_VALUE
    private_execute.offset
  else
    clone.offset!(value)
  end
end

#offset!(value) ⇒ Object



353
354
355
356
357
# File 'lib/searchkick/relation.rb', line 353

def offset!(value)
  check_loaded
  @options[:offset] = value
  self
end

#only(*keys) ⇒ Object



650
651
652
# File 'lib/searchkick/relation.rb', line 650

def only(*keys)
  Relation.new(@model, @term, **@options.slice(*keys))
end

#opaque_id(value) ⇒ Object



359
360
361
# File 'lib/searchkick/relation.rb', line 359

def opaque_id(value)
  clone.opaque_id!(value)
end

#opaque_id!(value) ⇒ Object



363
364
365
366
367
# File 'lib/searchkick/relation.rb', line 363

def opaque_id!(value)
  check_loaded
  @options[:opaque_id] = value
  self
end

#operator(value) ⇒ Object



369
370
371
# File 'lib/searchkick/relation.rb', line 369

def operator(value)
  clone.operator!(value)
end

#operator!(value) ⇒ Object



373
374
375
376
377
# File 'lib/searchkick/relation.rb', line 373

def operator!(value)
  check_loaded
  @options[:operator] = value
  self
end

#order(*values) ⇒ Object



379
380
381
# File 'lib/searchkick/relation.rb', line 379

def order(*values)
  clone.order!(*values)
end

#order!(*values) ⇒ Object



383
384
385
386
387
# File 'lib/searchkick/relation.rb', line 383

def order!(*values)
  check_loaded
  concat_option(:order, values.flatten)
  self
end

#padding(value = NO_DEFAULT_VALUE) ⇒ Object



389
390
391
392
393
394
395
# File 'lib/searchkick/relation.rb', line 389

def padding(value = NO_DEFAULT_VALUE)
  if value == NO_DEFAULT_VALUE
    private_execute.padding
  else
    clone.padding!(value)
  end
end

#padding!(value) ⇒ Object



397
398
399
400
401
# File 'lib/searchkick/relation.rb', line 397

def padding!(value)
  check_loaded
  @options[:padding] = value
  self
end

#page(value) ⇒ Object



403
404
405
# File 'lib/searchkick/relation.rb', line 403

def page(value)
  clone.page!(value)
end

#page!(value) ⇒ Object



407
408
409
410
411
# File 'lib/searchkick/relation.rb', line 407

def page!(value)
  check_loaded
  @options[:page] = value
  self
end

#per(value) ⇒ Object



421
422
423
# File 'lib/searchkick/relation.rb', line 421

def per(value)
  per_page(value)
end

#per_page(value = NO_DEFAULT_VALUE) ⇒ Object



413
414
415
416
417
418
419
# File 'lib/searchkick/relation.rb', line 413

def per_page(value = NO_DEFAULT_VALUE)
  if value == NO_DEFAULT_VALUE
    private_execute.per_page
  else
    clone.per_page!(value)
  end
end

#per_page!(value) ⇒ Object



425
426
427
428
429
430
# File 'lib/searchkick/relation.rb', line 425

def per_page!(value)
  check_loaded
  # TODO set limit?
  @options[:per_page] = value
  self
end

#pluck(*keys) ⇒ Object



612
613
614
615
616
617
618
# File 'lib/searchkick/relation.rb', line 612

def pluck(*keys)
  if !loaded? && @options[:load] == false
    select(*keys).send(:private_execute).pluck(*keys)
  else
    private_execute.pluck(*keys)
  end
end

#profile(value = true) ⇒ Object



432
433
434
# File 'lib/searchkick/relation.rb', line 432

def profile(value = true)
  clone.profile!(value)
end

#profile!(value = true) ⇒ Object



436
437
438
439
440
# File 'lib/searchkick/relation.rb', line 436

def profile!(value = true)
  check_loaded
  @options[:profile] = value
  self
end

#reorder(*values) ⇒ Object



620
621
622
# File 'lib/searchkick/relation.rb', line 620

def reorder(*values)
  clone.reorder!(*values)
end

#reorder!(*values) ⇒ Object



624
625
626
627
628
# File 'lib/searchkick/relation.rb', line 624

def reorder!(*values)
  check_loaded
  @options[:order] = values
  self
end

#request_params(value) ⇒ Object



442
443
444
# File 'lib/searchkick/relation.rb', line 442

def request_params(value)
  clone.request_params!(value)
end

#request_params!(value) ⇒ Object



446
447
448
449
450
# File 'lib/searchkick/relation.rb', line 446

def request_params!(value)
  check_loaded
  merge_option(:request_params, value)
  self
end

#reselect(*values) ⇒ Object



630
631
632
# File 'lib/searchkick/relation.rb', line 630

def reselect(*values)
  clone.reselect!(*values)
end

#reselect!(*values) ⇒ Object



634
635
636
637
638
# File 'lib/searchkick/relation.rb', line 634

def reselect!(*values)
  check_loaded
  @options[:select] = values
  self
end

#respond_to_missing?Boolean

Returns:

  • (Boolean)


664
665
666
# File 'lib/searchkick/relation.rb', line 664

def respond_to_missing?(...)
  Results.new(nil, nil, nil).respond_to?(...) || super
end

#rewhere(value) ⇒ Object



640
641
642
# File 'lib/searchkick/relation.rb', line 640

def rewhere(value)
  clone.rewhere!(value)
end

#rewhere!(value) ⇒ Object



644
645
646
647
648
# File 'lib/searchkick/relation.rb', line 644

def rewhere!(value)
  check_loaded
  @options[:where] = ensure_permitted(value)
  self
end

#routing(value) ⇒ Object



452
453
454
# File 'lib/searchkick/relation.rb', line 452

def routing(value)
  clone.routing!(value)
end

#routing!(value) ⇒ Object



456
457
458
459
460
# File 'lib/searchkick/relation.rb', line 456

def routing!(value)
  check_loaded
  @options[:routing] = value
  self
end

#scope_results(value) ⇒ Object



462
463
464
# File 'lib/searchkick/relation.rb', line 462

def scope_results(value)
  clone.scope_results!(value)
end

#scope_results!(value) ⇒ Object



466
467
468
469
470
# File 'lib/searchkick/relation.rb', line 466

def scope_results!(value)
  check_loaded
  @options[:scope_results] = value
  self
end

#scroll(value = NO_DEFAULT_VALUE, &block) ⇒ Object



472
473
474
475
476
477
478
479
480
# File 'lib/searchkick/relation.rb', line 472

def scroll(value = NO_DEFAULT_VALUE, &block)
  if value == NO_DEFAULT_VALUE
    private_execute.scroll(&block)
  elsif block_given?
    clone.scroll!(value).scroll(&block)
  else
    clone.scroll!(value)
  end
end

#scroll!(value) ⇒ Object



482
483
484
485
486
# File 'lib/searchkick/relation.rb', line 482

def scroll!(value)
  check_loaded
  @options[:scroll] = value
  self
end

#select(*values, &block) ⇒ Object



488
489
490
491
492
493
494
# File 'lib/searchkick/relation.rb', line 488

def select(*values, &block)
  if block_given?
    private_execute.select(*values, &block)
  else
    clone.select!(*values)
  end
end

#select!(*values) ⇒ Object



496
497
498
499
500
# File 'lib/searchkick/relation.rb', line 496

def select!(*values)
  check_loaded
  concat_option(:select, values.flatten)
  self
end

#similar(value = true) ⇒ Object



502
503
504
# File 'lib/searchkick/relation.rb', line 502

def similar(value = true)
  clone.similar!(value)
end

#similar!(value = true) ⇒ Object



506
507
508
509
510
# File 'lib/searchkick/relation.rb', line 506

def similar!(value = true)
  check_loaded
  @options[:similar] = value
  self
end

#smart_aggs(value) ⇒ Object



512
513
514
# File 'lib/searchkick/relation.rb', line 512

def smart_aggs(value)
  clone.smart_aggs!(value)
end

#smart_aggs!(value) ⇒ Object



516
517
518
519
520
# File 'lib/searchkick/relation.rb', line 516

def smart_aggs!(value)
  check_loaded
  @options[:smart_aggs] = value
  self
end

#suggest(value = true) ⇒ Object



522
523
524
# File 'lib/searchkick/relation.rb', line 522

def suggest(value = true)
  clone.suggest!(value)
end

#suggest!(value = true) ⇒ Object



526
527
528
529
530
# File 'lib/searchkick/relation.rb', line 526

def suggest!(value = true)
  check_loaded
  @options[:suggest] = value
  self
end

#to_yamlObject

TODO uncomment in 7.0 def as_json(…)

private_execute.to_a.as_json(...)

end



678
679
680
# File 'lib/searchkick/relation.rb', line 678

def to_yaml
  private_execute.to_a.to_yaml
end

#total_entries(value = NO_DEFAULT_VALUE) ⇒ Object



532
533
534
535
536
537
538
# File 'lib/searchkick/relation.rb', line 532

def total_entries(value = NO_DEFAULT_VALUE)
  if value == NO_DEFAULT_VALUE
    private_execute.total_entries
  else
    clone.total_entries!(value)
  end
end

#total_entries!(value) ⇒ Object



540
541
542
543
544
# File 'lib/searchkick/relation.rb', line 540

def total_entries!(value)
  check_loaded
  @options[:total_entries] = value
  self
end

#track(value = true) ⇒ Object



546
547
548
# File 'lib/searchkick/relation.rb', line 546

def track(value = true)
  clone.track!(value)
end

#track!(value = true) ⇒ Object



550
551
552
553
554
# File 'lib/searchkick/relation.rb', line 550

def track!(value = true)
  check_loaded
  @options[:track] = value
  self
end

#type(*values) ⇒ Object



556
557
558
# File 'lib/searchkick/relation.rb', line 556

def type(*values)
  clone.type!(*values)
end

#type!(*values) ⇒ Object



560
561
562
563
564
# File 'lib/searchkick/relation.rb', line 560

def type!(*values)
  check_loaded
  concat_option(:type, values.flatten)
  self
end

#where(value = NO_DEFAULT_VALUE) ⇒ Object



566
567
568
569
570
571
572
# File 'lib/searchkick/relation.rb', line 566

def where(value = NO_DEFAULT_VALUE)
  if value == NO_DEFAULT_VALUE
    Where.new(self)
  else
    clone.where!(value)
  end
end

#where!(value) ⇒ Object



574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
# File 'lib/searchkick/relation.rb', line 574

def where!(value)
  check_loaded
  value = ensure_permitted(value)
  if @options[:where]
    # keep simple when possible for smart aggs
    if !@options[:where].keys.intersect?(value.keys)
      merge_option(:where, value)
    elsif @options[:where][:_and].is_a?(Array)
      merge_option(:where, {_and: @options[:where][:_and] + [value]})
    else
      @options[:where] = {_and: [@options[:where], value]}
    end
  else
    @options[:where] = value
  end
  self
end