search_flip 1.1.0 → 2.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
@@ -38,7 +38,7 @@ module SearchFlip
38
38
  other = other.criteria
39
39
 
40
40
  fresh.tap do |criteria|
41
- criteria.profile_value = other.profile_value if other.profile_value != nil
41
+ criteria.profile_value = other.profile_value unless other.profile_value.nil?
42
42
  criteria.source_value = (criteria.source_value || []) + other.source_value if other.source_value
43
43
  criteria.sort_values = (criteria.sort_values || []) + other.sort_values if other.sort_values
44
44
  criteria.highlight_values = (criteria.highlight_values || {}).merge(other.highlight_values) if other.highlight_values
@@ -48,7 +48,7 @@ module SearchFlip
48
48
  criteria.includes_values = (criteria.includes_values || []) + other.includes_values if other.includes_values
49
49
  criteria.preload_values = (criteria.preload_values || []) + other.preload_values if other.preload_values
50
50
  criteria.eager_load_values = (criteria.eager_load_values || []) + other.eager_load_values if other.eager_load_values
51
- criteria.failsafe_value = other.failsafe_value if other.failsafe_value != nil
51
+ criteria.failsafe_value = other.failsafe_value unless other.failsafe_value.nil?
52
52
  criteria.scroll_args = other.scroll_args if other.scroll_args
53
53
  criteria.custom_value = (criteria.custom_value || {}).merge(other.custom_value) if other.custom_value
54
54
  criteria.search_values = (criteria.search_values || []) + other.search_values if other.search_values
@@ -62,8 +62,8 @@ module SearchFlip
62
62
  criteria.post_should_values = (criteria.post_should_values || []) + other.post_should_values if other.post_should_values
63
63
  criteria.post_filter_values = (criteria.post_filter_vales || []) + other.post_filter_values if other.post_filter_values
64
64
  criteria.aggregation_values = (criteria.aggregation_values || {}).merge(other.aggregation_values) if other.aggregation_values
65
- criteria.terminate_after_value = other.terminate_after_value if other.terminate_after_value != nil
66
- criteria.timeout_value = other.timeout_value if other.timeout_value != nil
65
+ criteria.terminate_after_value = other.terminate_after_value unless other.terminate_after_value.nil?
66
+ criteria.timeout_value = other.timeout_value unless other.timeout_value.nil?
67
67
  end
68
68
  end
69
69
 
@@ -74,11 +74,13 @@ module SearchFlip
74
74
  # @example
75
75
  # ProductIndex.timeout("3s").search("hello world")
76
76
  #
77
+ # @param value [String] The timeout value
78
+ #
77
79
  # @return [SearchFlip::Criteria] A newly created extended criteria
78
80
 
79
- def timeout(n)
81
+ def timeout(value)
80
82
  fresh.tap do |criteria|
81
- criteria.timeout_value = n
83
+ criteria.timeout_value = value
82
84
  end
83
85
  end
84
86
 
@@ -88,11 +90,13 @@ module SearchFlip
88
90
  # @example
89
91
  # ProductIndex.terminate_after(10_000).search("hello world")
90
92
  #
93
+ # @param value [Fixnum] The number of records to terminate after
94
+ #
91
95
  # @return [SearchFlip::Criteria] A newly created extended criteria
92
96
 
93
- def terminate_after(n)
97
+ def terminate_after(value)
94
98
  fresh.tap do |criteria|
95
- criteria.terminate_after_value = n
99
+ criteria.terminate_after_value = value
96
100
  end
97
101
  end
98
102
 
@@ -141,7 +145,7 @@ module SearchFlip
141
145
 
142
146
  def initialize(attributes = {})
143
147
  attributes.each do |key, value|
144
- self.send "#{key}=", value
148
+ send "#{key}=", value
145
149
  end
146
150
  end
147
151
 
@@ -155,30 +159,31 @@ module SearchFlip
155
159
  res = {}
156
160
 
157
161
  if must_values || search_values || must_not_values || should_values || filter_values
158
- if SearchFlip.version.to_i >= 2
162
+ if target.connection.version.to_i >= 2
159
163
  res[:query] = {
160
- bool: {}.
161
- merge(must_values || search_values ? { must: (must_values || []) + (search_values || [])} : {}).
162
- merge(must_not_values ? { must_not: must_not_values } : {}).
163
- merge(should_values ? { should: should_values } : {}).
164
- merge(filter_values ? { filter: filter_values } : {})
164
+ bool: {}
165
+ .merge(must_values || search_values ? { must: (must_values || []) + (search_values || []) } : {})
166
+ .merge(must_not_values ? { must_not: must_not_values } : {})
167
+ .merge(should_values ? { should: should_values } : {})
168
+ .merge(filter_values ? { filter: filter_values } : {})
165
169
  }
166
170
  else
167
171
  filters = (filter_values || []) + (must_not_values || []).map { |must_not_value| { not: must_not_value } }
168
172
 
169
- queries = {}.
170
- merge(must_values || search_values ? { must: (must_values || []) + (search_values || []) } : {}).
171
- merge(should_values ? { should: should_values } : {})
172
-
173
- if filters.size > 0
174
- res[:query] = {
175
- filtered: {}.
176
- merge(queries.size > 0 ? { query: { bool: queries } } : {}).
177
- merge(filter: filters.size > 1 ? { and: filters } : filters.first)
178
- }
179
- else
180
- res[:query] = { bool: queries }
181
- end
173
+ queries = {}
174
+ .merge(must_values || search_values ? { must: (must_values || []) + (search_values || []) } : {})
175
+ .merge(should_values ? { should: should_values } : {})
176
+
177
+ res[:query] =
178
+ if filters.size > 0
179
+ {
180
+ filtered: {}
181
+ .merge(queries.size > 0 ? { query: { bool: queries } } : {})
182
+ .merge(filter: filters.size > 1 ? { and: filters } : filters.first)
183
+ }
184
+ else
185
+ { bool: queries }
186
+ end
182
187
  end
183
188
  end
184
189
 
@@ -192,20 +197,20 @@ module SearchFlip
192
197
  res[:aggregations] = aggregation_values if aggregation_values
193
198
 
194
199
  if post_must_values || post_search_values || post_must_not_values || post_should_values || post_filter_values
195
- if SearchFlip.version.to_i >= 2
200
+ if target.connection.version.to_i >= 2
196
201
  res[:post_filter] = {
197
- bool: {}.
198
- merge(post_must_values || post_search_values ? { must: (post_must_values || []) + (post_search_values || []) } : {}).
199
- merge(post_must_not_values ? { must_not: post_must_not_values } : {}).
200
- merge(post_should_values ? { should: post_should_values } : {}).
201
- merge(post_filter_values ? { filter: post_filter_values } : {})
202
+ bool: {}
203
+ .merge(post_must_values || post_search_values ? { must: (post_must_values || []) + (post_search_values || []) } : {})
204
+ .merge(post_must_not_values ? { must_not: post_must_not_values } : {})
205
+ .merge(post_should_values ? { should: post_should_values } : {})
206
+ .merge(post_filter_values ? { filter: post_filter_values } : {})
202
207
  }
203
208
  else
204
209
  post_filters = (post_filter_values || []) + (post_must_not_values || []).map { |post_must_not_value| { not: post_must_not_value } }
205
210
 
206
- post_queries = {}.
207
- merge(post_must_values || post_search_values ? { must: (post_must_values || []) + (post_search_values || []) } : {}).
208
- merge(post_should_values ? { should: post_should_values } : {})
211
+ post_queries = {}
212
+ .merge(post_must_values || post_search_values ? { must: (post_must_values || []) + (post_search_values || []) } : {})
213
+ .merge(post_should_values ? { should: post_should_values } : {})
209
214
 
210
215
  post_filters_and_queries = post_filters + (post_queries.size > 0 ? [bool: post_queries] : [])
211
216
 
@@ -245,13 +250,14 @@ module SearchFlip
245
250
  fresh.tap do |criteria|
246
251
  criteria.highlight_values = (criteria.highlight_values || {}).merge(options)
247
252
 
248
- hash = if fields.is_a?(Hash)
249
- fields
250
- elsif fields.is_a?(Array)
251
- fields.each_with_object({}) { |field, h| h[field] = {} }
252
- else
253
- { fields => {} }
254
- end
253
+ hash =
254
+ if fields.is_a?(Hash)
255
+ fields
256
+ elsif fields.is_a?(Array)
257
+ fields.each_with_object({}) { |field, h| h[field] = {} }
258
+ else
259
+ { fields => {} }
260
+ end
255
261
 
256
262
  criteria.highlight_values[:fields] = (criteria.highlight_values[:fields] || {}).merge(hash)
257
263
  end
@@ -331,14 +337,14 @@ module SearchFlip
331
337
  # CommentIndex.where(public: false).delete
332
338
 
333
339
  def delete
334
- _request = request.dup
335
- _request.delete(:from)
336
- _request.delete(:size)
340
+ dupped_request = request.dup
341
+ dupped_request.delete(:from)
342
+ dupped_request.delete(:size)
337
343
 
338
- if SearchFlip.version.to_i >= 5
339
- SearchFlip::HTTPClient.post("#{target.type_url}/_delete_by_query", json: _request)
344
+ if target.connection.version.to_i >= 5
345
+ SearchFlip::HTTPClient.post("#{target.type_url}/_delete_by_query", json: dupped_request)
340
346
  else
341
- SearchFlip::HTTPClient.delete("#{target.type_url}/_query", json: _request)
347
+ SearchFlip::HTTPClient.delete("#{target.type_url}/_query", json: dupped_request)
342
348
  end
343
349
 
344
350
  target.refresh if SearchFlip::Config[:auto_refresh]
@@ -504,14 +510,14 @@ module SearchFlip
504
510
  # @example
505
511
  # CommentIndex.offset(100)
506
512
  #
507
- # @param n [Fixnum] The offset value, ie the number of results that are
513
+ # @param value [Fixnum] The offset value, ie the number of results that are
508
514
  # skipped in the result set
509
515
  #
510
516
  # @return [SearchFlip::Criteria] A newly created extended criteria
511
517
 
512
- def offset(n)
518
+ def offset(value)
513
519
  fresh.tap do |criteria|
514
- criteria.offset_value = n.to_i
520
+ criteria.offset_value = value.to_i
515
521
  end
516
522
  end
517
523
 
@@ -529,14 +535,14 @@ module SearchFlip
529
535
  # @example
530
536
  # CommentIndex.limit(100)
531
537
  #
532
- # @param n [Fixnum] The limit value, ie the max number of results that
538
+ # @param value [Fixnum] The limit value, ie the max number of results that
533
539
  # should be returned
534
540
  #
535
541
  # @return [SearchFlip::Criteria] A newly created extended criteria
536
542
 
537
- def limit(n)
543
+ def limit(value)
538
544
  fresh.tap do |criteria|
539
- criteria.limit_value = n.to_i
545
+ criteria.limit_value = value.to_i
540
546
  end
541
547
  end
542
548
 
@@ -567,12 +573,12 @@ module SearchFlip
567
573
  offset((page - 1) * per_page).limit(per_page)
568
574
  end
569
575
 
570
- def page(n)
571
- paginate(page: n)
576
+ def page(value)
577
+ paginate(page: value)
572
578
  end
573
579
 
574
- def per(n)
575
- paginate(page: offset_value_with_default / limit_value_with_default + 1, per_page: n)
580
+ def per(value)
581
+ paginate(page: offset_value_with_default / limit_value_with_default + 1, per_page: value)
576
582
  end
577
583
 
578
584
  # Fetches the records specified by the criteria in batches using the
@@ -656,29 +662,38 @@ module SearchFlip
656
662
  # response errors will be rescued if you specify the criteria to be
657
663
  # #failsafe, such that an empty response is returned instead.
658
664
  #
659
- # @param base_url An optional alternative base_url to send the request
660
- # to for e.g. proxying
665
+ # @param connection An optional alternative connection to used to send the
666
+ # request to for e.g. proxying
661
667
  #
662
668
  # @example
663
669
  # response = CommentIndex.search("hello world").execute
664
670
  #
665
671
  # @return [SearchFlip::Response] The response object
666
672
 
667
- def execute(base_url: target.base_url)
673
+ def execute(connection: target.connection)
668
674
  @response ||= begin
669
675
  http_request = SearchFlip::HTTPClient.headers(accept: "application/json")
670
676
 
671
677
  http_response =
672
678
  if scroll_args && scroll_args[:id]
673
- if SearchFlip.version.to_i >= 2
674
- http_request.post("#{base_url}/_search/scroll", json: { scroll: scroll_args[:timeout], scroll_id: scroll_args[:id] })
679
+ if target.connection.version.to_i >= 2
680
+ http_request.post(
681
+ "#{connection.base_url}/_search/scroll",
682
+ json: { scroll: scroll_args[:timeout], scroll_id: scroll_args[:id] }
683
+ )
675
684
  else
676
- http_request.headers(content_type: "text/plain").post("#{base_url}/_search/scroll", params: { scroll: scroll_args[:timeout] }, body: scroll_args[:id])
685
+ http_request
686
+ .headers(content_type: "text/plain")
687
+ .post("#{connection.base_url}/_search/scroll", params: { scroll: scroll_args[:timeout] }, body: scroll_args[:id])
677
688
  end
678
689
  elsif scroll_args
679
- http_request.post("#{target.type_url(base_url: base_url)}/_search", params: { scroll: scroll_args[:timeout] }, json: request)
690
+ http_request.post(
691
+ "#{target.type_url(connection: connection)}/_search",
692
+ params: { scroll: scroll_args[:timeout] },
693
+ json: request
694
+ )
680
695
  else
681
- http_request.post("#{target.type_url(base_url: base_url)}/_search", json: request)
696
+ http_request.post("#{target.type_url(connection: connection)}/_search", json: request)
682
697
  end
683
698
 
684
699
  SearchFlip::Response.new(self, http_response.parse)
@@ -731,8 +746,8 @@ module SearchFlip
731
746
  end
732
747
  end
733
748
 
734
- def respond_to?(name, *args)
735
- super || target.respond_to?(name, *args)
749
+ def respond_to_missing?(name, *args)
750
+ target.respond_to?(name, *args)
736
751
  end
737
752
 
738
753
  def method_missing(name, *args, &block)
@@ -743,8 +758,10 @@ module SearchFlip
743
758
  end
744
759
  end
745
760
 
746
- def_delegators :response, :total_entries, :total_count, :current_page, :previous_page, :prev_page, :next_page, :first_page?, :last_page?, :out_of_range?, :total_pages,
747
- :hits, :ids, :count, :size, :length, :took, :aggregations, :suggestions, :scope, :results, :records, :scroll_id, :raw_response
761
+ def_delegators :response, :total_entries, :total_count, :current_page, :previous_page,
762
+ :prev_page, :next_page, :first_page?, :last_page?, :out_of_range?, :total_pages,
763
+ :hits, :ids, :count, :size, :length, :took, :aggregations, :suggestions,
764
+ :scope, :results, :records, :scroll_id, :raw_response
748
765
 
749
766
  private
750
767
 
@@ -764,4 +781,3 @@ module SearchFlip
764
781
  end
765
782
  end
766
783
  end
767
-
@@ -0,0 +1,5 @@
1
+
2
+ module SearchFlip
3
+ class MethodNotImplemented < StandardError; end
4
+ end
5
+
@@ -31,7 +31,9 @@ module SearchFlip
31
31
 
32
32
  def search(q, options = {})
33
33
  fresh.tap do |criteria|
34
- criteria.search_values = (search_values || []) + [query_string: { query: q, :default_operator => :AND }.merge(options)] if q.to_s.strip.length > 0
34
+ if q.to_s.strip.length > 0
35
+ criteria.search_values = (search_values || []) + [query_string: { query: q, default_operator: :AND }.merge(options)]
36
+ end
35
37
  end
36
38
  end
37
39
 
@@ -88,7 +88,7 @@ module SearchFlip
88
88
  # @return [Hash] The hash-representation of the record
89
89
 
90
90
  def serialize(record)
91
- raise NotImplementedError
91
+ raise SearchFlip::MethodNotImplemented, "You must implement #{name}::serialize(record)"
92
92
  end
93
93
 
94
94
  # Adds a named scope to the index.
@@ -214,10 +214,13 @@ module SearchFlip
214
214
  SearchFlip::Criteria.new(target: self)
215
215
  end
216
216
 
217
- def_delegators :criteria, :profile, :where, :where_not, :filter, :range, :match_all, :exists, :exists_not, :post_where, :post_where_not, :post_filter, :post_range,
218
- :post_exists, :post_exists_not, :aggregate, :scroll, :source, :includes, :eager_load, :preload, :sort, :resort, :order, :reorder, :offset, :limit, :paginate,
219
- :page, :per, :search, :highlight, :suggest, :custom, :find_in_batches, :find_results_in_batches, :find_each, :failsafe, :total_entries, :total_count, :timeout,
220
- :terminate_after, :records, :should, :should_not, :must, :must_not
217
+ def_delegators :criteria, :profile, :where, :where_not, :filter, :range, :match_all, :exists,
218
+ :exists_not, :post_where, :post_where_not, :post_range, :post_exists, :post_exists_not,
219
+ :post_filter, :post_must, :post_must_not, :post_should, :aggregate, :scroll, :source,
220
+ :includes, :eager_load, :preload, :sort, :resort, :order, :reorder, :offset, :limit, :paginate,
221
+ :page, :per, :search, :highlight, :suggest, :custom, :find_in_batches, :find_results_in_batches,
222
+ :find_each, :failsafe, :total_entries, :total_count, :timeout, :terminate_after, :records,
223
+ :should, :should_not, :must, :must_not
221
224
 
222
225
  # Override to specify the type name used within ElasticSearch. Recap,
223
226
  # this gem uses an individual index for each index class, because
@@ -227,7 +230,7 @@ module SearchFlip
227
230
  # @return [String] The name used for the type within the index
228
231
 
229
232
  def type_name
230
- raise NotImplementedError
233
+ raise SearchFlip::MethodNotImplemented, "You must implement #{name}::type_name"
231
234
  end
232
235
 
233
236
  # Returns the base name of the index within ElasticSearch, ie the index
@@ -416,13 +419,13 @@ module SearchFlip
416
419
  # raised. Please note that this only applies to the bulk response, not to
417
420
  # the request in general, such that connection errors, etc will still
418
421
  # raise.
419
- # @param _index_options [Hash] Provides custom index options for eg
422
+ # @param additional_index_options [Hash] Provides custom index options for eg
420
423
  # routing, versioning, etc
421
424
 
422
- def index(scope, options = {}, _index_options = {})
425
+ def index(scope, options = {}, additional_index_options = {})
423
426
  bulk options do |indexer|
424
427
  each_record(scope, index_scope: true) do |object|
425
- indexer.index record_id(object), serialize(object), index_options(object).merge(_index_options)
428
+ indexer.index record_id(object), serialize(object), index_options(object).merge(additional_index_options)
426
429
  end
427
430
  end
428
431
 
@@ -437,10 +440,10 @@ module SearchFlip
437
440
  # @see #index See #index for more details regarding available
438
441
  # params and return values
439
442
 
440
- def create(scope, options = {}, _index_options = {})
443
+ def create(scope, options = {}, additional_index_options = {})
441
444
  bulk options do |indexer|
442
445
  each_record(scope, index_scope: true) do |object|
443
- indexer.create record_id(object), serialize(object), index_options(object).merge(_index_options)
446
+ indexer.create record_id(object), serialize(object), index_options(object).merge(additional_index_options)
444
447
  end
445
448
  end
446
449
 
@@ -455,10 +458,10 @@ module SearchFlip
455
458
  # @see #index See #index for more details regarding available
456
459
  # params and return values
457
460
 
458
- def update(scope, options = {}, _index_options = {})
461
+ def update(scope, options = {}, additional_index_options = {})
459
462
  bulk options do |indexer|
460
463
  each_record(scope, index_scope: true) do |object|
461
- indexer.update record_id(object), { doc: serialize(object) }, index_options(object).merge(_index_options)
464
+ indexer.update record_id(object), { doc: serialize(object) }, index_options(object).merge(additional_index_options)
462
465
  end
463
466
  end
464
467
 
@@ -471,10 +474,10 @@ module SearchFlip
471
474
  # @see #index See #index for more details regarding available
472
475
  # params and return values
473
476
 
474
- def delete(scope, options = {}, _index_options = {})
477
+ def delete(scope, options = {}, additional_index_options = {})
475
478
  bulk options do |indexer|
476
479
  each_record(scope) do |object|
477
- indexer.delete record_id(object), index_options(object).merge(_index_options)
480
+ indexer.delete record_id(object), index_options(object).merge(additional_index_options)
478
481
  end
479
482
  end
480
483
 
@@ -505,7 +508,7 @@ module SearchFlip
505
508
  # raised. Please note that this only applies to the bulk response, not to
506
509
  # the request in general, such that connection errors, etc will still
507
510
  # raise.
508
-
511
+
509
512
  def bulk(options = {})
510
513
  SearchFlip::Bulk.new("#{type_url}/_bulk", SearchFlip::Config[:bulk_limit], options) do |indexer|
511
514
  yield indexer
@@ -517,30 +520,33 @@ module SearchFlip
517
520
  # Returns the full ElasticSearch type URL, ie base URL, index name with
518
521
  # prefix and type name.
519
522
  #
523
+ # @param connection [SearchFlip::Connection] The connection to use
524
+ #
520
525
  # @return [String] The ElasticSearch type URL
521
526
 
522
- def type_url(base_url: self.base_url)
523
- "#{index_url(base_url: base_url)}/#{type_name}"
527
+ def type_url(connection: self.connection)
528
+ "#{index_url(connection: connection)}/#{type_name}"
524
529
  end
525
530
 
526
531
  # Returns the ElasticSearch index URL, ie base URL and index name with
527
532
  # prefix.
528
533
  #
534
+ # @param connection [SearchFlip::Connection] The connection to use
535
+ #
529
536
  # @return [String] The ElasticSearch index URL
530
537
 
531
- def index_url(base_url: self.base_url)
532
- "#{base_url}/#{index_name_with_prefix}"
538
+ def index_url(connection: self.connection)
539
+ "#{connection.base_url}/#{index_name_with_prefix}"
533
540
  end
534
541
 
535
- # Returns the ElasticSearch base URL, ie protcol and host with port.
536
- # Override to specify an index specific ElasticSearch cluster.
542
+ # Returns the SearchFlip::Connection for the index.
543
+ # Override to specify a custom connection.
537
544
  #
538
- # @return [String] The ElasticSearch base URL
545
+ # @return [SearchFlip::Connection] The connection
539
546
 
540
- def base_url
541
- SearchFlip::Config[:base_url]
547
+ def connection
548
+ @connection ||= SearchFlip::Connection.new(base_url: SearchFlip::Config[:base_url])
542
549
  end
543
550
  end
544
551
  end
545
552
  end
546
-