searchkick 1.3.3 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 95d6fb192a6e28ebc711b99439f23ad5f27990ab
4
- data.tar.gz: 7b749691174ca6b03e471c75e4afb304f09869ef
3
+ metadata.gz: e771f2aea318aada5efd68350c101abca94a77a8
4
+ data.tar.gz: 4c3d8566133e79b6456609a9d50faf84be229454
5
5
  SHA512:
6
- metadata.gz: 37e07bcc09568bc7ca4806b5623eb53436fcdfcca773fd12398886240aefddb0666a5385d13146b7667fc582f9bedf6a9ce1193ecff4e7fe5c94484d9053fcf1
7
- data.tar.gz: 9a6d7f8844242656226dca9f2d984ee7740c43e3ccd0724a4bacb3f03b5426860140b1f5eebd554e70a6f9db42f008c92267b7b2c0c86a6d0057949c5ac26205
6
+ metadata.gz: 67375bbcd44840170e0fc29eeb84308f4e6814b24c30e8c8e6d0ed177df04dc038f7d0f4084d9cba19a2f5116249bb8313a37b01707e4163a83aeccc89a812c1
7
+ data.tar.gz: e31a38b61ed0ddf786f7aaf8be45eb39a938122305a9886d60fc33eaac335b267c468e1fb01511bf5863ca390bea86b216e822461422656e956c423948a3361c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 1.3.4
2
+
3
+ - Added `resume` option to reindex
4
+ - Added search timeout to payload
5
+
1
6
  ## 1.3.3
2
7
 
3
8
  - Fix for namespaced models (broken in 1.3.2)
data/README.md CHANGED
@@ -372,6 +372,12 @@ class Product < ActiveRecord::Base
372
372
  end
373
373
  ```
374
374
 
375
+ If a reindex is interrupted, you can resume it with:
376
+
377
+ ```ruby
378
+ Product.reindex(resume: true)
379
+ ```
380
+
375
381
  ### To Reindex, or Not to Reindex
376
382
 
377
383
  #### Reindex
@@ -140,34 +140,60 @@ module Searchkick
140
140
  index
141
141
  end
142
142
 
143
- # remove old indices that start w/ index_name
144
- def clean_indices
145
- all_indices =
143
+ def all_indices(options = {})
144
+ indices =
146
145
  begin
147
146
  client.indices.get_aliases
148
147
  rescue Elasticsearch::Transport::Transport::Errors::NotFound
149
148
  {}
150
149
  end
151
- indices = all_indices.select { |k, v| (v.empty? || v["aliases"].empty?) && k =~ /\A#{Regexp.escape(name)}_\d{14,17}\z/ }.keys
150
+ indices = indices.select { |k, v| v.empty? || v["aliases"].empty? } if options[:unaliased]
151
+ indices.select { |k, v| k =~ /\A#{Regexp.escape(name)}_\d{14,17}\z/ }.keys
152
+ end
153
+
154
+ # remove old indices that start w/ index_name
155
+ def clean_indices
156
+ indices = all_indices(unaliased: true)
152
157
  indices.each do |index|
153
158
  Searchkick::Index.new(index).delete
154
159
  end
155
160
  indices
156
161
  end
157
162
 
163
+ def total_docs
164
+ response =
165
+ client.search(
166
+ index: name,
167
+ body: {
168
+ fields: [],
169
+ query: {match_all: {}},
170
+ size: 0
171
+ }
172
+ )
173
+
174
+ response["hits"]["total"]
175
+ end
176
+
158
177
  # https://gist.github.com/jarosan/3124884
159
178
  # http://www.elasticsearch.org/blog/changing-mapping-with-zero-downtime/
160
179
  def reindex_scope(scope, options = {})
161
180
  skip_import = options[:import] == false
181
+ resume = options[:resume]
162
182
 
163
- clean_indices
183
+ if resume
184
+ index_name = all_indices.sort.last
185
+ raise Searchkick::Error, "No index to resume" unless index_name
186
+ index = Searchkick::Index.new(index_name)
187
+ else
188
+ clean_indices
164
189
 
165
- index = create_index(index_options: scope.searchkick_index_options)
190
+ index = create_index(index_options: scope.searchkick_index_options)
191
+ end
166
192
 
167
193
  # check if alias exists
168
194
  if alias_exists?
169
195
  # import before swap
170
- index.import_scope(scope) unless skip_import
196
+ index.import_scope(scope, resume: resume) unless skip_import
171
197
 
172
198
  # get existing indices to remove
173
199
  swap(index.name)
@@ -177,7 +203,7 @@ module Searchkick
177
203
  swap(index.name)
178
204
 
179
205
  # import after swap
180
- index.import_scope(scope) unless skip_import
206
+ index.import_scope(scope, resume: resume) unless skip_import
181
207
  end
182
208
 
183
209
  index.refresh
@@ -185,12 +211,20 @@ module Searchkick
185
211
  true
186
212
  end
187
213
 
188
- def import_scope(scope)
214
+ def import_scope(scope, options = {})
189
215
  batch_size = @options[:batch_size] || 1000
190
216
 
191
217
  # use scope for import
192
218
  scope = scope.search_import if scope.respond_to?(:search_import)
193
219
  if scope.respond_to?(:find_in_batches)
220
+ if options[:resume]
221
+ # use total docs instead of max id since there's not a great way
222
+ # to get the max _id without scripting since it's a string
223
+
224
+ # TODO use primary key and prefix with table name
225
+ scope = scope.where("id > ?", total_docs)
226
+ end
227
+
194
228
  scope.find_in_batches batch_size: batch_size do |batch|
195
229
  import batch.select(&:should_index?)
196
230
  end
@@ -198,6 +232,7 @@ module Searchkick
198
232
  # https://github.com/karmi/tire/blob/master/lib/tire/model/import.rb
199
233
  # use cursor for Mongoid
200
234
  items = []
235
+ # TODO add resume
201
236
  scope.all.each do |item|
202
237
  items << item if item.should_index?
203
238
  if items.length == batch_size
@@ -368,6 +368,9 @@ module Searchkick
368
368
  # highlight
369
369
  set_highlights(payload, fields) if options[:highlight]
370
370
 
371
+ # timeout shortly after client times out
372
+ payload[:timeout] ||= "#{Searchkick.search_timeout + 1}s"
373
+
371
374
  # An empty array will cause only the _id and _type for each hit to be returned
372
375
  # doc for :select - http://www.elasticsearch.org/guide/reference/api/search/fields/
373
376
  # doc for :select_v2 - https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering.html
@@ -1,3 +1,3 @@
1
1
  module Searchkick
2
- VERSION = "1.3.3"
2
+ VERSION = "1.3.4"
3
3
  end
data/test/query_test.rb CHANGED
@@ -13,11 +13,19 @@ class QueryTest < Minitest::Test
13
13
 
14
14
  def test_with_effective_min_score
15
15
  store_names ["Milk", "Milk2"]
16
- assert_equal ["Milk"], Product.search("Milk", body_options: { min_score: 0.1 }).map(&:name)
16
+ assert_search "milk", ["Milk"], body_options: {min_score: 0.1}
17
17
  end
18
18
 
19
19
  def test_with_uneffective_min_score
20
20
  store_names ["Milk", "Milk2"]
21
- assert_equal ["Milk", "Milk2"], Product.search("Milk", body_options: { min_score: 0.0001 }).map(&:name)
21
+ assert_search "milk", ["Milk", "Milk2"], body_options: {min_score: 0.0001}
22
+ end
23
+
24
+ def test_default_timeout
25
+ assert_equal "6s", Product.search("*", execute: false).body[:timeout]
26
+ end
27
+
28
+ def test_timeout_override
29
+ assert_equal "1s", Product.search("*", body_options: {timeout: "1s"}, execute: false).body[:timeout]
22
30
  end
23
31
  end
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: 1.3.3
4
+ version: 1.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-02 00:00:00.000000000 Z
11
+ date: 2016-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel