searchkick 4.2.0 → 4.4.1

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: '0529381ceedcb4630640d4ae37b02ac2e950c3088a757946b930e56e0a8d4591'
4
- data.tar.gz: 539ee2b8da1632f5b86ff3da063e5b815fac2ba3edb5efc2b3d2d508cdb9c002
3
+ metadata.gz: ff49d45a4473f44b07e8f1654d47e9b0590fd71eb3c6567f62b2fbcdc1e837b9
4
+ data.tar.gz: fd6ac4c931c7250787bc6f905c6c72b8412355e6b505bb2ef9d8cf5731d2939d
5
5
  SHA512:
6
- metadata.gz: cfb0aa73064ee937db83d948086bf5f9f1a81bc597f871288786f18ddaff1f39edf202c3a877d4147c3e963c1a736130f4250e10238444924347dbf8854b15c0
7
- data.tar.gz: d4733742e12185d5f6296361948a20a2cc11ad14cf0f2c254cbcb80b5f5c64ba6754eb46161b22e33d786363a94b7e79db8b55d567e77ee8dc46ed3a9d7ab246
6
+ metadata.gz: 05630a20b302fd406e5545935861b6616db79e2dd12e2eb11fe82bb3733c8b21af1087b7ad8d0fd4bd93eb3a07d2bd67461815a293746a2d2c2d3f2148d7147b
7
+ data.tar.gz: 571528f3967fd921e92dda6413313d29bd9048ee832e44bdb1a31a297178c3ee2f0b31dead3c573b297da96b676fdd74467bd7aa514c6a97f2a38b2500901057
@@ -1,3 +1,29 @@
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
+
8
+ ## 4.4.0 (2020-06-17)
9
+
10
+ - Added support for reloadable, multi-word, search time synonyms
11
+ - Fixed another deprecation warning in Ruby 2.7
12
+
13
+ ## 4.3.1 (2020-05-13)
14
+
15
+ - Fixed error with `exclude` in certain cases for Elasticsearch 7.7
16
+
17
+ ## 4.3.0 (2020-02-19)
18
+
19
+ - Fixed `like` queries with `"` character
20
+ - Better error when invalid parameters passed to `where`
21
+
22
+ ## 4.2.1 (2020-01-27)
23
+
24
+ - Fixed deprecation warnings with Elasticsearch
25
+ - Fixed deprecation warnings in Ruby 2.7
26
+
1
27
  ## 4.2.0 (2019-12-18)
2
28
 
3
29
  - Added safety check for multiple `Model.reindex`
@@ -40,6 +66,7 @@ Breaking changes
40
66
 
41
67
  - Removed support for Elasticsearch 5
42
68
  - Removed support for multi-word synonyms (they no longer work with shingles)
69
+ - Removed support for Active Record < 5
43
70
 
44
71
  ## 3.1.3 (2019-04-11)
45
72
 
@@ -106,7 +133,7 @@ Breaking changes
106
133
  Breaking changes
107
134
 
108
135
  - Removed support for Elasticsearch 2
109
- - Removed support for ActiveRecord < 4.2 and Mongoid < 5
136
+ - Removed support for Active Record < 4.2 and Mongoid < 5
110
137
  - Types are no longer used
111
138
  - The `_all` field is disabled by default in Elasticsearch 5
112
139
  - Conversions are not stemmed by default
@@ -411,7 +438,7 @@ Breaking changes
411
438
 
412
439
  ## 0.8.3 (2014-09-20)
413
440
 
414
- - Added support for ActiveJob
441
+ - Added support for Active Job
415
442
  - Added `timeout` setting
416
443
  - Fixed import with no records
417
444
 
@@ -518,7 +545,7 @@ Breaking changes
518
545
 
519
546
  ## 0.5.2 (2014-02-12)
520
547
 
521
- - Use after_commit hook for ActiveRecord to prevent data inconsistencies
548
+ - Use after_commit hook for Active Record to prevent data inconsistencies
522
549
 
523
550
  ## 0.5.1 (2014-02-12)
524
551
 
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013-2019 Andrew Kane
1
+ Copyright (c) 2013-2020 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -4,12 +4,6 @@
4
4
 
5
5
  **Searchkick learns what your users are looking for.** As more people search, it gets smarter and the results get better. It’s friendly for developers - and magical for your users.
6
6
 
7
- ---
8
-
9
- [Searchkick Pro](https://searchkick.org/pro?utm_source=readme) is now available!
10
-
11
- ---
12
-
13
7
  Searchkick handles:
14
8
 
15
9
  - stemming - `tomatoes` matches `tomato`
@@ -39,17 +33,19 @@ Plus:
39
33
  - [Getting Started](#getting-started)
40
34
  - [Querying](#querying)
41
35
  - [Indexing](#indexing)
36
+ - [Intelligent Search](#intelligent-search)
42
37
  - [Instant Search / Autocomplete](#instant-search--autocomplete)
43
38
  - [Aggregations](#aggregations)
39
+ - [Testing](#testing)
44
40
  - [Deployment](#deployment)
45
41
  - [Performance](#performance)
46
42
  - [Elasticsearch DSL](#advanced)
47
43
  - [Reference](#reference)
48
- - [Testing](#testing)
44
+ - [Contributing](#contributing)
49
45
 
50
46
  ## Getting Started
51
47
 
52
- [Install Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/current/setup.html). For Homebrew, use:
48
+ [Install Elasticsearch](https://www.elastic.co/downloads/elasticsearch). For Homebrew, use:
53
49
 
54
50
  ```sh
55
51
  brew install elasticsearch
@@ -143,7 +139,7 @@ Select
143
139
  select: [:name]
144
140
  ```
145
141
 
146
- [These source filtering options are supported](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering.html)
142
+ [These source filtering options are supported](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#request-body-search-source-filtering)
147
143
 
148
144
  ### Results
149
145
 
@@ -303,7 +299,9 @@ To only match the exact order, use:
303
299
  User.search "fresh honey", match: :phrase
304
300
  ```
305
301
 
306
- ### 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.
307
305
 
308
306
  Searchkick defaults to English for stemming. To change this, use:
309
307
 
@@ -313,9 +311,7 @@ class Product < ApplicationRecord
313
311
  end
314
312
  ```
315
313
 
316
- [See the list of stemmers](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-stemmer-tokenfilter.html)
317
-
318
- 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:
319
315
 
320
316
  - `chinese` - [analysis-ik plugin](https://github.com/medcl/elasticsearch-analysis-ik)
321
317
  - `chinese2` - [analysis-smartcn plugin](https://www.elastic.co/guide/en/elasticsearch/plugins/7.4/analysis-smartcn.html)
@@ -326,33 +322,80 @@ A few languages require plugins:
326
322
  - `ukrainian` - [analysis-ukrainian plugin](https://www.elastic.co/guide/en/elasticsearch/plugins/7.4/analysis-ukrainian.html)
327
323
  - `vietnamese` - [analysis-vietnamese plugin](https://github.com/duydo/elasticsearch-analysis-vietnamese)
328
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
+
329
349
  ### Synonyms
330
350
 
331
351
  ```ruby
332
352
  class Product < ApplicationRecord
333
- searchkick synonyms: [["pop", "soda"], ["burger", "hamburger"]]
353
+ searchkick search_synonyms: [["pop", "soda"], ["burger", "hamburger"]]
334
354
  end
335
355
  ```
336
356
 
337
- Call `Product.reindex` after changing synonyms.
357
+ Call `Product.reindex` after changing synonyms. Synonyms are applied at search time before stemming, and can be a single word or multiple words.
358
+
359
+ For directional synonyms, use:
360
+
361
+ ```ruby
362
+ search_synonyms: ["lightbulb => halogenlamp"]
363
+ ```
364
+
365
+ ### Dynamic Synonyms
338
366
 
339
- Synonyms cannot be multiple words at the moment.
367
+ The above approach works well when your synonym list is static, but in practice, this is often not the case. When you analyze search conversions, you often want to add new synonyms without a full reindex.
340
368
 
341
- To read synonyms from a file, use:
369
+ #### Elasticsearch 7.3+
370
+
371
+ For Elasticsearch 7.3+, we recommend placing synonyms in a file on the Elasticsearch server (in the `config` directory). This allows you to reload synonyms without reindexing.
372
+
373
+ ```txt
374
+ pop, soda
375
+ burger, hamburger
376
+ ```
377
+
378
+ Then use:
342
379
 
343
380
  ```ruby
344
- synonyms: -> { CSV.read("/some/path/synonyms.csv") }
381
+ search_synonyms: "synonyms.txt"
345
382
  ```
346
383
 
347
- For directional synonyms, use:
384
+ Add [elasticsearch-xpack](https://github.com/elastic/elasticsearch-ruby/tree/master/elasticsearch-xpack) to your Gemfile:
385
+
386
+ ```ruby
387
+ gem 'elasticsearch-xpack', '>= 7.8.0'
388
+ ```
389
+
390
+ And use:
348
391
 
349
392
  ```ruby
350
- synonyms: ["lightbulb => halogenlamp"]
393
+ Product.search_index.reload_synonyms
351
394
  ```
352
395
 
353
- ### Tags and Dynamic Synonyms
396
+ #### Elasticsearch < 7.3
354
397
 
355
- The above approach works well when your synonym list is static, but in practice, this is often not the case. When you analyze search conversions, you often want to add new synonyms or tags without a full reindex. You can use a library like [ActsAsTaggableOn](https://github.com/mbleigh/acts-as-taggable-on) and do:
398
+ You can use a library like [ActsAsTaggableOn](https://github.com/mbleigh/acts-as-taggable-on) and do:
356
399
 
357
400
  ```ruby
358
401
  class Product < ApplicationRecord
@@ -504,7 +547,7 @@ For large data sets, try [parallel reindexing](#parallel-reindexing).
504
547
 
505
548
  - app starts
506
549
 
507
- ### Stay Synced
550
+ ### Strategies
508
551
 
509
552
  There are four strategies for keeping the index synced with your database.
510
553
 
@@ -570,11 +613,9 @@ class Image < ApplicationRecord
570
613
  end
571
614
  ```
572
615
 
573
- ### Analytics
616
+ ## Intelligent Search
574
617
 
575
- The best starting point to improve your search **by far** is to track searches and conversions.
576
-
577
- [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.
578
619
 
579
620
  ```ruby
580
621
  Product.search "apple", track: {user_id: current_user.id}
@@ -587,15 +628,9 @@ Focus on:
587
628
  - top searches with low conversions
588
629
  - top searches with no results
589
630
 
590
- ### Keep Getting Better
591
-
592
- 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.
593
-
594
- 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.
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.
595
632
 
596
- Searchkick automatically treats `apple` and `APPLE` the same.
597
-
598
- Next, add conversions to the index.
633
+ Add conversion data with:
599
634
 
600
635
  ```ruby
601
636
  class Product < ApplicationRecord
@@ -619,9 +654,11 @@ Reindex and set up a cron job to add new conversions daily.
619
654
  rake searchkick:reindex CLASS=Product
620
655
  ```
621
656
 
622
- **Note:** For a more performant (but more advanced) approach, check out [performant conversions](#performant-conversions).
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).
623
660
 
624
- ### Personalized Results
661
+ ## Personalized Results
625
662
 
626
663
  Order results differently for each user. For example, show a user’s previously purchased products before other results.
627
664
 
@@ -642,7 +679,7 @@ Reindex and search with:
642
679
  Product.search "milk", boost_where: {orderer_ids: current_user.id}
643
680
  ```
644
681
 
645
- ### Instant Search / Autocomplete
682
+ ## Instant Search / Autocomplete
646
683
 
647
684
  Autocomplete predicts what a user will type, making the search experience faster and easier.
648
685
 
@@ -710,7 +747,7 @@ Then add the search box and JavaScript code to a view.
710
747
  </script>
711
748
  ```
712
749
 
713
- ### Suggestions
750
+ ## Suggestions
714
751
 
715
752
  ![Suggest](https://gist.github.com/ankane/b6988db2802aca68a589b31e41b44195/raw/40febe948427e5bc53ec4e5dc248822855fef76f/recursion.png)
716
753
 
@@ -727,7 +764,7 @@ products = Product.search "peantu butta", suggest: true
727
764
  products.suggestions # ["peanut butter"]
728
765
  ```
729
766
 
730
- ### Aggregations
767
+ ## Aggregations
731
768
 
732
769
  [Aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html) provide aggregated search data.
733
770
 
@@ -770,8 +807,6 @@ Order
770
807
  Product.search "wingtips", aggs: {color: {order: {"_key" => "asc"}}} # alphabetically
771
808
  ```
772
809
 
773
- **Note:** Use `_term` instead of `_key` in Elasticsearch 5
774
-
775
810
  [All of these options are supported](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#search-aggregations-bucket-terms-aggregation-order)
776
811
 
777
812
  Ranges
@@ -802,10 +837,10 @@ Product.search "pear", aggs: {products_per_year: {date_histogram: {field: :creat
802
837
  For other aggregation types, including sub-aggregations, use `body_options`:
803
838
 
804
839
  ```ruby
805
- 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}}}}
806
841
  ```
807
842
 
808
- ### Highlight
843
+ ## Highlight
809
844
 
810
845
  Specify which fields to index with highlighting.
811
846
 
@@ -858,7 +893,7 @@ Band.search "cinema", fields: [:name], highlight: {fields: {name: {fragment_size
858
893
 
859
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).
860
895
 
861
- ### Similar Items
896
+ ## Similar Items
862
897
 
863
898
  Find similar items.
864
899
 
@@ -867,7 +902,7 @@ product = Product.first
867
902
  product.similar(fields: [:name], where: {size: "12 oz"})
868
903
  ```
869
904
 
870
- ### Geospatial Searches
905
+ ## Geospatial Searches
871
906
 
872
907
  ```ruby
873
908
  class Restaurant < ApplicationRecord
@@ -1034,13 +1069,165 @@ Product.search_index.tokens("dieg", analyzer: "searchkick_word_search")
1034
1069
 
1035
1070
  See the [complete list of analyzers](https://github.com/ankane/searchkick/blob/31780ddac7a89eab1e0552a32b403f2040a37931/lib/searchkick/index_options.rb#L32).
1036
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
+
1037
1205
  ## Deployment
1038
1206
 
1039
1207
  Searchkick uses `ENV["ELASTICSEARCH_URL"]` for the Elasticsearch server. This defaults to `http://localhost:9200`.
1040
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
+
1041
1228
  ### Heroku
1042
1229
 
1043
- Choose an add-on: [Bonsai](https://elements.heroku.com/addons/bonsai) or [Elastic Cloud](https://elements.heroku.com/addons/foundelasticsearch). [SearchBox](https://elements.heroku.com/addons/searchbox) does not work at the moment.
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).
1044
1231
 
1045
1232
  For Bonsai:
1046
1233
 
@@ -1049,6 +1236,13 @@ heroku addons:create bonsai
1049
1236
  heroku config:set ELASTICSEARCH_URL=`heroku config:get BONSAI_URL`
1050
1237
  ```
1051
1238
 
1239
+ For SearchBox:
1240
+
1241
+ ```sh
1242
+ heroku addons:create searchbox:starter
1243
+ heroku config:set ELASTICSEARCH_URL=`heroku config:get SEARCHBOX_URL`
1244
+ ```
1245
+
1052
1246
  For Elastic Cloud (previously Found):
1053
1247
 
1054
1248
  ```sh
@@ -1071,7 +1265,7 @@ heroku config:set ELASTICSEARCH_URL=https://elastic:password@12345.us-east-1.aws
1071
1265
  Then deploy and reindex:
1072
1266
 
1073
1267
  ```sh
1074
- heroku run rake searchkick:reindex CLASS=Product
1268
+ heroku run rake searchkick:reindex:all
1075
1269
  ```
1076
1270
 
1077
1271
  ### Amazon Elasticsearch Service
@@ -1101,10 +1295,10 @@ Searchkick.aws_credentials = {
1101
1295
  Then deploy and reindex:
1102
1296
 
1103
1297
  ```sh
1104
- rake searchkick:reindex CLASS=Product
1298
+ rake searchkick:reindex:all
1105
1299
  ```
1106
1300
 
1107
- ### Other
1301
+ ### Self-Hosted and Other
1108
1302
 
1109
1303
  Create an initializer `config/initializers/elasticsearch.rb` with:
1110
1304
 
@@ -1115,7 +1309,7 @@ ENV["ELASTICSEARCH_URL"] = "https://user:password@host:port"
1115
1309
  Then deploy and reindex:
1116
1310
 
1117
1311
  ```sh
1118
- rake searchkick:reindex CLASS=Product
1312
+ rake searchkick:reindex:all
1119
1313
  ```
1120
1314
 
1121
1315
  ### Data Protection
@@ -1495,6 +1689,10 @@ Boost specific models with:
1495
1689
  indices_boost: {Category => 2, Product => 1}
1496
1690
  ```
1497
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
+
1498
1696
  ## Scroll API
1499
1697
 
1500
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.
@@ -1701,14 +1899,6 @@ class Product < ApplicationRecord
1701
1899
  end
1702
1900
  ```
1703
1901
 
1704
- Turn off stemming
1705
-
1706
- ```ruby
1707
- class Product < ApplicationRecord
1708
- searchkick stem: false
1709
- end
1710
- ```
1711
-
1712
1902
  Turn on stemming for conversions
1713
1903
 
1714
1904
  ```ruby
@@ -1717,14 +1907,6 @@ class Product < ApplicationRecord
1717
1907
  end
1718
1908
  ```
1719
1909
 
1720
- Use a different [similarity algorithm](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-similarity.html) for scoring
1721
-
1722
- ```ruby
1723
- class Product < ApplicationRecord
1724
- searchkick similarity: "classic"
1725
- end
1726
- ```
1727
-
1728
1910
  Make search case-sensitive
1729
1911
 
1730
1912
  ```ruby
@@ -1809,142 +1991,11 @@ Product.search "api", misspellings: {prefix_length: 2} # api, apt, no ahi
1809
1991
  Product.search "ah", misspellings: {prefix_length: 2} # ah, no aha
1810
1992
  ```
1811
1993
 
1812
- ## Testing
1813
-
1814
- For performance, only enable Searchkick callbacks for the tests that need it.
1815
-
1816
- ### Minitest
1817
-
1818
- Add to your `test/test_helper.rb`:
1819
-
1820
- ```ruby
1821
- # reindex models
1822
- Product.reindex
1823
-
1824
- # and disable callbacks
1825
- Searchkick.disable_callbacks
1826
- ```
1827
-
1828
- And use:
1829
-
1830
- ```ruby
1831
- class ProductTest < Minitest::Test
1832
- def setup
1833
- Searchkick.enable_callbacks
1834
- end
1835
-
1836
- def teardown
1837
- Searchkick.disable_callbacks
1838
- end
1839
-
1840
- def test_search
1841
- Product.create!(name: "Apple")
1842
- Product.search_index.refresh
1843
- assert_equal ["Apple"], Product.search("apple").map(&:name)
1844
- end
1845
- end
1846
- ```
1847
-
1848
- ### RSpec
1849
-
1850
- Add to your `spec/spec_helper.rb`:
1851
-
1852
- ```ruby
1853
- RSpec.configure do |config|
1854
- config.before(:suite) do
1855
- # reindex models
1856
- Product.reindex
1857
-
1858
- # and disable callbacks
1859
- Searchkick.disable_callbacks
1860
- end
1861
-
1862
- config.around(:each, search: true) do |example|
1863
- Searchkick.callbacks(true) do
1864
- example.run
1865
- end
1866
- end
1867
- end
1868
- ```
1869
-
1870
- And use:
1871
-
1872
- ```ruby
1873
- describe Product, search: true do
1874
- it "searches" do
1875
- Product.create!(name: "Apple")
1876
- Product.search_index.refresh
1877
- assert_equal ["Apple"], Product.search("apple").map(&:name)
1878
- end
1879
- end
1880
- ```
1881
-
1882
- ### Factory Bot
1883
-
1884
- Use a trait and an after `create` hook for each indexed model:
1885
-
1886
- ```ruby
1887
- FactoryBot.define do
1888
- factory :product do
1889
- # ...
1890
-
1891
- # Note: This should be the last trait in the list so `reindex` is called
1892
- # after all the other callbacks complete.
1893
- trait :reindex do
1894
- after(:create) do |product, _evaluator|
1895
- product.reindex(refresh: true)
1896
- end
1897
- end
1898
- end
1899
- end
1900
-
1901
- # use it
1902
- FactoryBot.create(:product, :some_trait, :reindex, some_attribute: "foo")
1903
- ```
1904
-
1905
- ### Parallel Tests
1906
-
1907
- Set:
1908
-
1909
- ```ruby
1910
- Searchkick.index_suffix = ENV["TEST_ENV_NUMBER"]
1911
- ```
1912
-
1913
- ## Multi-Tenancy
1914
-
1915
- 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.
1916
-
1917
- ## Upgrading
1918
-
1919
- See [how to upgrade to Searchkick 3](docs/Searchkick-3-Upgrade.md)
1920
-
1921
1994
  ## Elasticsearch 6 to 7 Upgrade
1922
1995
 
1923
1996
  1. Install Searchkick 4
1924
1997
  2. Upgrade your Elasticsearch cluster
1925
1998
 
1926
- ## Elasticsearch 5 to 6 Upgrade
1927
-
1928
- 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.
1929
-
1930
- ```ruby
1931
- class Product < ApplicationRecord
1932
- searchkick _all: false, default_fields: [:name]
1933
- end
1934
- ```
1935
-
1936
- If you need search across multiple fields, we recommend creating a similar field in your search data.
1937
-
1938
- ```ruby
1939
- class Product < ApplicationRecord
1940
- def search_data
1941
- {
1942
- all: [name, size, quantity].join(" ")
1943
- }
1944
- end
1945
- end
1946
- ```
1947
-
1948
1999
  ## Elasticsearch Gotchas
1949
2000
 
1950
2001
  ### Consistency
@@ -1985,13 +2036,13 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
1985
2036
  - Write, clarify, or fix documentation
1986
2037
  - Suggest or add new features
1987
2038
 
1988
- If you’re looking for ideas, [try here](https://github.com/ankane/searchkick/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22).
1989
-
1990
- To get started with development and testing:
2039
+ To get started with development:
1991
2040
 
1992
2041
  ```sh
1993
2042
  git clone https://github.com/ankane/searchkick.git
1994
2043
  cd searchkick
1995
2044
  bundle install
1996
- rake test
2045
+ bundle exec rake test
1997
2046
  ```
2047
+
2048
+ Feel free to open an issue to get feedback on your idea before spending too much time on it.