searchkick 5.0.0 → 5.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/README.md +18 -10
- data/lib/searchkick/index.rb +29 -15
- data/lib/searchkick/index_options.rb +1 -1
- data/lib/searchkick/model.rb +9 -7
- data/lib/searchkick/query.rb +2 -2
- data/lib/searchkick/record_data.rb +1 -0
- data/lib/searchkick/record_indexer.rb +2 -2
- data/lib/searchkick/reindex_queue.rb +1 -1
- data/lib/searchkick/results.rb +5 -5
- data/lib/searchkick/version.rb +1 -1
- data/lib/searchkick.rb +4 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab19b7696cc775bda54eef31aaf9fea04a13a3027335440023f58f0c3b761fa0
|
4
|
+
data.tar.gz: 461f230a62f440e84684e9eb42cc85d307b726830eba80999c5648aef13de92e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5382e2de584271fc9f80802f858329c613f3b9aff7877c9bb9653dab550deb6ed1ac6971cbb2bc306f4d6e67056f16ee98eea04d69f2fd9ff15fd899e37f8962
|
7
|
+
data.tar.gz: dd8121e4991c9aaad5cd331cdc3adef3c703ee47abf8238ea3cc6feb1b1e5dcd85cb59c9f7ce91c086644d5946c5ccba936f48d0bc27988a59cca81adf161bb3
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## 5.0.1 (2022-02-27)
|
2
|
+
|
3
|
+
- Prefer `mode: :async` over `async: true` for full reindex
|
4
|
+
- Fixed instance method overriding with concerns
|
5
|
+
|
1
6
|
## 5.0.0 (2022-02-21)
|
2
7
|
|
3
8
|
- Searches now use lazy loading (similar to Active Record)
|
@@ -15,7 +20,7 @@
|
|
15
20
|
- Raise error when `search` called on relations
|
16
21
|
- Raise `ArgumentError` (instead of warning) for invalid regular expression modifiers
|
17
22
|
- Raise `ArgumentError` instead of `RuntimeError` for unknown operators
|
18
|
-
- Removed mapping of `id` to `_id` with `order` option
|
23
|
+
- Removed mapping of `id` to `_id` with `order` option (not supported in Elasticsearch 8)
|
19
24
|
- Removed `wordnet` option (no longer worked)
|
20
25
|
- Removed dependency on `elasticsearch` gem (can use `elasticsearch` or `opensearch-ruby`)
|
21
26
|
- Dropped support for Elasticsearch 6
|
data/README.md
CHANGED
@@ -596,7 +596,7 @@ You can also do bulk updates.
|
|
596
596
|
|
597
597
|
```ruby
|
598
598
|
Searchkick.callbacks(:bulk) do
|
599
|
-
|
599
|
+
Product.find_each(&:update_fields)
|
600
600
|
end
|
601
601
|
```
|
602
602
|
|
@@ -604,7 +604,7 @@ Or temporarily skip updates.
|
|
604
604
|
|
605
605
|
```ruby
|
606
606
|
Searchkick.callbacks(false) do
|
607
|
-
|
607
|
+
Product.find_each(&:update_fields)
|
608
608
|
end
|
609
609
|
```
|
610
610
|
|
@@ -1100,7 +1100,7 @@ Product.search_index.tokens("dieg", analyzer: "searchkick_word_search")
|
|
1100
1100
|
# ["dieg"] - match!!
|
1101
1101
|
```
|
1102
1102
|
|
1103
|
-
See the [complete list of analyzers](
|
1103
|
+
See the [complete list of analyzers](lib/searchkick/index_options.rb#L36).
|
1104
1104
|
|
1105
1105
|
## Testing
|
1106
1106
|
|
@@ -1376,13 +1376,13 @@ Bonsai, Elastic Cloud, and Amazon OpenSearch Service all support encryption at r
|
|
1376
1376
|
|
1377
1377
|
### Automatic Failover
|
1378
1378
|
|
1379
|
-
Create an initializer
|
1379
|
+
Create an initializer with multiple hosts:
|
1380
1380
|
|
1381
1381
|
```ruby
|
1382
1382
|
ENV["ELASTICSEARCH_URL"] = "https://user:password@host1,https://user:password@host2"
|
1383
1383
|
```
|
1384
1384
|
|
1385
|
-
See [
|
1385
|
+
See [elastic-transport](https://github.com/elastic/elastic-transport-ruby) or [opensearch-transport](https://github.com/opensearch-project/opensearch-ruby/tree/main/opensearch-transport) for a complete list of options.
|
1386
1386
|
|
1387
1387
|
### Lograge
|
1388
1388
|
|
@@ -1453,7 +1453,7 @@ end
|
|
1453
1453
|
For large data sets, you can use background jobs to parallelize reindexing.
|
1454
1454
|
|
1455
1455
|
```ruby
|
1456
|
-
Product.reindex(
|
1456
|
+
Product.reindex(mode: :async)
|
1457
1457
|
# {index_name: "products_production_20170111210018065"}
|
1458
1458
|
```
|
1459
1459
|
|
@@ -1478,7 +1478,7 @@ Searchkick.reindex_status(index_name)
|
|
1478
1478
|
You can also have Searchkick wait for reindexing to complete
|
1479
1479
|
|
1480
1480
|
```ruby
|
1481
|
-
Product.reindex(
|
1481
|
+
Product.reindex(mode: :async, wait: true)
|
1482
1482
|
```
|
1483
1483
|
|
1484
1484
|
You can use [ActiveJob::TrafficControl](https://github.com/nickelser/activejob-traffic_control) to control concurrency. Install the gem:
|
@@ -1504,7 +1504,7 @@ This will allow only 3 jobs to run at once.
|
|
1504
1504
|
You can specify a longer refresh interval while reindexing to increase performance.
|
1505
1505
|
|
1506
1506
|
```ruby
|
1507
|
-
Product.reindex(
|
1507
|
+
Product.reindex(mode: :async, refresh_interval: "30s")
|
1508
1508
|
```
|
1509
1509
|
|
1510
1510
|
**Note:** This only makes a noticable difference with parallel reindexing.
|
@@ -1711,7 +1711,7 @@ products =
|
|
1711
1711
|
|
1712
1712
|
### Client
|
1713
1713
|
|
1714
|
-
|
1714
|
+
To access the `Elasticsearch::Client` or `OpenSearch::Client` directly, use:
|
1715
1715
|
|
1716
1716
|
```ruby
|
1717
1717
|
Searchkick.client
|
@@ -2087,9 +2087,17 @@ Product.search("milk")
|
|
2087
2087
|
Product.search("milk").to_a
|
2088
2088
|
```
|
2089
2089
|
|
2090
|
+
You can reindex relations in the background:
|
2091
|
+
|
2092
|
+
```ruby
|
2093
|
+
store.products.reindex(mode: :async)
|
2094
|
+
# or
|
2095
|
+
store.products.reindex(mode: :queue)
|
2096
|
+
```
|
2097
|
+
|
2090
2098
|
And there’s a [new option](#default-scopes) for models with default scopes.
|
2091
2099
|
|
2092
|
-
Check out the [changelog](https://github.com/ankane/searchkick/blob/master/CHANGELOG.md) for the full list of changes.
|
2100
|
+
Check out the [changelog](https://github.com/ankane/searchkick/blob/master/CHANGELOG.md#500-2022-02-21) for the full list of changes.
|
2093
2101
|
|
2094
2102
|
## History
|
2095
2103
|
|
data/lib/searchkick/index.rb
CHANGED
@@ -71,12 +71,12 @@ module Searchkick
|
|
71
71
|
}
|
72
72
|
)
|
73
73
|
|
74
|
-
|
74
|
+
Results.new(nil, response).total_count
|
75
75
|
end
|
76
76
|
|
77
77
|
def promote(new_name, update_refresh_interval: false)
|
78
78
|
if update_refresh_interval
|
79
|
-
new_index =
|
79
|
+
new_index = Index.new(new_name, @options)
|
80
80
|
settings = options[:settings] || {}
|
81
81
|
refresh_interval = (settings[:index] && settings[:index][:refresh_interval]) || "1s"
|
82
82
|
new_index.update_settings(index: {refresh_interval: refresh_interval})
|
@@ -123,7 +123,7 @@ module Searchkick
|
|
123
123
|
def clean_indices
|
124
124
|
indices = all_indices(unaliased: true)
|
125
125
|
indices.each do |index|
|
126
|
-
|
126
|
+
Index.new(index).delete
|
127
127
|
end
|
128
128
|
indices
|
129
129
|
end
|
@@ -204,7 +204,7 @@ module Searchkick
|
|
204
204
|
# queue
|
205
205
|
|
206
206
|
def reindex_queue
|
207
|
-
|
207
|
+
ReindexQueue.new(name)
|
208
208
|
end
|
209
209
|
|
210
210
|
# reindex
|
@@ -237,13 +237,26 @@ module Searchkick
|
|
237
237
|
self.refresh if refresh
|
238
238
|
true
|
239
239
|
else
|
240
|
+
async = options.delete(:async)
|
241
|
+
if async
|
242
|
+
if async.is_a?(Hash) && async[:wait]
|
243
|
+
# TODO warn in 5.1
|
244
|
+
# Searchkick.warn "async option is deprecated - use mode: :async, wait: true instead"
|
245
|
+
options[:wait] = true unless options.key?(:wait)
|
246
|
+
else
|
247
|
+
# TODO warn in 5.1
|
248
|
+
# Searchkick.warn "async option is deprecated - use mode: :async instead"
|
249
|
+
end
|
250
|
+
options[:mode] ||= :async
|
251
|
+
end
|
252
|
+
|
240
253
|
full_reindex(relation, **options)
|
241
254
|
end
|
242
255
|
end
|
243
256
|
|
244
257
|
def create_index(index_options: nil)
|
245
258
|
index_options ||= self.index_options
|
246
|
-
index =
|
259
|
+
index = Index.new("#{name}_#{Time.now.strftime('%Y%m%d%H%M%S%L')}", @options)
|
247
260
|
index.create(index_options)
|
248
261
|
index
|
249
262
|
end
|
@@ -326,7 +339,7 @@ module Searchkick
|
|
326
339
|
end
|
327
340
|
|
328
341
|
def reindex_records(object, mode: nil, refresh: false, **options)
|
329
|
-
mode ||= Searchkick.callbacks_value || @options[:callbacks] ||
|
342
|
+
mode ||= Searchkick.callbacks_value || @options[:callbacks] || :inline
|
330
343
|
mode = :inline if mode == :bulk
|
331
344
|
|
332
345
|
result = RecordIndexer.new(self).reindex(object, mode: mode, full: false, **options)
|
@@ -336,12 +349,13 @@ module Searchkick
|
|
336
349
|
|
337
350
|
# https://gist.github.com/jarosan/3124884
|
338
351
|
# http://www.elasticsearch.org/blog/changing-mapping-with-zero-downtime/
|
339
|
-
|
340
|
-
|
352
|
+
def full_reindex(relation, import: true, resume: false, retain: false, mode: nil, refresh_interval: nil, scope: nil, wait: nil)
|
353
|
+
raise ArgumentError, "wait only available in :async mode" if !wait.nil? && mode != :async
|
354
|
+
|
341
355
|
if resume
|
342
356
|
index_name = all_indices.sort.last
|
343
|
-
raise
|
344
|
-
index =
|
357
|
+
raise Error, "No index to resume" unless index_name
|
358
|
+
index = Index.new(index_name, @options)
|
345
359
|
else
|
346
360
|
clean_indices unless retain
|
347
361
|
|
@@ -351,7 +365,7 @@ module Searchkick
|
|
351
365
|
end
|
352
366
|
|
353
367
|
import_options = {
|
354
|
-
mode: (
|
368
|
+
mode: (mode || :inline),
|
355
369
|
full: true,
|
356
370
|
resume: resume,
|
357
371
|
scope: scope
|
@@ -365,7 +379,7 @@ module Searchkick
|
|
365
379
|
import_before_promotion(index, relation, **import_options) if import
|
366
380
|
|
367
381
|
# get existing indices to remove
|
368
|
-
unless async
|
382
|
+
unless mode == :async
|
369
383
|
check_uuid(uuid, index.uuid)
|
370
384
|
promote(index.name, update_refresh_interval: !refresh_interval.nil?)
|
371
385
|
clean_indices unless retain
|
@@ -378,8 +392,8 @@ module Searchkick
|
|
378
392
|
index.import_scope(relation, **import_options) if import
|
379
393
|
end
|
380
394
|
|
381
|
-
if async
|
382
|
-
if
|
395
|
+
if mode == :async
|
396
|
+
if wait
|
383
397
|
puts "Created index: #{index.name}"
|
384
398
|
puts "Jobs queued. Waiting..."
|
385
399
|
loop do
|
@@ -417,7 +431,7 @@ module Searchkick
|
|
417
431
|
# https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html#index-creation
|
418
432
|
def check_uuid(old_uuid, new_uuid)
|
419
433
|
if old_uuid != new_uuid
|
420
|
-
raise
|
434
|
+
raise Error, "Safety check failed - only run one Model.reindex per model at a time"
|
421
435
|
end
|
422
436
|
end
|
423
437
|
|
@@ -513,7 +513,7 @@ module Searchkick
|
|
513
513
|
else
|
514
514
|
[:searchkick_search2, :searchkick_word_search].each do |analyzer|
|
515
515
|
unless settings[:analysis][:analyzer][analyzer].key?(:filter)
|
516
|
-
raise
|
516
|
+
raise Error, "Search synonyms are not supported yet for language"
|
517
517
|
end
|
518
518
|
|
519
519
|
settings[:analysis][:analyzer][analyzer][:filter].insert(2, "searchkick_synonym_graph")
|
data/lib/searchkick/model.rb
CHANGED
@@ -22,16 +22,18 @@ module Searchkick
|
|
22
22
|
raise ArgumentError, "Invalid value for callbacks"
|
23
23
|
end
|
24
24
|
|
25
|
+
base = self
|
26
|
+
|
25
27
|
mod = Module.new
|
26
28
|
include(mod)
|
27
29
|
mod.module_eval do
|
28
30
|
def reindex(method_name = nil, mode: nil, refresh: false)
|
29
31
|
self.class.searchkick_index.reindex([self], method_name: method_name, mode: mode, refresh: refresh, single: true)
|
30
|
-
end
|
32
|
+
end unless base.method_defined?(:reindex)
|
31
33
|
|
32
34
|
def similar(**options)
|
33
35
|
self.class.searchkick_index.similar_record(self, **options)
|
34
|
-
end
|
36
|
+
end unless base.method_defined?(:similar)
|
35
37
|
|
36
38
|
def search_data
|
37
39
|
data = respond_to?(:to_hash) ? to_hash : serializable_hash
|
@@ -39,11 +41,11 @@ module Searchkick
|
|
39
41
|
data.delete("_id")
|
40
42
|
data.delete("_type")
|
41
43
|
data
|
42
|
-
end
|
44
|
+
end unless base.method_defined?(:search_data)
|
43
45
|
|
44
46
|
def should_index?
|
45
47
|
true
|
46
|
-
end
|
48
|
+
end unless base.method_defined?(:should_index?)
|
47
49
|
end
|
48
50
|
|
49
51
|
class_eval do
|
@@ -64,10 +66,10 @@ module Searchkick
|
|
64
66
|
alias_method Searchkick.search_method_name, :searchkick_search if Searchkick.search_method_name
|
65
67
|
|
66
68
|
def searchkick_index(name: nil)
|
67
|
-
|
68
|
-
|
69
|
+
index_name = name || searchkick_index_name
|
70
|
+
index_name = index_name.call if index_name.respond_to?(:call)
|
69
71
|
index_cache = class_variable_get(:@@searchkick_index_cache)
|
70
|
-
index_cache.fetch(
|
72
|
+
index_cache.fetch(index_name) { Searchkick::Index.new(index_name, searchkick_options) }
|
71
73
|
end
|
72
74
|
alias_method :search_index, :searchkick_index unless method_defined?(:search_index)
|
73
75
|
|
data/lib/searchkick/query.rb
CHANGED
@@ -187,11 +187,11 @@ module Searchkick
|
|
187
187
|
end
|
188
188
|
|
189
189
|
# set execute for multi search
|
190
|
-
@execute =
|
190
|
+
@execute = Results.new(searchkick_klass, response, opts)
|
191
191
|
end
|
192
192
|
|
193
193
|
def retry_misspellings?(response)
|
194
|
-
@misspellings_below &&
|
194
|
+
@misspellings_below && Results.new(searchkick_klass, response).total_count < @misspellings_below
|
195
195
|
end
|
196
196
|
|
197
197
|
private
|
@@ -14,7 +14,7 @@ module Searchkick
|
|
14
14
|
case mode
|
15
15
|
when :async
|
16
16
|
unless defined?(ActiveJob)
|
17
|
-
raise
|
17
|
+
raise Error, "Active Job not found"
|
18
18
|
end
|
19
19
|
|
20
20
|
# we could likely combine ReindexV2Job, BulkReindexJob, and ProcessBatchJob
|
@@ -45,7 +45,7 @@ module Searchkick
|
|
45
45
|
end
|
46
46
|
when :queue
|
47
47
|
if method_name
|
48
|
-
raise
|
48
|
+
raise Error, "Partial reindex not supported with queue option"
|
49
49
|
end
|
50
50
|
|
51
51
|
index.reindex_queue.push_records(records)
|
data/lib/searchkick/results.rb
CHANGED
@@ -141,7 +141,7 @@ module Searchkick
|
|
141
141
|
|
142
142
|
def hits
|
143
143
|
if error
|
144
|
-
raise
|
144
|
+
raise Error, "Query error - use the error method to view it"
|
145
145
|
else
|
146
146
|
@response["hits"]["hits"]
|
147
147
|
end
|
@@ -178,7 +178,7 @@ module Searchkick
|
|
178
178
|
end
|
179
179
|
|
180
180
|
def scroll
|
181
|
-
raise
|
181
|
+
raise Error, "Pass `scroll` option to the search method for scrolling" unless scroll_id
|
182
182
|
|
183
183
|
if block_given?
|
184
184
|
records = self
|
@@ -191,10 +191,10 @@ module Searchkick
|
|
191
191
|
else
|
192
192
|
begin
|
193
193
|
# TODO Active Support notifications for this scroll call
|
194
|
-
|
194
|
+
Results.new(@klass, Searchkick.client.scroll(scroll: options[:scroll], body: {scroll_id: scroll_id}), @options)
|
195
195
|
rescue => e
|
196
196
|
if Searchkick.not_found_error?(e) && e.message =~ /search_context_missing_exception/i
|
197
|
-
raise
|
197
|
+
raise Error, "Scroll id has expired"
|
198
198
|
else
|
199
199
|
raise e
|
200
200
|
end
|
@@ -232,7 +232,7 @@ module Searchkick
|
|
232
232
|
index_alias = index.split("_")[0..-2].join("_")
|
233
233
|
Array((options[:index_mapping] || {})[index_alias])
|
234
234
|
end
|
235
|
-
raise
|
235
|
+
raise Error, "Unknown model for index: #{index}. Pass the `models` option to the search method." unless models.any?
|
236
236
|
index_models[index] = models
|
237
237
|
end
|
238
238
|
|
data/lib/searchkick/version.rb
CHANGED
data/lib/searchkick.rb
CHANGED
@@ -171,7 +171,7 @@ module Searchkick
|
|
171
171
|
end
|
172
172
|
|
173
173
|
options = options.merge(block: block) if block
|
174
|
-
|
174
|
+
Relation.new(klass, term, **options)
|
175
175
|
end
|
176
176
|
|
177
177
|
def self.multi_search(queries)
|
@@ -183,7 +183,7 @@ module Searchkick
|
|
183
183
|
body: queries.flat_map { |q| [q.params.except(:body).to_json, q.body.to_json] }.map { |v| "#{v}\n" }.join,
|
184
184
|
}
|
185
185
|
ActiveSupport::Notifications.instrument("multi_search.searchkick", event) do
|
186
|
-
|
186
|
+
MultiSearch.new(queries).perform
|
187
187
|
end
|
188
188
|
end
|
189
189
|
|
@@ -241,9 +241,9 @@ module Searchkick
|
|
241
241
|
end
|
242
242
|
|
243
243
|
def self.reindex_status(index_name)
|
244
|
-
raise
|
244
|
+
raise Error, "Redis not configured" unless redis
|
245
245
|
|
246
|
-
batches_left =
|
246
|
+
batches_left = Index.new(index_name).batches_left
|
247
247
|
{
|
248
248
|
completed: batches_left == 0,
|
249
249
|
batches_left: batches_left
|
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: 5.0.
|
4
|
+
version: 5.0.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: 2022-02-
|
11
|
+
date: 2022-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|