searchkick 4.0.0 → 4.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,6 +19,7 @@ module Searchkick
19
19
  @results ||= with_hit.map(&:first)
20
20
  end
21
21
 
22
+ # TODO return enumerator like with_score
22
23
  def with_hit
23
24
  @with_hit ||= begin
24
25
  if options[:load]
@@ -26,15 +27,19 @@ module Searchkick
26
27
  results = {}
27
28
 
28
29
  hits.group_by { |hit, _| hit["_index"] }.each do |index, grouped_hits|
29
- klass =
30
+ klasses =
30
31
  if @klass
31
- @klass
32
+ [@klass]
32
33
  else
33
34
  index_alias = index.split("_")[0..-2].join("_")
34
- (options[:index_mapping] || {})[index_alias]
35
+ Array((options[:index_mapping] || {})[index_alias])
35
36
  end
36
- raise Searchkick::Error, "Unknown model for index: #{index}" unless klass
37
- results[index] = results_query(klass, grouped_hits).to_a.index_by { |r| r.id.to_s }
37
+ raise Searchkick::Error, "Unknown model for index: #{index}" unless klasses.any?
38
+
39
+ results[index] = {}
40
+ klasses.each do |klass|
41
+ results[index].merge!(results_query(klass, grouped_hits).to_a.index_by { |r| r.id.to_s })
42
+ end
38
43
  end
39
44
 
40
45
  missing_ids = []
@@ -58,7 +63,7 @@ module Searchkick
58
63
  end
59
64
 
60
65
  if missing_ids.any?
61
- warn "[searchkick] WARNING: Records in search index do not exist in database: #{missing_ids.join(", ")}"
66
+ Searchkick.warn("Records in search index do not exist in database: #{missing_ids.join(", ")}")
62
67
  end
63
68
 
64
69
  results
@@ -90,7 +95,7 @@ module Searchkick
90
95
  def suggestions
91
96
  if response["suggest"]
92
97
  response["suggest"].values.flat_map { |v| v.first["options"] }.sort_by { |o| -o["score"] }.map { |o| o["text"] }.uniq
93
- elsif options[:term] == "*"
98
+ elsif options[:suggest] || options[:term] == "*" # TODO remove 2nd term
94
99
  []
95
100
  else
96
101
  raise "Pass `suggest: true` to the search method for suggestions"
@@ -207,16 +212,70 @@ module Searchkick
207
212
  end
208
213
  end
209
214
 
215
+ # TODO return enumerator like with_score
210
216
  def with_highlights(multiple: false)
211
217
  with_hit.map do |result, hit|
212
218
  [result, hit_highlights(hit, multiple: multiple)]
213
219
  end
214
220
  end
215
221
 
222
+ def with_score
223
+ return enum_for(:with_score) unless block_given?
224
+
225
+ with_hit.each do |result, hit|
226
+ yield result, hit["_score"]
227
+ end
228
+ end
229
+
216
230
  def misspellings?
217
231
  @options[:misspellings]
218
232
  end
219
233
 
234
+ def scroll_id
235
+ @response["_scroll_id"]
236
+ end
237
+
238
+ def scroll
239
+ raise Searchkick::Error, "Pass `scroll` option to the search method for scrolling" unless scroll_id
240
+
241
+ if block_given?
242
+ records = self
243
+ while records.any?
244
+ yield records
245
+ records = records.scroll
246
+ end
247
+
248
+ records.clear_scroll
249
+ else
250
+ params = {
251
+ scroll: options[:scroll],
252
+ scroll_id: scroll_id
253
+ }
254
+
255
+ begin
256
+ # TODO Active Support notifications for this scroll call
257
+ Searchkick::Results.new(@klass, Searchkick.client.scroll(params), @options)
258
+ rescue Elasticsearch::Transport::Transport::Errors::NotFound => e
259
+ if e.class.to_s =~ /NotFound/ && e.message =~ /search_context_missing_exception/i
260
+ raise Searchkick::Error, "Scroll id has expired"
261
+ else
262
+ raise e
263
+ end
264
+ end
265
+ end
266
+ end
267
+
268
+ def clear_scroll
269
+ begin
270
+ # try to clear scroll
271
+ # not required as scroll will expire
272
+ # but there is a cost to open scrolls
273
+ Searchkick.client.clear_scroll(scroll_id: scroll_id)
274
+ rescue Elasticsearch::Transport::Transport::Error
275
+ # do nothing
276
+ end
277
+ end
278
+
220
279
  private
221
280
 
222
281
  def results_query(records, hits)
@@ -1,3 +1,3 @@
1
1
  module Searchkick
2
- VERSION = "4.0.0"
2
+ VERSION = "4.4.1"
3
3
  end
@@ -1,22 +1,29 @@
1
1
  namespace :searchkick do
2
- desc "reindex model"
2
+ desc "reindex a model (specify CLASS)"
3
3
  task reindex: :environment do
4
- if ENV["CLASS"]
5
- klass = ENV["CLASS"].constantize rescue nil
6
- if klass
7
- klass.reindex
8
- else
9
- abort "Could not find class: #{ENV['CLASS']}"
10
- end
11
- else
12
- abort "USAGE: rake searchkick:reindex CLASS=Product"
13
- end
4
+ class_name = ENV["CLASS"]
5
+ abort "USAGE: rake searchkick:reindex CLASS=Product" unless class_name
6
+
7
+ model = class_name.safe_constantize
8
+ abort "Could not find class: #{class_name}" unless model
9
+ abort "#{class_name} is not a searchkick model" unless Searchkick.models.include?(model)
10
+
11
+ puts "Reindexing #{model.name}..."
12
+ model.reindex
13
+ puts "Reindex successful"
14
14
  end
15
15
 
16
16
  namespace :reindex do
17
17
  desc "reindex all models"
18
18
  task all: :environment do
19
- Rails.application.eager_load!
19
+ # eager load models to populate Searchkick.models
20
+ if Rails.respond_to?(:autoloaders) && Rails.autoloaders.zeitwerk_enabled?
21
+ # fix for https://github.com/rails/rails/issues/37006
22
+ Zeitwerk::Loader.eager_load_all
23
+ else
24
+ Rails.application.eager_load!
25
+ end
26
+
20
27
  Searchkick.models.each do |model|
21
28
  puts "Reindexing #{model.name}..."
22
29
  model.reindex
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: searchkick
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-12 00:00:00.000000000 Z
11
+ date: 2020-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -52,48 +52,6 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: bundler
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: minitest
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rake
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
55
  description:
98
56
  email: andrew@chartkick.com
99
57
  executables: []
@@ -101,7 +59,6 @@ extensions: []
101
59
  extra_rdoc_files: []
102
60
  files:
103
61
  - CHANGELOG.md
104
- - CONTRIBUTING.md
105
62
  - LICENSE.txt
106
63
  - README.md
107
64
  - lib/searchkick.rb
@@ -145,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
102
  - !ruby/object:Gem::Version
146
103
  version: '0'
147
104
  requirements: []
148
- rubygems_version: 3.0.3
105
+ rubygems_version: 3.1.2
149
106
  signing_key:
150
107
  specification_version: 4
151
108
  summary: Intelligent search made easy with Rails and Elasticsearch
@@ -1,53 +0,0 @@
1
- # Contributing
2
-
3
- First, thanks for wanting to contribute. You’re awesome! :heart:
4
-
5
- ## Help
6
-
7
- We’re not able to provide support through GitHub Issues. If you’re looking for help with your code, try posting on [Stack Overflow](https://stackoverflow.com/).
8
-
9
- All features should be documented. If you don’t see a feature in the docs, assume it doesn’t exist.
10
-
11
- ## Bugs
12
-
13
- Think you’ve discovered a bug?
14
-
15
- 1. Search existing issues to see if it’s been reported.
16
- 2. Try the `master` branch to make sure it hasn’t been fixed.
17
-
18
- ```rb
19
- gem "searchkick", github: "ankane/searchkick"
20
- ```
21
-
22
- 3. Try the `debug` option when searching. This can reveal useful info.
23
-
24
- ```ruby
25
- Product.search("something", debug: true)
26
- ```
27
-
28
- If the above steps don’t help, create an issue.
29
-
30
- - Recreate the problem by forking [this gist](https://gist.github.com/ankane/f80b0923d9ae2c077f41997f7b704e5c). Include a link to your gist and the output in the issue.
31
- - For exceptions, include the complete backtrace.
32
-
33
- ## New Features
34
-
35
- If you’d like to discuss a new feature, create an issue and start the title with `[Idea]`.
36
-
37
- ## Pull Requests
38
-
39
- Fork the project and create a pull request. A few tips:
40
-
41
- - Keep changes to a minimum. If you have multiple features or fixes, submit multiple pull requests.
42
- - Follow the existing style. The code should read like it’s written by a single person.
43
- - Add one or more tests if possible. Make sure existing tests pass with:
44
-
45
- ```sh
46
- bundle exec rake test
47
- ```
48
-
49
- Feel free to open an issue to get feedback on your idea before spending too much time on it.
50
-
51
- ---
52
-
53
- This contributing guide is released under [CCO](https://creativecommons.org/publicdomain/zero/1.0/) (public domain). Use it for your own project without attribution.