searchkick 4.2.1 → 4.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -3
- data/README.md +264 -199
- data/lib/searchkick.rb +30 -11
- data/lib/searchkick/bulk_indexer.rb +1 -1
- data/lib/searchkick/index.rb +22 -2
- data/lib/searchkick/index_options.rb +468 -382
- data/lib/searchkick/model.rb +8 -4
- data/lib/searchkick/query.rb +27 -5
- data/lib/searchkick/results.rb +101 -66
- data/lib/searchkick/version.rb +1 -1
- data/lib/tasks/searchkick.rake +12 -11
- metadata +7 -50
- 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: 782d732ce3dca45ba3654f3afa2ee565fc396543179dbdc87a0ee7418a151a3c
|
4
|
+
data.tar.gz: 2752fb40094f068a97e77009634fccf7a1433182294835ad077a66632d43bcb6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1125b09caaf20b0dcc8aa7c55755e257338499dda6d09427e139f9167d9e5b2e9971657b830352babe8100c510236412fbaa5a6edf9617c8eefcbe7aff4d2c7
|
7
|
+
data.tar.gz: b111187e5e1d05f19120f850833a491405727811fde6b31465f6021dffdd01b44e55c6e9a19b930246a4a92671ddda62aa65f9fa6fb6793342a5581009961985
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
## 4.4.2 (2020-11-23)
|
2
|
+
|
3
|
+
- Added `missing_records` method to results
|
4
|
+
- Fixed issue with `like` and special characters
|
5
|
+
|
6
|
+
## 4.4.1 (2020-06-24)
|
7
|
+
|
8
|
+
- Added `stem_exclusion` and `stemmer_override` options
|
9
|
+
- Added `with_score` method to search results
|
10
|
+
- Improved error message for `reload_synonyms` with non-OSS version of Elasticsearch
|
11
|
+
- Improved output for reindex rake task
|
12
|
+
|
13
|
+
## 4.4.0 (2020-06-17)
|
14
|
+
|
15
|
+
- Added support for reloadable, multi-word, search time synonyms
|
16
|
+
- Fixed another deprecation warning in Ruby 2.7
|
17
|
+
|
18
|
+
## 4.3.1 (2020-05-13)
|
19
|
+
|
20
|
+
- Fixed error with `exclude` in certain cases for Elasticsearch 7.7
|
21
|
+
|
22
|
+
## 4.3.0 (2020-02-19)
|
23
|
+
|
24
|
+
- Fixed `like` queries with `"` character
|
25
|
+
- Better error when invalid parameters passed to `where`
|
26
|
+
|
1
27
|
## 4.2.1 (2020-01-27)
|
2
28
|
|
3
29
|
- Fixed deprecation warnings with Elasticsearch
|
@@ -45,6 +71,7 @@ Breaking changes
|
|
45
71
|
|
46
72
|
- Removed support for Elasticsearch 5
|
47
73
|
- Removed support for multi-word synonyms (they no longer work with shingles)
|
74
|
+
- Removed support for Active Record < 5
|
48
75
|
|
49
76
|
## 3.1.3 (2019-04-11)
|
50
77
|
|
@@ -111,7 +138,7 @@ Breaking changes
|
|
111
138
|
Breaking changes
|
112
139
|
|
113
140
|
- Removed support for Elasticsearch 2
|
114
|
-
- Removed support for
|
141
|
+
- Removed support for Active Record < 4.2 and Mongoid < 5
|
115
142
|
- Types are no longer used
|
116
143
|
- The `_all` field is disabled by default in Elasticsearch 5
|
117
144
|
- Conversions are not stemmed by default
|
@@ -416,7 +443,7 @@ Breaking changes
|
|
416
443
|
|
417
444
|
## 0.8.3 (2014-09-20)
|
418
445
|
|
419
|
-
- Added support for
|
446
|
+
- Added support for Active Job
|
420
447
|
- Added `timeout` setting
|
421
448
|
- Fixed import with no records
|
422
449
|
|
@@ -523,7 +550,7 @@ Breaking changes
|
|
523
550
|
|
524
551
|
## 0.5.2 (2014-02-12)
|
525
552
|
|
526
|
-
- Use after_commit hook for
|
553
|
+
- Use after_commit hook for Active Record to prevent data inconsistencies
|
527
554
|
|
528
555
|
## 0.5.1 (2014-02-12)
|
529
556
|
|
data/README.md
CHANGED
@@ -22,28 +22,30 @@ Plus:
|
|
22
22
|
- supports many languages
|
23
23
|
- works with ActiveRecord, Mongoid, and NoBrainer
|
24
24
|
|
25
|
-
|
25
|
+
Check out [Searchjoy](https://github.com/ankane/searchjoy) for analytics and [Autosuggest](https://github.com/ankane/autosuggest) for query suggestions
|
26
26
|
|
27
|
-
:
|
27
|
+
:tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
|
28
28
|
|
29
|
-
[![Build Status](https://
|
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
|
-
- [
|
44
|
+
- [Contributing](#contributing)
|
43
45
|
|
44
46
|
## Getting Started
|
45
47
|
|
46
|
-
[Install Elasticsearch](https://www.elastic.co/
|
48
|
+
[Install Elasticsearch](https://www.elastic.co/downloads/elasticsearch). For Homebrew, use:
|
47
49
|
|
48
50
|
```sh
|
49
51
|
brew install elasticsearch
|
@@ -137,7 +139,7 @@ Select
|
|
137
139
|
select: [:name]
|
138
140
|
```
|
139
141
|
|
140
|
-
[These source filtering options are supported](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering
|
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)
|
141
143
|
|
142
144
|
### Results
|
143
145
|
|
@@ -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,33 +322,80 @@ 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
|
326
352
|
class Product < ApplicationRecord
|
327
|
-
searchkick
|
353
|
+
searchkick search_synonyms: [["pop", "soda"], ["burger", "hamburger"]]
|
328
354
|
end
|
329
355
|
```
|
330
356
|
|
331
|
-
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.
|
332
358
|
|
333
|
-
|
359
|
+
For directional synonyms, use:
|
334
360
|
|
335
|
-
|
361
|
+
```ruby
|
362
|
+
search_synonyms: ["lightbulb => halogenlamp"]
|
363
|
+
```
|
364
|
+
|
365
|
+
### Dynamic Synonyms
|
366
|
+
|
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.
|
368
|
+
|
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:
|
336
379
|
|
337
380
|
```ruby
|
338
|
-
|
381
|
+
search_synonyms: "synonyms.txt"
|
339
382
|
```
|
340
383
|
|
341
|
-
|
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:
|
342
391
|
|
343
392
|
```ruby
|
344
|
-
|
393
|
+
Product.search_index.reload_synonyms
|
345
394
|
```
|
346
395
|
|
347
|
-
|
396
|
+
#### Elasticsearch < 7.3
|
348
397
|
|
349
|
-
|
398
|
+
You can use a library like [ActsAsTaggableOn](https://github.com/mbleigh/acts-as-taggable-on) and do:
|
350
399
|
|
351
400
|
```ruby
|
352
401
|
class Product < ApplicationRecord
|
@@ -498,7 +547,7 @@ For large data sets, try [parallel reindexing](#parallel-reindexing).
|
|
498
547
|
|
499
548
|
- app starts
|
500
549
|
|
501
|
-
###
|
550
|
+
### Strategies
|
502
551
|
|
503
552
|
There are four strategies for keeping the index synced with your database.
|
504
553
|
|
@@ -564,11 +613,9 @@ class Image < ApplicationRecord
|
|
564
613
|
end
|
565
614
|
```
|
566
615
|
|
567
|
-
|
616
|
+
## Intelligent Search
|
568
617
|
|
569
|
-
The best starting point to improve your search **by far** is to track searches and conversions.
|
570
|
-
|
571
|
-
[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.
|
572
619
|
|
573
620
|
```ruby
|
574
621
|
Product.search "apple", track: {user_id: current_user.id}
|
@@ -581,15 +628,9 @@ Focus on:
|
|
581
628
|
- top searches with low conversions
|
582
629
|
- top searches with no results
|
583
630
|
|
584
|
-
|
585
|
-
|
586
|
-
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.
|
587
632
|
|
588
|
-
|
589
|
-
|
590
|
-
Searchkick automatically treats `apple` and `APPLE` the same.
|
591
|
-
|
592
|
-
Next, add conversions to the index.
|
633
|
+
Add conversion data with:
|
593
634
|
|
594
635
|
```ruby
|
595
636
|
class Product < ApplicationRecord
|
@@ -613,9 +654,11 @@ Reindex and set up a cron job to add new conversions daily.
|
|
613
654
|
rake searchkick:reindex CLASS=Product
|
614
655
|
```
|
615
656
|
|
616
|
-
|
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).
|
617
660
|
|
618
|
-
|
661
|
+
## Personalized Results
|
619
662
|
|
620
663
|
Order results differently for each user. For example, show a user’s previously purchased products before other results.
|
621
664
|
|
@@ -636,7 +679,7 @@ Reindex and search with:
|
|
636
679
|
Product.search "milk", boost_where: {orderer_ids: current_user.id}
|
637
680
|
```
|
638
681
|
|
639
|
-
|
682
|
+
## Instant Search / Autocomplete
|
640
683
|
|
641
684
|
Autocomplete predicts what a user will type, making the search experience faster and easier.
|
642
685
|
|
@@ -704,7 +747,7 @@ Then add the search box and JavaScript code to a view.
|
|
704
747
|
</script>
|
705
748
|
```
|
706
749
|
|
707
|
-
|
750
|
+
## Suggestions
|
708
751
|
|
709
752
|
![Suggest](https://gist.github.com/ankane/b6988db2802aca68a589b31e41b44195/raw/40febe948427e5bc53ec4e5dc248822855fef76f/recursion.png)
|
710
753
|
|
@@ -721,7 +764,7 @@ products = Product.search "peantu butta", suggest: true
|
|
721
764
|
products.suggestions # ["peanut butter"]
|
722
765
|
```
|
723
766
|
|
724
|
-
|
767
|
+
## Aggregations
|
725
768
|
|
726
769
|
[Aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html) provide aggregated search data.
|
727
770
|
|
@@ -764,8 +807,6 @@ Order
|
|
764
807
|
Product.search "wingtips", aggs: {color: {order: {"_key" => "asc"}}} # alphabetically
|
765
808
|
```
|
766
809
|
|
767
|
-
**Note:** Use `_term` instead of `_key` in Elasticsearch 5
|
768
|
-
|
769
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)
|
770
811
|
|
771
812
|
Ranges
|
@@ -796,10 +837,10 @@ Product.search "pear", aggs: {products_per_year: {date_histogram: {field: :creat
|
|
796
837
|
For other aggregation types, including sub-aggregations, use `body_options`:
|
797
838
|
|
798
839
|
```ruby
|
799
|
-
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}}}}
|
800
841
|
```
|
801
842
|
|
802
|
-
|
843
|
+
## Highlight
|
803
844
|
|
804
845
|
Specify which fields to index with highlighting.
|
805
846
|
|
@@ -852,7 +893,7 @@ Band.search "cinema", fields: [:name], highlight: {fields: {name: {fragment_size
|
|
852
893
|
|
853
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).
|
854
895
|
|
855
|
-
|
896
|
+
## Similar Items
|
856
897
|
|
857
898
|
Find similar items.
|
858
899
|
|
@@ -861,7 +902,7 @@ product = Product.first
|
|
861
902
|
product.similar(fields: [:name], where: {size: "12 oz"})
|
862
903
|
```
|
863
904
|
|
864
|
-
|
905
|
+
## Geospatial Searches
|
865
906
|
|
866
907
|
```ruby
|
867
908
|
class Restaurant < ApplicationRecord
|
@@ -1028,13 +1069,173 @@ Product.search_index.tokens("dieg", analyzer: "searchkick_word_search")
|
|
1028
1069
|
|
1029
1070
|
See the [complete list of analyzers](https://github.com/ankane/searchkick/blob/31780ddac7a89eab1e0552a32b403f2040a37931/lib/searchkick/index_options.rb#L32).
|
1030
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
|
+
|
1205
|
+
### GitHub Actions
|
1206
|
+
|
1207
|
+
Check out [setup-elasticsearch](https://github.com/ankane/setup-elasticsearch) for an easy way to install Elasticsearch.
|
1208
|
+
|
1209
|
+
```yml
|
1210
|
+
- uses: ankane/setup-elasticsearch@v1
|
1211
|
+
```
|
1212
|
+
|
1031
1213
|
## Deployment
|
1032
1214
|
|
1033
1215
|
Searchkick uses `ENV["ELASTICSEARCH_URL"]` for the Elasticsearch server. This defaults to `http://localhost:9200`.
|
1034
1216
|
|
1217
|
+
- [Elastic Cloud](#elastic-cloud)
|
1218
|
+
- [Heroku](#heroku)
|
1219
|
+
- [Amazon Elasticsearch Service](#amazon-elasticsearch-service)
|
1220
|
+
- [Self-Hosted and Other](#other)
|
1221
|
+
|
1222
|
+
### Elastic Cloud
|
1223
|
+
|
1224
|
+
Create an initializer `config/initializers/elasticsearch.rb` with:
|
1225
|
+
|
1226
|
+
```ruby
|
1227
|
+
ENV["ELASTICSEARCH_URL"] = "https://user:password@host:port"
|
1228
|
+
```
|
1229
|
+
|
1230
|
+
Then deploy and reindex:
|
1231
|
+
|
1232
|
+
```sh
|
1233
|
+
rake searchkick:reindex:all
|
1234
|
+
```
|
1235
|
+
|
1035
1236
|
### Heroku
|
1036
1237
|
|
1037
|
-
Choose an add-on: [Bonsai](https://elements.heroku.com/addons/bonsai)
|
1238
|
+
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).
|
1038
1239
|
|
1039
1240
|
For Bonsai:
|
1040
1241
|
|
@@ -1043,6 +1244,13 @@ heroku addons:create bonsai
|
|
1043
1244
|
heroku config:set ELASTICSEARCH_URL=`heroku config:get BONSAI_URL`
|
1044
1245
|
```
|
1045
1246
|
|
1247
|
+
For SearchBox:
|
1248
|
+
|
1249
|
+
```sh
|
1250
|
+
heroku addons:create searchbox:starter
|
1251
|
+
heroku config:set ELASTICSEARCH_URL=`heroku config:get SEARCHBOX_URL`
|
1252
|
+
```
|
1253
|
+
|
1046
1254
|
For Elastic Cloud (previously Found):
|
1047
1255
|
|
1048
1256
|
```sh
|
@@ -1065,7 +1273,7 @@ heroku config:set ELASTICSEARCH_URL=https://elastic:password@12345.us-east-1.aws
|
|
1065
1273
|
Then deploy and reindex:
|
1066
1274
|
|
1067
1275
|
```sh
|
1068
|
-
heroku run rake searchkick:reindex
|
1276
|
+
heroku run rake searchkick:reindex:all
|
1069
1277
|
```
|
1070
1278
|
|
1071
1279
|
### Amazon Elasticsearch Service
|
@@ -1095,10 +1303,10 @@ Searchkick.aws_credentials = {
|
|
1095
1303
|
Then deploy and reindex:
|
1096
1304
|
|
1097
1305
|
```sh
|
1098
|
-
rake searchkick:reindex
|
1306
|
+
rake searchkick:reindex:all
|
1099
1307
|
```
|
1100
1308
|
|
1101
|
-
### Other
|
1309
|
+
### Self-Hosted and Other
|
1102
1310
|
|
1103
1311
|
Create an initializer `config/initializers/elasticsearch.rb` with:
|
1104
1312
|
|
@@ -1109,7 +1317,7 @@ ENV["ELASTICSEARCH_URL"] = "https://user:password@host:port"
|
|
1109
1317
|
Then deploy and reindex:
|
1110
1318
|
|
1111
1319
|
```sh
|
1112
|
-
rake searchkick:reindex
|
1320
|
+
rake searchkick:reindex:all
|
1113
1321
|
```
|
1114
1322
|
|
1115
1323
|
### Data Protection
|
@@ -1489,6 +1697,10 @@ Boost specific models with:
|
|
1489
1697
|
indices_boost: {Category => 2, Product => 1}
|
1490
1698
|
```
|
1491
1699
|
|
1700
|
+
## Multi-Tenancy
|
1701
|
+
|
1702
|
+
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.
|
1703
|
+
|
1492
1704
|
## Scroll API
|
1493
1705
|
|
1494
1706
|
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.
|
@@ -1695,14 +1907,6 @@ class Product < ApplicationRecord
|
|
1695
1907
|
end
|
1696
1908
|
```
|
1697
1909
|
|
1698
|
-
Turn off stemming
|
1699
|
-
|
1700
|
-
```ruby
|
1701
|
-
class Product < ApplicationRecord
|
1702
|
-
searchkick stem: false
|
1703
|
-
end
|
1704
|
-
```
|
1705
|
-
|
1706
1910
|
Turn on stemming for conversions
|
1707
1911
|
|
1708
1912
|
```ruby
|
@@ -1711,14 +1915,6 @@ class Product < ApplicationRecord
|
|
1711
1915
|
end
|
1712
1916
|
```
|
1713
1917
|
|
1714
|
-
Use a different [similarity algorithm](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-similarity.html) for scoring
|
1715
|
-
|
1716
|
-
```ruby
|
1717
|
-
class Product < ApplicationRecord
|
1718
|
-
searchkick similarity: "classic"
|
1719
|
-
end
|
1720
|
-
```
|
1721
|
-
|
1722
1918
|
Make search case-sensitive
|
1723
1919
|
|
1724
1920
|
```ruby
|
@@ -1803,142 +1999,11 @@ Product.search "api", misspellings: {prefix_length: 2} # api, apt, no ahi
|
|
1803
1999
|
Product.search "ah", misspellings: {prefix_length: 2} # ah, no aha
|
1804
2000
|
```
|
1805
2001
|
|
1806
|
-
## Testing
|
1807
|
-
|
1808
|
-
For performance, only enable Searchkick callbacks for the tests that need it.
|
1809
|
-
|
1810
|
-
### Minitest
|
1811
|
-
|
1812
|
-
Add to your `test/test_helper.rb`:
|
1813
|
-
|
1814
|
-
```ruby
|
1815
|
-
# reindex models
|
1816
|
-
Product.reindex
|
1817
|
-
|
1818
|
-
# and disable callbacks
|
1819
|
-
Searchkick.disable_callbacks
|
1820
|
-
```
|
1821
|
-
|
1822
|
-
And use:
|
1823
|
-
|
1824
|
-
```ruby
|
1825
|
-
class ProductTest < Minitest::Test
|
1826
|
-
def setup
|
1827
|
-
Searchkick.enable_callbacks
|
1828
|
-
end
|
1829
|
-
|
1830
|
-
def teardown
|
1831
|
-
Searchkick.disable_callbacks
|
1832
|
-
end
|
1833
|
-
|
1834
|
-
def test_search
|
1835
|
-
Product.create!(name: "Apple")
|
1836
|
-
Product.search_index.refresh
|
1837
|
-
assert_equal ["Apple"], Product.search("apple").map(&:name)
|
1838
|
-
end
|
1839
|
-
end
|
1840
|
-
```
|
1841
|
-
|
1842
|
-
### RSpec
|
1843
|
-
|
1844
|
-
Add to your `spec/spec_helper.rb`:
|
1845
|
-
|
1846
|
-
```ruby
|
1847
|
-
RSpec.configure do |config|
|
1848
|
-
config.before(:suite) do
|
1849
|
-
# reindex models
|
1850
|
-
Product.reindex
|
1851
|
-
|
1852
|
-
# and disable callbacks
|
1853
|
-
Searchkick.disable_callbacks
|
1854
|
-
end
|
1855
|
-
|
1856
|
-
config.around(:each, search: true) do |example|
|
1857
|
-
Searchkick.callbacks(true) do
|
1858
|
-
example.run
|
1859
|
-
end
|
1860
|
-
end
|
1861
|
-
end
|
1862
|
-
```
|
1863
|
-
|
1864
|
-
And use:
|
1865
|
-
|
1866
|
-
```ruby
|
1867
|
-
describe Product, search: true do
|
1868
|
-
it "searches" do
|
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
|
-
### Factory Bot
|
1877
|
-
|
1878
|
-
Use a trait and an after `create` hook for each indexed model:
|
1879
|
-
|
1880
|
-
```ruby
|
1881
|
-
FactoryBot.define do
|
1882
|
-
factory :product do
|
1883
|
-
# ...
|
1884
|
-
|
1885
|
-
# Note: This should be the last trait in the list so `reindex` is called
|
1886
|
-
# after all the other callbacks complete.
|
1887
|
-
trait :reindex do
|
1888
|
-
after(:create) do |product, _evaluator|
|
1889
|
-
product.reindex(refresh: true)
|
1890
|
-
end
|
1891
|
-
end
|
1892
|
-
end
|
1893
|
-
end
|
1894
|
-
|
1895
|
-
# use it
|
1896
|
-
FactoryBot.create(:product, :some_trait, :reindex, some_attribute: "foo")
|
1897
|
-
```
|
1898
|
-
|
1899
|
-
### Parallel Tests
|
1900
|
-
|
1901
|
-
Set:
|
1902
|
-
|
1903
|
-
```ruby
|
1904
|
-
Searchkick.index_suffix = ENV["TEST_ENV_NUMBER"]
|
1905
|
-
```
|
1906
|
-
|
1907
|
-
## Multi-Tenancy
|
1908
|
-
|
1909
|
-
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.
|
1910
|
-
|
1911
|
-
## Upgrading
|
1912
|
-
|
1913
|
-
See [how to upgrade to Searchkick 3](docs/Searchkick-3-Upgrade.md)
|
1914
|
-
|
1915
2002
|
## Elasticsearch 6 to 7 Upgrade
|
1916
2003
|
|
1917
2004
|
1. Install Searchkick 4
|
1918
2005
|
2. Upgrade your Elasticsearch cluster
|
1919
2006
|
|
1920
|
-
## Elasticsearch 5 to 6 Upgrade
|
1921
|
-
|
1922
|
-
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.
|
1923
|
-
|
1924
|
-
```ruby
|
1925
|
-
class Product < ApplicationRecord
|
1926
|
-
searchkick _all: false, default_fields: [:name]
|
1927
|
-
end
|
1928
|
-
```
|
1929
|
-
|
1930
|
-
If you need search across multiple fields, we recommend creating a similar field in your search data.
|
1931
|
-
|
1932
|
-
```ruby
|
1933
|
-
class Product < ApplicationRecord
|
1934
|
-
def search_data
|
1935
|
-
{
|
1936
|
-
all: [name, size, quantity].join(" ")
|
1937
|
-
}
|
1938
|
-
end
|
1939
|
-
end
|
1940
|
-
```
|
1941
|
-
|
1942
2007
|
## Elasticsearch Gotchas
|
1943
2008
|
|
1944
2009
|
### Consistency
|
@@ -1979,13 +2044,13 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
|
|
1979
2044
|
- Write, clarify, or fix documentation
|
1980
2045
|
- Suggest or add new features
|
1981
2046
|
|
1982
|
-
|
1983
|
-
|
1984
|
-
To get started with development and testing:
|
2047
|
+
To get started with development:
|
1985
2048
|
|
1986
2049
|
```sh
|
1987
2050
|
git clone https://github.com/ankane/searchkick.git
|
1988
2051
|
cd searchkick
|
1989
2052
|
bundle install
|
1990
|
-
rake test
|
2053
|
+
bundle exec rake test
|
1991
2054
|
```
|
2055
|
+
|
2056
|
+
Feel free to open an issue to get feedback on your idea before spending too much time on it.
|