searchkick 4.4.0 → 4.5.0

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
  SHA256:
3
- metadata.gz: '0218ffe2be1e6fcebea56dfa7c8d112e2f43580d69b513d064f48c4905c51934'
4
- data.tar.gz: 79b21178f3db14d84179aa3db7cbf5dae4d7adfa98a9a72e7f92991c9bff2ce0
3
+ metadata.gz: 62e2797b9ad2290378febadeaab675b745b0318cd86a8219cada4774b529e290
4
+ data.tar.gz: 8f0956287e802ce93a67940f6283f914b58b38aee2240f3ef101ae08e7428966
5
5
  SHA512:
6
- metadata.gz: ce5ec190b6d754210ce88f48197cc0c08a32b6d33cc9a904385613ae3ec5bd7490a1d6c711bcf6cd3645636d64fe0c7e91bc23e009a32416194c8fbbe0119956
7
- data.tar.gz: 3b306480292cfbcdc5854cc491f3700ecfd88715d37f879aa5715f0782ac86f380aa4828bec2866d2ea74186e445b9d4380d4696c8c2abcf1404207afa8ede18
6
+ metadata.gz: 34a3bf2400766d7a2e95c3ba430a42c08dc1cfeb6c2d26b4d6d2a04828fd5ee296f3b121b076f00502f7c0c849ff27e1e622635a70885ef7f1336f0b4b8709de
7
+ data.tar.gz: 1c190e32fa87aa03a025a349dfc200ced4c28069c524acaa7b3c220628c58b9da2742ae4c924a87bc354f920a7486cae176d2bd7078a72a98568a068b20df290
data/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ ## 4.5.0 (2021-06-07)
2
+
3
+ - Added experimental support for OpenSearch
4
+ - Added support for synonyms in Japanese
5
+
6
+ ## 4.4.4 (2021-03-12)
7
+
8
+ - Fixed `too_long_frame_exception` with `scroll` method
9
+ - Fixed multi-word emoji tokenization
10
+
11
+ ## 4.4.3 (2021-02-25)
12
+
13
+ - Added support for Hunspell
14
+ - Fixed warning about accessing system indices
15
+
16
+ ## 4.4.2 (2020-11-23)
17
+
18
+ - Added `missing_records` method to results
19
+ - Fixed issue with `like` and special characters
20
+
21
+ ## 4.4.1 (2020-06-24)
22
+
23
+ - Added `stem_exclusion` and `stemmer_override` options
24
+ - Added `with_score` method to search results
25
+ - Improved error message for `reload_synonyms` with non-OSS version of Elasticsearch
26
+ - Improved output for reindex rake task
27
+
1
28
  ## 4.4.0 (2020-06-17)
2
29
 
3
30
  - Added support for reloadable, multi-word, search time synonyms
@@ -59,6 +86,7 @@ Breaking changes
59
86
 
60
87
  - Removed support for Elasticsearch 5
61
88
  - Removed support for multi-word synonyms (they no longer work with shingles)
89
+ - Removed support for Active Record < 5
62
90
 
63
91
  ## 3.1.3 (2019-04-11)
64
92
 
@@ -125,7 +153,7 @@ Breaking changes
125
153
  Breaking changes
126
154
 
127
155
  - Removed support for Elasticsearch 2
128
- - Removed support for ActiveRecord < 4.2 and Mongoid < 5
156
+ - Removed support for Active Record < 4.2 and Mongoid < 5
129
157
  - Types are no longer used
130
158
  - The `_all` field is disabled by default in Elasticsearch 5
131
159
  - Conversions are not stemmed by default
@@ -430,7 +458,7 @@ Breaking changes
430
458
 
431
459
  ## 0.8.3 (2014-09-20)
432
460
 
433
- - Added support for ActiveJob
461
+ - Added support for Active Job
434
462
  - Added `timeout` setting
435
463
  - Fixed import with no records
436
464
 
@@ -537,7 +565,7 @@ Breaking changes
537
565
 
538
566
  ## 0.5.2 (2014-02-12)
539
567
 
540
- - Use after_commit hook for ActiveRecord to prevent data inconsistencies
568
+ - Use after_commit hook for Active Record to prevent data inconsistencies
541
569
 
542
570
  ## 0.5.1 (2014-02-12)
543
571
 
data/README.md CHANGED
@@ -22,24 +22,26 @@ Plus:
22
22
  - supports many languages
23
23
  - works with ActiveRecord, Mongoid, and NoBrainer
24
24
 
25
- :tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
25
+ Check out [Searchjoy](https://github.com/ankane/searchjoy) for analytics and [Autosuggest](https://github.com/ankane/autosuggest) for query suggestions
26
26
 
27
- :speech_balloon: Get [handcrafted updates](https://chartkick.us7.list-manage.com/subscribe?u=952c861f99eb43084e0a49f98&id=6ea6541e8e&group[0][4]=true) for new features
27
+ :tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
28
28
 
29
- [![Build Status](https://travis-ci.org/ankane/searchkick.svg?branch=master)](https://travis-ci.org/ankane/searchkick)
29
+ [![Build Status](https://github.com/ankane/searchkick/workflows/build/badge.svg?branch=master)](https://github.com/ankane/searchkick/actions)
30
30
 
31
31
  ## Contents
32
32
 
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
- - [Testing](#testing)
44
+ - [Contributing](#contributing)
43
45
 
44
46
  ## Getting Started
45
47
 
@@ -174,7 +176,7 @@ Get the full response from Elasticsearch
174
176
  results.response
175
177
  ```
176
178
 
177
- **Note:** By default, Elasticsearch [limits paging](#deep-paging-master) to the first 10,000 results for performance. With Elasticsearch 7, this applies to the total count as well.
179
+ **Note:** By default, Elasticsearch [limits paging](#deep-paging) to the first 10,000 results for performance. With Elasticsearch 7, this applies to the total count as well.
178
180
 
179
181
  ### Boosting
180
182
 
@@ -207,7 +209,7 @@ boost_by_recency: {created_at: {scale: "7d", decay: 0.5}}
207
209
 
208
210
  You can also boost by:
209
211
 
210
- - [Conversions](#keep-getting-better)
212
+ - [Conversions](#intelligent-search)
211
213
  - [Distance](#boost-by-distance)
212
214
 
213
215
  ### Get Everything
@@ -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
- [See the list of stemmers](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-stemmer-tokenfilter.html)
311
-
312
- A few languages require plugins:
314
+ See the [list of languages](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-stemmer-tokenfilter.html#analysis-stemmer-tokenfilter-configure-parms). 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,38 @@ 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
+ You can also use a Hunspell dictionary for stemming.
326
+
327
+ ```ruby
328
+ class Product < ApplicationRecord
329
+ searchkick stemmer: {type: "hunspell", locale: "en_US"}
330
+ end
331
+ ```
332
+
333
+ Disable stemming with:
334
+
335
+ ```ruby
336
+ class Image < ApplicationRecord
337
+ searchkick stem: false
338
+ end
339
+ ```
340
+
341
+ Exclude certain words from stemming with:
342
+
343
+ ```ruby
344
+ class Image < ApplicationRecord
345
+ searchkick stem_exclusion: ["apples"]
346
+ end
347
+ ```
348
+
349
+ Or change how words are stemmed:
350
+
351
+ ```ruby
352
+ class Image < ApplicationRecord
353
+ searchkick stemmer_override: ["apples => other"]
354
+ end
355
+ ```
356
+
323
357
  ### Synonyms
324
358
 
325
359
  ```ruby
@@ -333,7 +367,7 @@ Call `Product.reindex` after changing synonyms. Synonyms are applied at search t
333
367
  For directional synonyms, use:
334
368
 
335
369
  ```ruby
336
- synonyms: ["lightbulb => halogenlamp"]
370
+ search_synonyms: ["lightbulb => halogenlamp"]
337
371
  ```
338
372
 
339
373
  ### Dynamic Synonyms
@@ -358,7 +392,7 @@ search_synonyms: "synonyms.txt"
358
392
  Add [elasticsearch-xpack](https://github.com/elastic/elasticsearch-ruby/tree/master/elasticsearch-xpack) to your Gemfile:
359
393
 
360
394
  ```ruby
361
- gem 'elasticsearch-xpack', '>= 7.8.0.pre'
395
+ gem 'elasticsearch-xpack', '>= 7.8.0'
362
396
  ```
363
397
 
364
398
  And use:
@@ -521,7 +555,7 @@ For large data sets, try [parallel reindexing](#parallel-reindexing).
521
555
 
522
556
  - app starts
523
557
 
524
- ### Stay Synced
558
+ ### Strategies
525
559
 
526
560
  There are four strategies for keeping the index synced with your database.
527
561
 
@@ -587,11 +621,9 @@ class Image < ApplicationRecord
587
621
  end
588
622
  ```
589
623
 
590
- ### Analytics
591
-
592
- The best starting point to improve your search **by far** is to track searches and conversions.
624
+ ## Intelligent Search
593
625
 
594
- [Searchjoy](https://github.com/ankane/searchjoy) makes it easy.
626
+ 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
627
 
596
628
  ```ruby
597
629
  Product.search "apple", track: {user_id: current_user.id}
@@ -604,15 +636,9 @@ Focus on:
604
636
  - top searches with low conversions
605
637
  - top searches with no results
606
638
 
607
- ### Keep Getting Better
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.
610
-
611
- The first step is to define your conversion metric and start tracking conversions. The database works well for low volume, but feel free to use Redis or another datastore.
612
-
613
- Searchkick automatically treats `apple` and `APPLE` the same.
639
+ 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.
614
640
 
615
- Next, add conversions to the index.
641
+ Add conversion data with:
616
642
 
617
643
  ```ruby
618
644
  class Product < ApplicationRecord
@@ -636,9 +662,11 @@ Reindex and set up a cron job to add new conversions daily.
636
662
  rake searchkick:reindex CLASS=Product
637
663
  ```
638
664
 
639
- **Note:** For a more performant (but more advanced) approach, check out [performant conversions](#performant-conversions).
665
+ This can make a huge difference on the quality of your search.
640
666
 
641
- ### Personalized Results
667
+ For a more performant way to reindex conversion data, check out [performant conversions](#performant-conversions).
668
+
669
+ ## Personalized Results
642
670
 
643
671
  Order results differently for each user. For example, show a user’s previously purchased products before other results.
644
672
 
@@ -659,7 +687,7 @@ Reindex and search with:
659
687
  Product.search "milk", boost_where: {orderer_ids: current_user.id}
660
688
  ```
661
689
 
662
- ### Instant Search / Autocomplete
690
+ ## Instant Search / Autocomplete
663
691
 
664
692
  Autocomplete predicts what a user will type, making the search experience faster and easier.
665
693
 
@@ -727,7 +755,7 @@ Then add the search box and JavaScript code to a view.
727
755
  </script>
728
756
  ```
729
757
 
730
- ### Suggestions
758
+ ## Suggestions
731
759
 
732
760
  ![Suggest](https://gist.github.com/ankane/b6988db2802aca68a589b31e41b44195/raw/40febe948427e5bc53ec4e5dc248822855fef76f/recursion.png)
733
761
 
@@ -744,7 +772,7 @@ products = Product.search "peantu butta", suggest: true
744
772
  products.suggestions # ["peanut butter"]
745
773
  ```
746
774
 
747
- ### Aggregations
775
+ ## Aggregations
748
776
 
749
777
  [Aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html) provide aggregated search data.
750
778
 
@@ -817,10 +845,10 @@ Product.search "pear", aggs: {products_per_year: {date_histogram: {field: :creat
817
845
  For other aggregation types, including sub-aggregations, use `body_options`:
818
846
 
819
847
  ```ruby
820
- Product.search "orange", body_options: {aggs: {price: {histogram: {field: :price, interval: 10}}}
848
+ Product.search "orange", body_options: {aggs: {price: {histogram: {field: :price, interval: 10}}}}
821
849
  ```
822
850
 
823
- ### Highlight
851
+ ## Highlight
824
852
 
825
853
  Specify which fields to index with highlighting.
826
854
 
@@ -873,7 +901,7 @@ Band.search "cinema", fields: [:name], highlight: {fields: {name: {fragment_size
873
901
 
874
902
  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
903
 
876
- ### Similar Items
904
+ ## Similar Items
877
905
 
878
906
  Find similar items.
879
907
 
@@ -882,7 +910,7 @@ product = Product.first
882
910
  product.similar(fields: [:name], where: {size: "12 oz"})
883
911
  ```
884
912
 
885
- ### Geospatial Searches
913
+ ## Geospatial Searches
886
914
 
887
915
  ```ruby
888
916
  class Restaurant < ApplicationRecord
@@ -1049,10 +1077,170 @@ Product.search_index.tokens("dieg", analyzer: "searchkick_word_search")
1049
1077
 
1050
1078
  See the [complete list of analyzers](https://github.com/ankane/searchkick/blob/31780ddac7a89eab1e0552a32b403f2040a37931/lib/searchkick/index_options.rb#L32).
1051
1079
 
1080
+ ## Testing
1081
+
1082
+ As you iterate on your search, it’s a good idea to add tests.
1083
+
1084
+ For performance, only enable Searchkick callbacks for the tests that need it.
1085
+
1086
+ ### Parallel Tests
1087
+
1088
+ Rails 6 enables parallel tests by default. Add to your `test/test_helper.rb`:
1089
+
1090
+ ```ruby
1091
+ class ActiveSupport::TestCase
1092
+ parallelize_setup do |worker|
1093
+ Searchkick.index_suffix = worker
1094
+
1095
+ # reindex models
1096
+ Product.reindex
1097
+
1098
+ # and disable callbacks
1099
+ Searchkick.disable_callbacks
1100
+ end
1101
+ end
1102
+ ```
1103
+
1104
+ And use:
1105
+
1106
+ ```ruby
1107
+ class ProductTest < ActiveSupport::TestCase
1108
+ def setup
1109
+ Searchkick.enable_callbacks
1110
+ end
1111
+
1112
+ def teardown
1113
+ Searchkick.disable_callbacks
1114
+ end
1115
+
1116
+ def test_search
1117
+ Product.create!(name: "Apple")
1118
+ Product.search_index.refresh
1119
+ assert_equal ["Apple"], Product.search("apple").map(&:name)
1120
+ end
1121
+ end
1122
+ ```
1123
+
1124
+ ### Minitest
1125
+
1126
+ Add to your `test/test_helper.rb`:
1127
+
1128
+ ```ruby
1129
+ # reindex models
1130
+ Product.reindex
1131
+
1132
+ # and disable callbacks
1133
+ Searchkick.disable_callbacks
1134
+ ```
1135
+
1136
+ And use:
1137
+
1138
+ ```ruby
1139
+ class ProductTest < Minitest::Test
1140
+ def setup
1141
+ Searchkick.enable_callbacks
1142
+ end
1143
+
1144
+ def teardown
1145
+ Searchkick.disable_callbacks
1146
+ end
1147
+
1148
+ def test_search
1149
+ Product.create!(name: "Apple")
1150
+ Product.search_index.refresh
1151
+ assert_equal ["Apple"], Product.search("apple").map(&:name)
1152
+ end
1153
+ end
1154
+ ```
1155
+
1156
+ ### RSpec
1157
+
1158
+ Add to your `spec/spec_helper.rb`:
1159
+
1160
+ ```ruby
1161
+ RSpec.configure do |config|
1162
+ config.before(:suite) do
1163
+ # reindex models
1164
+ Product.reindex
1165
+
1166
+ # and disable callbacks
1167
+ Searchkick.disable_callbacks
1168
+ end
1169
+
1170
+ config.around(:each, search: true) do |example|
1171
+ Searchkick.callbacks(nil) do
1172
+ example.run
1173
+ end
1174
+ end
1175
+ end
1176
+ ```
1177
+
1178
+ And use:
1179
+
1180
+ ```ruby
1181
+ describe Product, search: true do
1182
+ it "searches" do
1183
+ Product.create!(name: "Apple")
1184
+ Product.search_index.refresh
1185
+ assert_equal ["Apple"], Product.search("apple").map(&:name)
1186
+ end
1187
+ end
1188
+ ```
1189
+
1190
+ ### Factory Bot
1191
+
1192
+ Use a trait and an after `create` hook for each indexed model:
1193
+
1194
+ ```ruby
1195
+ FactoryBot.define do
1196
+ factory :product do
1197
+ # ...
1198
+
1199
+ # Note: This should be the last trait in the list so `reindex` is called
1200
+ # after all the other callbacks complete.
1201
+ trait :reindex do
1202
+ after(:create) do |product, _evaluator|
1203
+ product.reindex(refresh: true)
1204
+ end
1205
+ end
1206
+ end
1207
+ end
1208
+
1209
+ # use it
1210
+ FactoryBot.create(:product, :some_trait, :reindex, some_attribute: "foo")
1211
+ ```
1212
+
1213
+ ### GitHub Actions
1214
+
1215
+ Check out [setup-elasticsearch](https://github.com/ankane/setup-elasticsearch) for an easy way to install Elasticsearch.
1216
+
1217
+ ```yml
1218
+ - uses: ankane/setup-elasticsearch@v1
1219
+ ```
1220
+
1052
1221
  ## Deployment
1053
1222
 
1054
1223
  Searchkick uses `ENV["ELASTICSEARCH_URL"]` for the Elasticsearch server. This defaults to `http://localhost:9200`.
1055
1224
 
1225
+ - [Elastic Cloud](#elastic-cloud)
1226
+ - [Heroku](#heroku)
1227
+ - [Amazon Elasticsearch Service](#amazon-elasticsearch-service)
1228
+ - [Self-Hosted and Other](#self-hosted-and-other)
1229
+
1230
+ ### Elastic Cloud
1231
+
1232
+ Create an initializer `config/initializers/elasticsearch.rb` with:
1233
+
1234
+ ```ruby
1235
+ ENV["ELASTICSEARCH_URL"] = "https://user:password@host:port"
1236
+ ```
1237
+
1238
+ Then deploy and reindex:
1239
+
1240
+ ```sh
1241
+ rake searchkick:reindex:all
1242
+ ```
1243
+
1056
1244
  ### Heroku
1057
1245
 
1058
1246
  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 +1281,7 @@ heroku config:set ELASTICSEARCH_URL=https://elastic:password@12345.us-east-1.aws
1093
1281
  Then deploy and reindex:
1094
1282
 
1095
1283
  ```sh
1096
- heroku run rake searchkick:reindex CLASS=Product
1284
+ heroku run rake searchkick:reindex:all
1097
1285
  ```
1098
1286
 
1099
1287
  ### Amazon Elasticsearch Service
@@ -1123,10 +1311,10 @@ Searchkick.aws_credentials = {
1123
1311
  Then deploy and reindex:
1124
1312
 
1125
1313
  ```sh
1126
- rake searchkick:reindex CLASS=Product
1314
+ rake searchkick:reindex:all
1127
1315
  ```
1128
1316
 
1129
- ### Other
1317
+ ### Self-Hosted and Other
1130
1318
 
1131
1319
  Create an initializer `config/initializers/elasticsearch.rb` with:
1132
1320
 
@@ -1137,7 +1325,7 @@ ENV["ELASTICSEARCH_URL"] = "https://user:password@host:port"
1137
1325
  Then deploy and reindex:
1138
1326
 
1139
1327
  ```sh
1140
- rake searchkick:reindex CLASS=Product
1328
+ rake searchkick:reindex:all
1141
1329
  ```
1142
1330
 
1143
1331
  ### Data Protection
@@ -1289,7 +1477,7 @@ Product.search_index.promote(index_name, update_refresh_interval: true)
1289
1477
 
1290
1478
  ### Queuing
1291
1479
 
1292
- Push ids of records needing reindexed to a queue and reindex in bulk for better performance. First, set up Redis in an initializer. We recommend using [connection_pool](https://github.com/mperham/connection_pool).
1480
+ Push ids of records needing reindexing to a queue and reindex in bulk for better performance. First, set up Redis in an initializer. We recommend using [connection_pool](https://github.com/mperham/connection_pool).
1293
1481
 
1294
1482
  ```ruby
1295
1483
  Searchkick.redis = ConnectionPool.new { Redis.new }
@@ -1517,6 +1705,10 @@ Boost specific models with:
1517
1705
  indices_boost: {Category => 2, Product => 1}
1518
1706
  ```
1519
1707
 
1708
+ ## Multi-Tenancy
1709
+
1710
+ 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.
1711
+
1520
1712
  ## Scroll API
1521
1713
 
1522
1714
  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 +1915,6 @@ class Product < ApplicationRecord
1723
1915
  end
1724
1916
  ```
1725
1917
 
1726
- Turn off stemming
1727
-
1728
- ```ruby
1729
- class Product < ApplicationRecord
1730
- searchkick stem: false
1731
- end
1732
- ```
1733
-
1734
1918
  Turn on stemming for conversions
1735
1919
 
1736
1920
  ```ruby
@@ -1739,14 +1923,6 @@ class Product < ApplicationRecord
1739
1923
  end
1740
1924
  ```
1741
1925
 
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
1926
  Make search case-sensitive
1751
1927
 
1752
1928
  ```ruby
@@ -1831,172 +2007,11 @@ Product.search "api", misspellings: {prefix_length: 2} # api, apt, no ahi
1831
2007
  Product.search "ah", misspellings: {prefix_length: 2} # ah, no aha
1832
2008
  ```
1833
2009
 
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
2010
  ## Elasticsearch 6 to 7 Upgrade
1974
2011
 
1975
2012
  1. Install Searchkick 4
1976
2013
  2. Upgrade your Elasticsearch cluster
1977
2014
 
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
2015
  ## Elasticsearch Gotchas
2001
2016
 
2002
2017
  ### Consistency
@@ -2045,3 +2060,5 @@ cd searchkick
2045
2060
  bundle install
2046
2061
  bundle exec rake test
2047
2062
  ```
2063
+
2064
+ Feel free to open an issue to get feedback on your idea before spending too much time on it.