searchkick 4.4.0 → 4.4.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 +11 -3
- data/README.md +211 -210
- data/lib/searchkick.rb +13 -10
- data/lib/searchkick/index.rb +9 -3
- data/lib/searchkick/index_options.rb +467 -400
- data/lib/searchkick/model.rb +1 -1
- data/lib/searchkick/results.rb +10 -0
- data/lib/searchkick/version.rb +1 -1
- data/lib/tasks/searchkick.rake +12 -11
- metadata +2 -59
- data/CONTRIBUTING.md +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff49d45a4473f44b07e8f1654d47e9b0590fd71eb3c6567f62b2fbcdc1e837b9
|
4
|
+
data.tar.gz: fd6ac4c931c7250787bc6f905c6c72b8412355e6b505bb2ef9d8cf5731d2939d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05630a20b302fd406e5545935861b6616db79e2dd12e2eb11fe82bb3733c8b21af1087b7ad8d0fd4bd93eb3a07d2bd67461815a293746a2d2c2d3f2148d7147b
|
7
|
+
data.tar.gz: 571528f3967fd921e92dda6413313d29bd9048ee832e44bdb1a31a297178c3ee2f0b31dead3c573b297da96b676fdd74467bd7aa514c6a97f2a38b2500901057
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## 4.4.1 (2020-06-24)
|
2
|
+
|
3
|
+
- Added `stem_exclusion` and `stemmer_override` options
|
4
|
+
- Added `with_score` method to search results
|
5
|
+
- Improved error message for `reload_synonyms` with non-OSS version of Elasticsearch
|
6
|
+
- Improved output for reindex rake task
|
7
|
+
|
1
8
|
## 4.4.0 (2020-06-17)
|
2
9
|
|
3
10
|
- Added support for reloadable, multi-word, search time synonyms
|
@@ -59,6 +66,7 @@ Breaking changes
|
|
59
66
|
|
60
67
|
- Removed support for Elasticsearch 5
|
61
68
|
- Removed support for multi-word synonyms (they no longer work with shingles)
|
69
|
+
- Removed support for Active Record < 5
|
62
70
|
|
63
71
|
## 3.1.3 (2019-04-11)
|
64
72
|
|
@@ -125,7 +133,7 @@ Breaking changes
|
|
125
133
|
Breaking changes
|
126
134
|
|
127
135
|
- Removed support for Elasticsearch 2
|
128
|
-
- Removed support for
|
136
|
+
- Removed support for Active Record < 4.2 and Mongoid < 5
|
129
137
|
- Types are no longer used
|
130
138
|
- The `_all` field is disabled by default in Elasticsearch 5
|
131
139
|
- Conversions are not stemmed by default
|
@@ -430,7 +438,7 @@ Breaking changes
|
|
430
438
|
|
431
439
|
## 0.8.3 (2014-09-20)
|
432
440
|
|
433
|
-
- Added support for
|
441
|
+
- Added support for Active Job
|
434
442
|
- Added `timeout` setting
|
435
443
|
- Fixed import with no records
|
436
444
|
|
@@ -537,7 +545,7 @@ Breaking changes
|
|
537
545
|
|
538
546
|
## 0.5.2 (2014-02-12)
|
539
547
|
|
540
|
-
- Use after_commit hook for
|
548
|
+
- Use after_commit hook for Active Record to prevent data inconsistencies
|
541
549
|
|
542
550
|
## 0.5.1 (2014-02-12)
|
543
551
|
|
data/README.md
CHANGED
@@ -33,13 +33,15 @@ Plus:
|
|
33
33
|
- [Getting Started](#getting-started)
|
34
34
|
- [Querying](#querying)
|
35
35
|
- [Indexing](#indexing)
|
36
|
+
- [Intelligent Search](#intelligent-search)
|
36
37
|
- [Instant Search / Autocomplete](#instant-search--autocomplete)
|
37
38
|
- [Aggregations](#aggregations)
|
39
|
+
- [Testing](#testing)
|
38
40
|
- [Deployment](#deployment)
|
39
41
|
- [Performance](#performance)
|
40
42
|
- [Elasticsearch DSL](#advanced)
|
41
43
|
- [Reference](#reference)
|
42
|
-
- [
|
44
|
+
- [Contributing](#contributing)
|
43
45
|
|
44
46
|
## Getting Started
|
45
47
|
|
@@ -297,7 +299,9 @@ To only match the exact order, use:
|
|
297
299
|
User.search "fresh honey", match: :phrase
|
298
300
|
```
|
299
301
|
|
300
|
-
### Language
|
302
|
+
### Stemming and Language
|
303
|
+
|
304
|
+
Searchkick stems words by default for better matching. `apple` and `apples` both stem to `appl`, so searches for either term will have the same matches.
|
301
305
|
|
302
306
|
Searchkick defaults to English for stemming. To change this, use:
|
303
307
|
|
@@ -307,9 +311,7 @@ class Product < ApplicationRecord
|
|
307
311
|
end
|
308
312
|
```
|
309
313
|
|
310
|
-
|
311
|
-
|
312
|
-
A few languages require plugins:
|
314
|
+
See the [list of stemmers](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-stemmer-tokenfilter.html). A few languages require plugins:
|
313
315
|
|
314
316
|
- `chinese` - [analysis-ik plugin](https://github.com/medcl/elasticsearch-analysis-ik)
|
315
317
|
- `chinese2` - [analysis-smartcn plugin](https://www.elastic.co/guide/en/elasticsearch/plugins/7.4/analysis-smartcn.html)
|
@@ -320,6 +322,30 @@ A few languages require plugins:
|
|
320
322
|
- `ukrainian` - [analysis-ukrainian plugin](https://www.elastic.co/guide/en/elasticsearch/plugins/7.4/analysis-ukrainian.html)
|
321
323
|
- `vietnamese` - [analysis-vietnamese plugin](https://github.com/duydo/elasticsearch-analysis-vietnamese)
|
322
324
|
|
325
|
+
Disable stemming with:
|
326
|
+
|
327
|
+
```ruby
|
328
|
+
class Image < ApplicationRecord
|
329
|
+
searchkick stem: false
|
330
|
+
end
|
331
|
+
```
|
332
|
+
|
333
|
+
Exclude certain words from stemming with:
|
334
|
+
|
335
|
+
```ruby
|
336
|
+
class Image < ApplicationRecord
|
337
|
+
searchkick stem_exclusion: ["apples"]
|
338
|
+
end
|
339
|
+
```
|
340
|
+
|
341
|
+
Or change how words are stemmed:
|
342
|
+
|
343
|
+
```ruby
|
344
|
+
class Image < ApplicationRecord
|
345
|
+
searchkick stemmer_override: ["apples => other"]
|
346
|
+
end
|
347
|
+
```
|
348
|
+
|
323
349
|
### Synonyms
|
324
350
|
|
325
351
|
```ruby
|
@@ -333,7 +359,7 @@ Call `Product.reindex` after changing synonyms. Synonyms are applied at search t
|
|
333
359
|
For directional synonyms, use:
|
334
360
|
|
335
361
|
```ruby
|
336
|
-
|
362
|
+
search_synonyms: ["lightbulb => halogenlamp"]
|
337
363
|
```
|
338
364
|
|
339
365
|
### Dynamic Synonyms
|
@@ -358,7 +384,7 @@ search_synonyms: "synonyms.txt"
|
|
358
384
|
Add [elasticsearch-xpack](https://github.com/elastic/elasticsearch-ruby/tree/master/elasticsearch-xpack) to your Gemfile:
|
359
385
|
|
360
386
|
```ruby
|
361
|
-
gem 'elasticsearch-xpack', '>= 7.8.0
|
387
|
+
gem 'elasticsearch-xpack', '>= 7.8.0'
|
362
388
|
```
|
363
389
|
|
364
390
|
And use:
|
@@ -521,7 +547,7 @@ For large data sets, try [parallel reindexing](#parallel-reindexing).
|
|
521
547
|
|
522
548
|
- app starts
|
523
549
|
|
524
|
-
###
|
550
|
+
### Strategies
|
525
551
|
|
526
552
|
There are four strategies for keeping the index synced with your database.
|
527
553
|
|
@@ -587,11 +613,9 @@ class Image < ApplicationRecord
|
|
587
613
|
end
|
588
614
|
```
|
589
615
|
|
590
|
-
|
591
|
-
|
592
|
-
The best starting point to improve your search **by far** is to track searches and conversions.
|
616
|
+
## Intelligent Search
|
593
617
|
|
594
|
-
[Searchjoy](https://github.com/ankane/searchjoy) makes it easy.
|
618
|
+
The best starting point to improve your search **by far** is to track searches and conversions. [Searchjoy](https://github.com/ankane/searchjoy) makes it easy.
|
595
619
|
|
596
620
|
```ruby
|
597
621
|
Product.search "apple", track: {user_id: current_user.id}
|
@@ -604,15 +628,9 @@ Focus on:
|
|
604
628
|
- top searches with low conversions
|
605
629
|
- top searches with no results
|
606
630
|
|
607
|
-
|
608
|
-
|
609
|
-
Searchkick can use conversion data to learn what users are looking for. If a user searches for “ice cream” and adds Ben & Jerry’s Chunky Monkey to the cart (our conversion metric at Instacart), that item gets a little more weight for similar searches.
|
631
|
+
Searchkick can then use the conversion data to learn what users are looking for. If a user searches for “ice cream” and adds Ben & Jerry’s Chunky Monkey to the cart (our conversion metric at Instacart), that item gets a little more weight for similar searches.
|
610
632
|
|
611
|
-
|
612
|
-
|
613
|
-
Searchkick automatically treats `apple` and `APPLE` the same.
|
614
|
-
|
615
|
-
Next, add conversions to the index.
|
633
|
+
Add conversion data with:
|
616
634
|
|
617
635
|
```ruby
|
618
636
|
class Product < ApplicationRecord
|
@@ -636,9 +654,11 @@ Reindex and set up a cron job to add new conversions daily.
|
|
636
654
|
rake searchkick:reindex CLASS=Product
|
637
655
|
```
|
638
656
|
|
639
|
-
|
657
|
+
This can make a huge difference on the quality of your search.
|
658
|
+
|
659
|
+
For a more performant way to reindex conversion data, check out [performant conversions](#performant-conversions).
|
640
660
|
|
641
|
-
|
661
|
+
## Personalized Results
|
642
662
|
|
643
663
|
Order results differently for each user. For example, show a user’s previously purchased products before other results.
|
644
664
|
|
@@ -659,7 +679,7 @@ Reindex and search with:
|
|
659
679
|
Product.search "milk", boost_where: {orderer_ids: current_user.id}
|
660
680
|
```
|
661
681
|
|
662
|
-
|
682
|
+
## Instant Search / Autocomplete
|
663
683
|
|
664
684
|
Autocomplete predicts what a user will type, making the search experience faster and easier.
|
665
685
|
|
@@ -727,7 +747,7 @@ Then add the search box and JavaScript code to a view.
|
|
727
747
|
</script>
|
728
748
|
```
|
729
749
|
|
730
|
-
|
750
|
+
## Suggestions
|
731
751
|
|
732
752
|
![Suggest](https://gist.github.com/ankane/b6988db2802aca68a589b31e41b44195/raw/40febe948427e5bc53ec4e5dc248822855fef76f/recursion.png)
|
733
753
|
|
@@ -744,7 +764,7 @@ products = Product.search "peantu butta", suggest: true
|
|
744
764
|
products.suggestions # ["peanut butter"]
|
745
765
|
```
|
746
766
|
|
747
|
-
|
767
|
+
## Aggregations
|
748
768
|
|
749
769
|
[Aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html) provide aggregated search data.
|
750
770
|
|
@@ -817,10 +837,10 @@ Product.search "pear", aggs: {products_per_year: {date_histogram: {field: :creat
|
|
817
837
|
For other aggregation types, including sub-aggregations, use `body_options`:
|
818
838
|
|
819
839
|
```ruby
|
820
|
-
Product.search "orange", body_options: {aggs: {price: {histogram: {field: :price, interval: 10}}}
|
840
|
+
Product.search "orange", body_options: {aggs: {price: {histogram: {field: :price, interval: 10}}}}
|
821
841
|
```
|
822
842
|
|
823
|
-
|
843
|
+
## Highlight
|
824
844
|
|
825
845
|
Specify which fields to index with highlighting.
|
826
846
|
|
@@ -873,7 +893,7 @@ Band.search "cinema", fields: [:name], highlight: {fields: {name: {fragment_size
|
|
873
893
|
|
874
894
|
You can find available highlight options in the [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-highlighting.html#_highlighted_fragments).
|
875
895
|
|
876
|
-
|
896
|
+
## Similar Items
|
877
897
|
|
878
898
|
Find similar items.
|
879
899
|
|
@@ -882,7 +902,7 @@ product = Product.first
|
|
882
902
|
product.similar(fields: [:name], where: {size: "12 oz"})
|
883
903
|
```
|
884
904
|
|
885
|
-
|
905
|
+
## Geospatial Searches
|
886
906
|
|
887
907
|
```ruby
|
888
908
|
class Restaurant < ApplicationRecord
|
@@ -1049,10 +1069,162 @@ Product.search_index.tokens("dieg", analyzer: "searchkick_word_search")
|
|
1049
1069
|
|
1050
1070
|
See the [complete list of analyzers](https://github.com/ankane/searchkick/blob/31780ddac7a89eab1e0552a32b403f2040a37931/lib/searchkick/index_options.rb#L32).
|
1051
1071
|
|
1072
|
+
## Testing
|
1073
|
+
|
1074
|
+
As you iterate on your search, it’s a good idea to add tests.
|
1075
|
+
|
1076
|
+
For performance, only enable Searchkick callbacks for the tests that need it.
|
1077
|
+
|
1078
|
+
### Parallel Tests
|
1079
|
+
|
1080
|
+
Rails 6 enables parallel tests by default. Add to your `test/test_helper.rb`:
|
1081
|
+
|
1082
|
+
```ruby
|
1083
|
+
class ActiveSupport::TestCase
|
1084
|
+
parallelize_setup do |worker|
|
1085
|
+
Searchkick.index_suffix = worker
|
1086
|
+
|
1087
|
+
# reindex models
|
1088
|
+
Product.reindex
|
1089
|
+
|
1090
|
+
# and disable callbacks
|
1091
|
+
Searchkick.disable_callbacks
|
1092
|
+
end
|
1093
|
+
end
|
1094
|
+
```
|
1095
|
+
|
1096
|
+
And use:
|
1097
|
+
|
1098
|
+
```ruby
|
1099
|
+
class ProductTest < ActiveSupport::TestCase
|
1100
|
+
def setup
|
1101
|
+
Searchkick.enable_callbacks
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
def teardown
|
1105
|
+
Searchkick.disable_callbacks
|
1106
|
+
end
|
1107
|
+
|
1108
|
+
def test_search
|
1109
|
+
Product.create!(name: "Apple")
|
1110
|
+
Product.search_index.refresh
|
1111
|
+
assert_equal ["Apple"], Product.search("apple").map(&:name)
|
1112
|
+
end
|
1113
|
+
end
|
1114
|
+
```
|
1115
|
+
|
1116
|
+
### Minitest
|
1117
|
+
|
1118
|
+
Add to your `test/test_helper.rb`:
|
1119
|
+
|
1120
|
+
```ruby
|
1121
|
+
# reindex models
|
1122
|
+
Product.reindex
|
1123
|
+
|
1124
|
+
# and disable callbacks
|
1125
|
+
Searchkick.disable_callbacks
|
1126
|
+
```
|
1127
|
+
|
1128
|
+
And use:
|
1129
|
+
|
1130
|
+
```ruby
|
1131
|
+
class ProductTest < Minitest::Test
|
1132
|
+
def setup
|
1133
|
+
Searchkick.enable_callbacks
|
1134
|
+
end
|
1135
|
+
|
1136
|
+
def teardown
|
1137
|
+
Searchkick.disable_callbacks
|
1138
|
+
end
|
1139
|
+
|
1140
|
+
def test_search
|
1141
|
+
Product.create!(name: "Apple")
|
1142
|
+
Product.search_index.refresh
|
1143
|
+
assert_equal ["Apple"], Product.search("apple").map(&:name)
|
1144
|
+
end
|
1145
|
+
end
|
1146
|
+
```
|
1147
|
+
|
1148
|
+
### RSpec
|
1149
|
+
|
1150
|
+
Add to your `spec/spec_helper.rb`:
|
1151
|
+
|
1152
|
+
```ruby
|
1153
|
+
RSpec.configure do |config|
|
1154
|
+
config.before(:suite) do
|
1155
|
+
# reindex models
|
1156
|
+
Product.reindex
|
1157
|
+
|
1158
|
+
# and disable callbacks
|
1159
|
+
Searchkick.disable_callbacks
|
1160
|
+
end
|
1161
|
+
|
1162
|
+
config.around(:each, search: true) do |example|
|
1163
|
+
Searchkick.callbacks(nil) do
|
1164
|
+
example.run
|
1165
|
+
end
|
1166
|
+
end
|
1167
|
+
end
|
1168
|
+
```
|
1169
|
+
|
1170
|
+
And use:
|
1171
|
+
|
1172
|
+
```ruby
|
1173
|
+
describe Product, search: true do
|
1174
|
+
it "searches" do
|
1175
|
+
Product.create!(name: "Apple")
|
1176
|
+
Product.search_index.refresh
|
1177
|
+
assert_equal ["Apple"], Product.search("apple").map(&:name)
|
1178
|
+
end
|
1179
|
+
end
|
1180
|
+
```
|
1181
|
+
|
1182
|
+
### Factory Bot
|
1183
|
+
|
1184
|
+
Use a trait and an after `create` hook for each indexed model:
|
1185
|
+
|
1186
|
+
```ruby
|
1187
|
+
FactoryBot.define do
|
1188
|
+
factory :product do
|
1189
|
+
# ...
|
1190
|
+
|
1191
|
+
# Note: This should be the last trait in the list so `reindex` is called
|
1192
|
+
# after all the other callbacks complete.
|
1193
|
+
trait :reindex do
|
1194
|
+
after(:create) do |product, _evaluator|
|
1195
|
+
product.reindex(refresh: true)
|
1196
|
+
end
|
1197
|
+
end
|
1198
|
+
end
|
1199
|
+
end
|
1200
|
+
|
1201
|
+
# use it
|
1202
|
+
FactoryBot.create(:product, :some_trait, :reindex, some_attribute: "foo")
|
1203
|
+
```
|
1204
|
+
|
1052
1205
|
## Deployment
|
1053
1206
|
|
1054
1207
|
Searchkick uses `ENV["ELASTICSEARCH_URL"]` for the Elasticsearch server. This defaults to `http://localhost:9200`.
|
1055
1208
|
|
1209
|
+
- [Elastic Cloud](#elastic-cloud)
|
1210
|
+
- [Heroku](#heroku)
|
1211
|
+
- [Amazon Elasticsearch Service](#amazon-elasticsearch-service)
|
1212
|
+
- [Self-Hosted and Other](#other)
|
1213
|
+
|
1214
|
+
### Elastic Cloud
|
1215
|
+
|
1216
|
+
Create an initializer `config/initializers/elasticsearch.rb` with:
|
1217
|
+
|
1218
|
+
```ruby
|
1219
|
+
ENV["ELASTICSEARCH_URL"] = "https://user:password@host:port"
|
1220
|
+
```
|
1221
|
+
|
1222
|
+
Then deploy and reindex:
|
1223
|
+
|
1224
|
+
```sh
|
1225
|
+
rake searchkick:reindex:all
|
1226
|
+
```
|
1227
|
+
|
1056
1228
|
### Heroku
|
1057
1229
|
|
1058
1230
|
Choose an add-on: [Bonsai](https://elements.heroku.com/addons/bonsai), [SearchBox](https://elements.heroku.com/addons/searchbox), or [Elastic Cloud](https://elements.heroku.com/addons/foundelasticsearch).
|
@@ -1093,7 +1265,7 @@ heroku config:set ELASTICSEARCH_URL=https://elastic:password@12345.us-east-1.aws
|
|
1093
1265
|
Then deploy and reindex:
|
1094
1266
|
|
1095
1267
|
```sh
|
1096
|
-
heroku run rake searchkick:reindex
|
1268
|
+
heroku run rake searchkick:reindex:all
|
1097
1269
|
```
|
1098
1270
|
|
1099
1271
|
### Amazon Elasticsearch Service
|
@@ -1123,10 +1295,10 @@ Searchkick.aws_credentials = {
|
|
1123
1295
|
Then deploy and reindex:
|
1124
1296
|
|
1125
1297
|
```sh
|
1126
|
-
rake searchkick:reindex
|
1298
|
+
rake searchkick:reindex:all
|
1127
1299
|
```
|
1128
1300
|
|
1129
|
-
### Other
|
1301
|
+
### Self-Hosted and Other
|
1130
1302
|
|
1131
1303
|
Create an initializer `config/initializers/elasticsearch.rb` with:
|
1132
1304
|
|
@@ -1137,7 +1309,7 @@ ENV["ELASTICSEARCH_URL"] = "https://user:password@host:port"
|
|
1137
1309
|
Then deploy and reindex:
|
1138
1310
|
|
1139
1311
|
```sh
|
1140
|
-
rake searchkick:reindex
|
1312
|
+
rake searchkick:reindex:all
|
1141
1313
|
```
|
1142
1314
|
|
1143
1315
|
### Data Protection
|
@@ -1517,6 +1689,10 @@ Boost specific models with:
|
|
1517
1689
|
indices_boost: {Category => 2, Product => 1}
|
1518
1690
|
```
|
1519
1691
|
|
1692
|
+
## Multi-Tenancy
|
1693
|
+
|
1694
|
+
Check out [this great post](https://www.tiagoamaro.com.br/2014/12/11/multi-tenancy-with-searchkick/) on the [Apartment](https://github.com/influitive/apartment) gem. Follow a similar pattern if you use another gem.
|
1695
|
+
|
1520
1696
|
## Scroll API
|
1521
1697
|
|
1522
1698
|
Searchkick also supports the [scroll API](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html). Scrolling is not intended for real time user requests, but rather for processing large amounts of data.
|
@@ -1723,14 +1899,6 @@ class Product < ApplicationRecord
|
|
1723
1899
|
end
|
1724
1900
|
```
|
1725
1901
|
|
1726
|
-
Turn off stemming
|
1727
|
-
|
1728
|
-
```ruby
|
1729
|
-
class Product < ApplicationRecord
|
1730
|
-
searchkick stem: false
|
1731
|
-
end
|
1732
|
-
```
|
1733
|
-
|
1734
1902
|
Turn on stemming for conversions
|
1735
1903
|
|
1736
1904
|
```ruby
|
@@ -1739,14 +1907,6 @@ class Product < ApplicationRecord
|
|
1739
1907
|
end
|
1740
1908
|
```
|
1741
1909
|
|
1742
|
-
Use a different [similarity algorithm](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-similarity.html) for scoring
|
1743
|
-
|
1744
|
-
```ruby
|
1745
|
-
class Product < ApplicationRecord
|
1746
|
-
searchkick similarity: "classic"
|
1747
|
-
end
|
1748
|
-
```
|
1749
|
-
|
1750
1910
|
Make search case-sensitive
|
1751
1911
|
|
1752
1912
|
```ruby
|
@@ -1831,172 +1991,11 @@ Product.search "api", misspellings: {prefix_length: 2} # api, apt, no ahi
|
|
1831
1991
|
Product.search "ah", misspellings: {prefix_length: 2} # ah, no aha
|
1832
1992
|
```
|
1833
1993
|
|
1834
|
-
## Testing
|
1835
|
-
|
1836
|
-
For performance, only enable Searchkick callbacks for the tests that need it.
|
1837
|
-
|
1838
|
-
### Parallel Tests
|
1839
|
-
|
1840
|
-
Rails 6 enables parallel tests by default. Add to your `test/test_helper.rb`:
|
1841
|
-
|
1842
|
-
```ruby
|
1843
|
-
class ActiveSupport::TestCase
|
1844
|
-
parallelize_setup do |worker|
|
1845
|
-
Searchkick.index_suffix = worker
|
1846
|
-
|
1847
|
-
# reindex models
|
1848
|
-
Product.reindex
|
1849
|
-
|
1850
|
-
# and disable callbacks
|
1851
|
-
Searchkick.disable_callbacks
|
1852
|
-
end
|
1853
|
-
end
|
1854
|
-
```
|
1855
|
-
|
1856
|
-
And use:
|
1857
|
-
|
1858
|
-
```ruby
|
1859
|
-
class ProductTest < ActiveSupport::TestCase
|
1860
|
-
def setup
|
1861
|
-
Searchkick.enable_callbacks
|
1862
|
-
end
|
1863
|
-
|
1864
|
-
def teardown
|
1865
|
-
Searchkick.disable_callbacks
|
1866
|
-
end
|
1867
|
-
|
1868
|
-
def test_search
|
1869
|
-
Product.create!(name: "Apple")
|
1870
|
-
Product.search_index.refresh
|
1871
|
-
assert_equal ["Apple"], Product.search("apple").map(&:name)
|
1872
|
-
end
|
1873
|
-
end
|
1874
|
-
```
|
1875
|
-
|
1876
|
-
### Minitest
|
1877
|
-
|
1878
|
-
Add to your `test/test_helper.rb`:
|
1879
|
-
|
1880
|
-
```ruby
|
1881
|
-
# reindex models
|
1882
|
-
Product.reindex
|
1883
|
-
|
1884
|
-
# and disable callbacks
|
1885
|
-
Searchkick.disable_callbacks
|
1886
|
-
```
|
1887
|
-
|
1888
|
-
And use:
|
1889
|
-
|
1890
|
-
```ruby
|
1891
|
-
class ProductTest < Minitest::Test
|
1892
|
-
def setup
|
1893
|
-
Searchkick.enable_callbacks
|
1894
|
-
end
|
1895
|
-
|
1896
|
-
def teardown
|
1897
|
-
Searchkick.disable_callbacks
|
1898
|
-
end
|
1899
|
-
|
1900
|
-
def test_search
|
1901
|
-
Product.create!(name: "Apple")
|
1902
|
-
Product.search_index.refresh
|
1903
|
-
assert_equal ["Apple"], Product.search("apple").map(&:name)
|
1904
|
-
end
|
1905
|
-
end
|
1906
|
-
```
|
1907
|
-
|
1908
|
-
### RSpec
|
1909
|
-
|
1910
|
-
Add to your `spec/spec_helper.rb`:
|
1911
|
-
|
1912
|
-
```ruby
|
1913
|
-
RSpec.configure do |config|
|
1914
|
-
config.before(:suite) do
|
1915
|
-
# reindex models
|
1916
|
-
Product.reindex
|
1917
|
-
|
1918
|
-
# and disable callbacks
|
1919
|
-
Searchkick.disable_callbacks
|
1920
|
-
end
|
1921
|
-
|
1922
|
-
config.around(:each, search: true) do |example|
|
1923
|
-
Searchkick.callbacks(nil) do
|
1924
|
-
example.run
|
1925
|
-
end
|
1926
|
-
end
|
1927
|
-
end
|
1928
|
-
```
|
1929
|
-
|
1930
|
-
And use:
|
1931
|
-
|
1932
|
-
```ruby
|
1933
|
-
describe Product, search: true do
|
1934
|
-
it "searches" do
|
1935
|
-
Product.create!(name: "Apple")
|
1936
|
-
Product.search_index.refresh
|
1937
|
-
assert_equal ["Apple"], Product.search("apple").map(&:name)
|
1938
|
-
end
|
1939
|
-
end
|
1940
|
-
```
|
1941
|
-
|
1942
|
-
### Factory Bot
|
1943
|
-
|
1944
|
-
Use a trait and an after `create` hook for each indexed model:
|
1945
|
-
|
1946
|
-
```ruby
|
1947
|
-
FactoryBot.define do
|
1948
|
-
factory :product do
|
1949
|
-
# ...
|
1950
|
-
|
1951
|
-
# Note: This should be the last trait in the list so `reindex` is called
|
1952
|
-
# after all the other callbacks complete.
|
1953
|
-
trait :reindex do
|
1954
|
-
after(:create) do |product, _evaluator|
|
1955
|
-
product.reindex(refresh: true)
|
1956
|
-
end
|
1957
|
-
end
|
1958
|
-
end
|
1959
|
-
end
|
1960
|
-
|
1961
|
-
# use it
|
1962
|
-
FactoryBot.create(:product, :some_trait, :reindex, some_attribute: "foo")
|
1963
|
-
```
|
1964
|
-
|
1965
|
-
## Multi-Tenancy
|
1966
|
-
|
1967
|
-
Check out [this great post](https://www.tiagoamaro.com.br/2014/12/11/multi-tenancy-with-searchkick/) on the [Apartment](https://github.com/influitive/apartment) gem. Follow a similar pattern if you use another gem.
|
1968
|
-
|
1969
|
-
## Upgrading
|
1970
|
-
|
1971
|
-
See [how to upgrade to Searchkick 3](docs/Searchkick-3-Upgrade.md)
|
1972
|
-
|
1973
1994
|
## Elasticsearch 6 to 7 Upgrade
|
1974
1995
|
|
1975
1996
|
1. Install Searchkick 4
|
1976
1997
|
2. Upgrade your Elasticsearch cluster
|
1977
1998
|
|
1978
|
-
## Elasticsearch 5 to 6 Upgrade
|
1979
|
-
|
1980
|
-
Elasticsearch 6 removes the ability to reindex with the `_all` field. Before you upgrade, we recommend disabling this field manually and specifying default fields on your models.
|
1981
|
-
|
1982
|
-
```ruby
|
1983
|
-
class Product < ApplicationRecord
|
1984
|
-
searchkick _all: false, default_fields: [:name]
|
1985
|
-
end
|
1986
|
-
```
|
1987
|
-
|
1988
|
-
If you need search across multiple fields, we recommend creating a similar field in your search data.
|
1989
|
-
|
1990
|
-
```ruby
|
1991
|
-
class Product < ApplicationRecord
|
1992
|
-
def search_data
|
1993
|
-
{
|
1994
|
-
all: [name, size, quantity].join(" ")
|
1995
|
-
}
|
1996
|
-
end
|
1997
|
-
end
|
1998
|
-
```
|
1999
|
-
|
2000
1999
|
## Elasticsearch Gotchas
|
2001
2000
|
|
2002
2001
|
### Consistency
|
@@ -2045,3 +2044,5 @@ cd searchkick
|
|
2045
2044
|
bundle install
|
2046
2045
|
bundle exec rake test
|
2047
2046
|
```
|
2047
|
+
|
2048
|
+
Feel free to open an issue to get feedback on your idea before spending too much time on it.
|