searchkick 5.0.0 → 5.0.3

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: bc223f746f73c44e5c6f56b5e351cb31ae5a655069d92f5bfd2a0b2e531afae8
4
- data.tar.gz: 1969964f34a5adaf3ed746230fbef57673454f7304d890466e2814d27eb2cb47
3
+ metadata.gz: ec7741cb306a56f1a5ae5a07450c5c102236bc6103079fc34a5f602fa2853b31
4
+ data.tar.gz: 2bd747ee31846c901ce2a58125b34e9c90af6937a2c7dc041f2dd9f69701f1e9
5
5
  SHA512:
6
- metadata.gz: 17259c3e071d69c3852584aba480b523211b167f1249951f32d1bd2f761fc07322144283f0ccabac4878c0a2ff2f4c9dd8def2db2beac004c449839052e503ea
7
- data.tar.gz: 1109a53d99eb30f7e76cab8df00505c82af5e898c4e3f1821773932b8f6917e68f6bfedfa952b8e4acb25387607edf10856cc994021943671086af4d751cc728
6
+ metadata.gz: f92f2a3c7bb27862b1768f5ecedc19ad0eab515d62515f94d72412ed7c22a20493049dd0e52cba21b3a43d8c846b0dc0c6cda40c68edc12f6af37e8487fb9403
7
+ data.tar.gz: f69a1cfc401bad0f09bda3f2788b1096cc004dcb765eb20b3d8ada06202185eeae630d953005298e5944ed1b8c239fa808eeebb32e9440cc7ae9a32e771469dc
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## 5.0.3 (2022-03-13)
2
+
3
+ - Fixed context for index name for inherited models
4
+
5
+ ## 5.0.2 (2022-03-03)
6
+
7
+ - Fixed index name for inherited models
8
+
9
+ ## 5.0.1 (2022-02-27)
10
+
11
+ - Prefer `mode: :async` over `async: true` for full reindex
12
+ - Fixed instance method overriding with concerns
13
+
1
14
  ## 5.0.0 (2022-02-21)
2
15
 
3
16
  - Searches now use lazy loading (similar to Active Record)
@@ -15,7 +28,7 @@
15
28
  - Raise error when `search` called on relations
16
29
  - Raise `ArgumentError` (instead of warning) for invalid regular expression modifiers
17
30
  - Raise `ArgumentError` instead of `RuntimeError` for unknown operators
18
- - Removed mapping of `id` to `_id` with `order` option
31
+ - Removed mapping of `id` to `_id` with `order` option (not supported in Elasticsearch 8)
19
32
  - Removed `wordnet` option (no longer worked)
20
33
  - Removed dependency on `elasticsearch` gem (can use `elasticsearch` or `opensearch-ruby`)
21
34
  - Dropped support for Elasticsearch 6
data/README.md CHANGED
@@ -50,8 +50,8 @@ Searchkick 5.0 was recently released! See [how to upgrade](#upgrading)
50
50
  Install [Elasticsearch](https://www.elastic.co/downloads/elasticsearch) or [OpenSearch](https://opensearch.org/downloads.html). For Homebrew, use:
51
51
 
52
52
  ```sh
53
- brew install elasticsearch
54
- brew services start elasticsearch
53
+ brew install elastic/tap/elasticsearch-full
54
+ brew services start elasticsearch-full
55
55
  # or
56
56
  brew install opensearch
57
57
  brew services start opensearch
@@ -98,7 +98,7 @@ Searchkick supports the complete [Elasticsearch Search API](https://www.elastic.
98
98
  Query like SQL
99
99
 
100
100
  ```ruby
101
- Product.search "apples", where: {in_stock: true}, limit: 10, offset: 50
101
+ Product.search("apples", where: {in_stock: true}, limit: 10, offset: 50)
102
102
  ```
103
103
 
104
104
  Search specific fields
@@ -226,7 +226,7 @@ You can also boost by:
226
226
  Use a `*` for the query.
227
227
 
228
228
  ```ruby
229
- Product.search "*"
229
+ Product.search("*")
230
230
  ```
231
231
 
232
232
  ### Pagination
@@ -235,7 +235,7 @@ Plays nicely with kaminari and will_paginate.
235
235
 
236
236
  ```ruby
237
237
  # controller
238
- @products = Product.search "milk", page: params[:page], per_page: 20
238
+ @products = Product.search("milk", page: params[:page], per_page: 20)
239
239
  ```
240
240
 
241
241
  View with kaminari
@@ -255,13 +255,13 @@ View with will_paginate
255
255
  By default, results must match all words in the query.
256
256
 
257
257
  ```ruby
258
- Product.search "fresh honey" # fresh AND honey
258
+ Product.search("fresh honey") # fresh AND honey
259
259
  ```
260
260
 
261
261
  To change this, use:
262
262
 
263
263
  ```ruby
264
- Product.search "fresh honey", operator: "or" # fresh OR honey
264
+ Product.search("fresh honey", operator: "or") # fresh OR honey
265
265
  ```
266
266
 
267
267
  By default, results must match the entire word - `back` will not match `backpack`. You can change this behavior with:
@@ -275,7 +275,7 @@ end
275
275
  And to search (after you reindex):
276
276
 
277
277
  ```ruby
278
- Product.search "back", fields: [:name], match: :word_start
278
+ Product.search("back", fields: [:name], match: :word_start)
279
279
  ```
280
280
 
281
281
  Available options are:
@@ -297,7 +297,7 @@ The default is `:word`. The most matches will happen with `:word_middle`.
297
297
  To match a field exactly (case-sensitive), use:
298
298
 
299
299
  ```ruby
300
- User.search query, fields: [{email: :exact}, :name]
300
+ Product.search(query, fields: [{email: :exact}, :name])
301
301
  ```
302
302
 
303
303
  ### Phrase Matches
@@ -305,7 +305,7 @@ User.search query, fields: [{email: :exact}, :name]
305
305
  To only match the exact order, use:
306
306
 
307
307
  ```ruby
308
- User.search "fresh honey", match: :phrase
308
+ Product.search("fresh honey", match: :phrase)
309
309
  ```
310
310
 
311
311
  ### Stemming and Language
@@ -426,7 +426,7 @@ end
426
426
  Search with:
427
427
 
428
428
  ```ruby
429
- Product.search query, fields: [:name_tagged]
429
+ Product.search(query, fields: [:name_tagged])
430
430
  ```
431
431
 
432
432
  ### Misspellings
@@ -436,13 +436,13 @@ By default, Searchkick handles misspelled queries by returning results with an [
436
436
  You can change this with:
437
437
 
438
438
  ```ruby
439
- Product.search "zucini", misspellings: {edit_distance: 2} # zucchini
439
+ Product.search("zucini", misspellings: {edit_distance: 2}) # zucchini
440
440
  ```
441
441
 
442
442
  To prevent poor precision and improve performance for correctly spelled queries (which should be a majority for most applications), Searchkick can first perform a search without misspellings, and if there are too few results, perform another with them.
443
443
 
444
444
  ```ruby
445
- Product.search "zuchini", misspellings: {below: 5}
445
+ Product.search("zuchini", misspellings: {below: 5})
446
446
  ```
447
447
 
448
448
  If there are fewer than 5 results, a 2nd search is performed with misspellings enabled. The result of this query is returned.
@@ -450,13 +450,13 @@ If there are fewer than 5 results, a 2nd search is performed with misspellings e
450
450
  Turn off misspellings with:
451
451
 
452
452
  ```ruby
453
- Product.search "zuchini", misspellings: false # no zucchini
453
+ Product.search("zuchini", misspellings: false) # no zucchini
454
454
  ```
455
455
 
456
456
  Specify which fields can include misspellings with:
457
457
 
458
458
  ```ruby
459
- Product.search "zucini", fields: [:name, :color], misspellings: {fields: [:name]}
459
+ Product.search("zucini", fields: [:name, :color], misspellings: {fields: [:name]})
460
460
  ```
461
461
 
462
462
  > When doing this, you must also specify fields to search
@@ -466,7 +466,7 @@ Product.search "zucini", fields: [:name, :color], misspellings: {fields: [:name]
466
466
  If a user searches `butter`, they may also get results for `peanut butter`. To prevent this, use:
467
467
 
468
468
  ```ruby
469
- Product.search "butter", exclude: ["peanut butter"]
469
+ Product.search("butter", exclude: ["peanut butter"])
470
470
  ```
471
471
 
472
472
  You can map queries and terms to exclude with:
@@ -477,7 +477,7 @@ exclude_queries = {
477
477
  "cream" => ["ice cream", "whipped cream"]
478
478
  }
479
479
 
480
- Product.search query, exclude: exclude_queries[query]
480
+ Product.search(query, exclude: exclude_queries[query])
481
481
  ```
482
482
 
483
483
  You can demote results by boosting by a factor less than one:
@@ -499,7 +499,7 @@ gem "gemoji-parser"
499
499
  And use:
500
500
 
501
501
  ```ruby
502
- Product.search "🍨🍰", emoji: true
502
+ Product.search("🍨🍰", emoji: true)
503
503
  ```
504
504
 
505
505
  ## Indexing
@@ -596,7 +596,7 @@ You can also do bulk updates.
596
596
 
597
597
  ```ruby
598
598
  Searchkick.callbacks(:bulk) do
599
- User.find_each(&:update_fields)
599
+ Product.find_each(&:update_fields)
600
600
  end
601
601
  ```
602
602
 
@@ -604,7 +604,7 @@ Or temporarily skip updates.
604
604
 
605
605
  ```ruby
606
606
  Searchkick.callbacks(false) do
607
- User.find_each(&:update_fields)
607
+ Product.find_each(&:update_fields)
608
608
  end
609
609
  ```
610
610
 
@@ -651,7 +651,7 @@ end
651
651
  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.
652
652
 
653
653
  ```ruby
654
- Product.search "apple", track: {user_id: current_user.id}
654
+ Product.search("apple", track: {user_id: current_user.id})
655
655
  ```
656
656
 
657
657
  [See the docs](https://github.com/ankane/searchjoy) for how to install and use.
@@ -683,7 +683,7 @@ end
683
683
 
684
684
  Reindex and set up a cron job to add new conversions daily.
685
685
 
686
- ```ruby
686
+ ```sh
687
687
  rake searchkick:reindex CLASS=Product
688
688
  ```
689
689
 
@@ -709,7 +709,7 @@ end
709
709
  Reindex and search with:
710
710
 
711
711
  ```ruby
712
- Product.search "milk", boost_where: {orderer_ids: current_user.id}
712
+ Product.search("milk", boost_where: {orderer_ids: current_user.id})
713
713
  ```
714
714
 
715
715
  ## Instant Search / Autocomplete
@@ -733,7 +733,7 @@ end
733
733
  Reindex and search with:
734
734
 
735
735
  ```ruby
736
- Movie.search "jurassic pa", fields: [:title], match: :word_start
736
+ Movie.search("jurassic pa", fields: [:title], match: :word_start)
737
737
  ```
738
738
 
739
739
  Typically, you want to use a JavaScript library like [typeahead.js](https://twitter.github.io/typeahead.js/) or [jQuery UI](https://jqueryui.com/autocomplete/).
@@ -793,7 +793,7 @@ end
793
793
  Reindex and search with:
794
794
 
795
795
  ```ruby
796
- products = Product.search "peantu butta", suggest: true
796
+ products = Product.search("peantu butta", suggest: true)
797
797
  products.suggestions # ["peanut butter"]
798
798
  ```
799
799
 
@@ -804,40 +804,40 @@ products.suggestions # ["peanut butter"]
804
804
  ![Aggregations](https://gist.github.com/ankane/b6988db2802aca68a589b31e41b44195/raw/40febe948427e5bc53ec4e5dc248822855fef76f/facets.png)
805
805
 
806
806
  ```ruby
807
- products = Product.search "chuck taylor", aggs: [:product_type, :gender, :brand]
807
+ products = Product.search("chuck taylor", aggs: [:product_type, :gender, :brand])
808
808
  products.aggs
809
809
  ```
810
810
 
811
811
  By default, `where` conditions apply to aggregations.
812
812
 
813
813
  ```ruby
814
- Product.search "wingtips", where: {color: "brandy"}, aggs: [:size]
814
+ Product.search("wingtips", where: {color: "brandy"}, aggs: [:size])
815
815
  # aggregations for brandy wingtips are returned
816
816
  ```
817
817
 
818
818
  Change this with:
819
819
 
820
820
  ```ruby
821
- Product.search "wingtips", where: {color: "brandy"}, aggs: [:size], smart_aggs: false
821
+ Product.search("wingtips", where: {color: "brandy"}, aggs: [:size], smart_aggs: false)
822
822
  # aggregations for all wingtips are returned
823
823
  ```
824
824
 
825
825
  Set `where` conditions for each aggregation separately with:
826
826
 
827
827
  ```ruby
828
- Product.search "wingtips", aggs: {size: {where: {color: "brandy"}}}
828
+ Product.search("wingtips", aggs: {size: {where: {color: "brandy"}}})
829
829
  ```
830
830
 
831
831
  Limit
832
832
 
833
833
  ```ruby
834
- Product.search "apples", aggs: {store_id: {limit: 10}}
834
+ Product.search("apples", aggs: {store_id: {limit: 10}})
835
835
  ```
836
836
 
837
837
  Order
838
838
 
839
839
  ```ruby
840
- Product.search "wingtips", aggs: {color: {order: {"_key" => "asc"}}} # alphabetically
840
+ Product.search("wingtips", aggs: {color: {order: {"_key" => "asc"}}}) # alphabetically
841
841
  ```
842
842
 
843
843
  [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)
@@ -846,31 +846,31 @@ Ranges
846
846
 
847
847
  ```ruby
848
848
  price_ranges = [{to: 20}, {from: 20, to: 50}, {from: 50}]
849
- Product.search "*", aggs: {price: {ranges: price_ranges}}
849
+ Product.search("*", aggs: {price: {ranges: price_ranges}})
850
850
  ```
851
851
 
852
852
  Minimum document count
853
853
 
854
854
  ```ruby
855
- Product.search "apples", aggs: {store_id: {min_doc_count: 2}}
855
+ Product.search("apples", aggs: {store_id: {min_doc_count: 2}})
856
856
  ```
857
857
 
858
858
  Script support
859
859
 
860
860
  ```ruby
861
- Product.search "*", aggs: {color: {script: {source: "'Color: ' + _value"}}}
861
+ Product.search("*", aggs: {color: {script: {source: "'Color: ' + _value"}}})
862
862
  ```
863
863
 
864
864
  Date histogram
865
865
 
866
866
  ```ruby
867
- Product.search "pear", aggs: {products_per_year: {date_histogram: {field: :created_at, interval: :year}}}
867
+ Product.search("pear", aggs: {products_per_year: {date_histogram: {field: :created_at, interval: :year}}})
868
868
  ```
869
869
 
870
870
  For other aggregation types, including sub-aggregations, use `body_options`:
871
871
 
872
872
  ```ruby
873
- Product.search "orange", body_options: {aggs: {price: {histogram: {field: :price, interval: 10}}}}
873
+ Product.search("orange", body_options: {aggs: {price: {histogram: {field: :price, interval: 10}}}})
874
874
  ```
875
875
 
876
876
  ## Highlight
@@ -878,7 +878,7 @@ Product.search "orange", body_options: {aggs: {price: {histogram: {field: :price
878
878
  Specify which fields to index with highlighting.
879
879
 
880
880
  ```ruby
881
- class Product < ApplicationRecord
881
+ class Band < ApplicationRecord
882
882
  searchkick highlight: [:name]
883
883
  end
884
884
  ```
@@ -886,7 +886,7 @@ end
886
886
  Highlight the search query in the results.
887
887
 
888
888
  ```ruby
889
- bands = Band.search "cinema", highlight: true
889
+ bands = Band.search("cinema", highlight: true)
890
890
  ```
891
891
 
892
892
  View the highlighted fields with:
@@ -900,19 +900,19 @@ end
900
900
  To change the tag, use:
901
901
 
902
902
  ```ruby
903
- Band.search "cinema", highlight: {tag: "<strong>"}
903
+ Band.search("cinema", highlight: {tag: "<strong>"})
904
904
  ```
905
905
 
906
906
  To highlight and search different fields, use:
907
907
 
908
908
  ```ruby
909
- Band.search "cinema", fields: [:name], highlight: {fields: [:description]}
909
+ Band.search("cinema", fields: [:name], highlight: {fields: [:description]})
910
910
  ```
911
911
 
912
912
  By default, the entire field is highlighted. To get small snippets instead, use:
913
913
 
914
914
  ```ruby
915
- bands = Band.search "cinema", highlight: {fragment_size: 20}
915
+ bands = Band.search("cinema", highlight: {fragment_size: 20})
916
916
  bands.with_highlights(multiple: true).each do |band, highlights|
917
917
  highlights[:name].join(" and ")
918
918
  end
@@ -921,7 +921,7 @@ end
921
921
  Additional options can be specified for each field:
922
922
 
923
923
  ```ruby
924
- Band.search "cinema", fields: [:name], highlight: {fields: {name: {fragment_size: 200}}}
924
+ Band.search("cinema", fields: [:name], highlight: {fields: {name: {fragment_size: 200}}})
925
925
  ```
926
926
 
927
927
  You can find available highlight options in the [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/highlighting.html).
@@ -950,13 +950,13 @@ end
950
950
  Reindex and search with:
951
951
 
952
952
  ```ruby
953
- Restaurant.search "pizza", where: {location: {near: {lat: 37, lon: -114}, within: "100mi"}} # or 160km
953
+ Restaurant.search("pizza", where: {location: {near: {lat: 37, lon: -114}, within: "100mi"}}) # or 160km
954
954
  ```
955
955
 
956
956
  Bounded by a box
957
957
 
958
958
  ```ruby
959
- Restaurant.search "sushi", where: {location: {top_left: {lat: 38, lon: -123}, bottom_right: {lat: 37, lon: -122}}}
959
+ Restaurant.search("sushi", where: {location: {top_left: {lat: 38, lon: -123}, bottom_right: {lat: 37, lon: -122}}})
960
960
  ```
961
961
 
962
962
  **Note:** `top_right` and `bottom_left` also work
@@ -964,7 +964,7 @@ Restaurant.search "sushi", where: {location: {top_left: {lat: 38, lon: -123}, bo
964
964
  Bounded by a polygon
965
965
 
966
966
  ```ruby
967
- Restaurant.search "dessert", where: {location: {geo_polygon: {points: [{lat: 38, lon: -123}, {lat: 39, lon: -123}, {lat: 37, lon: 122}]}}}
967
+ Restaurant.search("dessert", where: {location: {geo_polygon: {points: [{lat: 38, lon: -123}, {lat: 39, lon: -123}, {lat: 37, lon: 122}]}}})
968
968
  ```
969
969
 
970
970
  ### Boost By Distance
@@ -972,13 +972,13 @@ Restaurant.search "dessert", where: {location: {geo_polygon: {points: [{lat: 38,
972
972
  Boost results by distance - closer results are boosted more
973
973
 
974
974
  ```ruby
975
- Restaurant.search "noodles", boost_by_distance: {location: {origin: {lat: 37, lon: -122}}}
975
+ Restaurant.search("noodles", boost_by_distance: {location: {origin: {lat: 37, lon: -122}}})
976
976
  ```
977
977
 
978
978
  Also supports [additional options](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-decay)
979
979
 
980
980
  ```ruby
981
- Restaurant.search "wings", boost_by_distance: {location: {origin: {lat: 37, lon: -122}, function: "linear", scale: "30mi", decay: 0.5}}
981
+ Restaurant.search("wings", boost_by_distance: {location: {origin: {lat: 37, lon: -122}, function: "linear", scale: "30mi", decay: 0.5}})
982
982
  ```
983
983
 
984
984
  ### Geo Shapes
@@ -1005,19 +1005,19 @@ See the [Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsea
1005
1005
  Find shapes intersecting with the query shape
1006
1006
 
1007
1007
  ```ruby
1008
- Restaurant.search "soup", where: {bounds: {geo_shape: {type: "polygon", coordinates: [[{lat: 38, lon: -123}, ...]]}}}
1008
+ Restaurant.search("soup", where: {bounds: {geo_shape: {type: "polygon", coordinates: [[{lat: 38, lon: -123}, ...]]}}})
1009
1009
  ```
1010
1010
 
1011
1011
  Falling entirely within the query shape
1012
1012
 
1013
1013
  ```ruby
1014
- Restaurant.search "salad", where: {bounds: {geo_shape: {type: "circle", relation: "within", coordinates: [{lat: 38, lon: -123}], radius: "1km"}}}
1014
+ Restaurant.search("salad", where: {bounds: {geo_shape: {type: "circle", relation: "within", coordinates: [{lat: 38, lon: -123}], radius: "1km"}}})
1015
1015
  ```
1016
1016
 
1017
1017
  Not touching the query shape
1018
1018
 
1019
1019
  ```ruby
1020
- Restaurant.search "burger", where: {bounds: {geo_shape: {type: "envelope", relation: "disjoint", coordinates: [{lat: 38, lon: -123}, {lat: 37, lon: -122}]}}}
1020
+ Restaurant.search("burger", where: {bounds: {geo_shape: {type: "envelope", relation: "disjoint", coordinates: [{lat: 38, lon: -123}, {lat: 37, lon: -122}]}}})
1021
1021
  ```
1022
1022
 
1023
1023
  ## Inheritance
@@ -1047,9 +1047,9 @@ Dog.reindex # equivalent, all animals reindexed
1047
1047
  And to search, use:
1048
1048
 
1049
1049
  ```ruby
1050
- Animal.search "*" # all animals
1051
- Dog.search "*" # just dogs
1052
- Animal.search "*", type: [Dog, Cat] # just cats and dogs
1050
+ Animal.search("*") # all animals
1051
+ Dog.search("*") # just dogs
1052
+ Animal.search("*", type: [Dog, Cat]) # just cats and dogs
1053
1053
  ```
1054
1054
 
1055
1055
  **Notes:**
@@ -1057,7 +1057,7 @@ Animal.search "*", type: [Dog, Cat] # just cats and dogs
1057
1057
  1. The `suggest` option retrieves suggestions from the parent at the moment.
1058
1058
 
1059
1059
  ```ruby
1060
- Dog.search "airbudd", suggest: true # suggestions for all animals
1060
+ Dog.search("airbudd", suggest: true) # suggestions for all animals
1061
1061
  ```
1062
1062
  2. This relies on a `type` field that is automatically added to the indexed document. Be wary of defining your own `type` field in `search_data`, as it will take precedence.
1063
1063
 
@@ -1100,7 +1100,7 @@ Product.search_index.tokens("dieg", analyzer: "searchkick_word_search")
1100
1100
  # ["dieg"] - match!!
1101
1101
  ```
1102
1102
 
1103
- See the [complete list of analyzers](https://github.com/ankane/searchkick/blob/31780ddac7a89eab1e0552a32b403f2040a37931/lib/searchkick/index_options.rb#L32).
1103
+ See the [complete list of analyzers](lib/searchkick/index_options.rb#L36).
1104
1104
 
1105
1105
  ## Testing
1106
1106
 
@@ -1376,13 +1376,15 @@ Bonsai, Elastic Cloud, and Amazon OpenSearch Service all support encryption at r
1376
1376
 
1377
1377
  ### Automatic Failover
1378
1378
 
1379
- Create an initializer `config/initializers/elasticsearch.rb` with multiple hosts:
1379
+ Create an initializer with multiple hosts:
1380
1380
 
1381
1381
  ```ruby
1382
1382
  ENV["ELASTICSEARCH_URL"] = "https://user:password@host1,https://user:password@host2"
1383
+ # or
1384
+ ENV["OPENSEARCH_URL"] = "https://user:password@host1,https://user:password@host2"
1383
1385
  ```
1384
1386
 
1385
- See [elasticsearch-transport](https://github.com/elastic/elasticsearch-ruby/blob/master/elasticsearch-transport) for a complete list of options.
1387
+ See [elastic-transport](https://github.com/elastic/elastic-transport-ruby) or [opensearch-transport](https://github.com/opensearch-project/opensearch-ruby/tree/main/opensearch-transport) for a complete list of options.
1386
1388
 
1387
1389
  ### Lograge
1388
1390
 
@@ -1453,7 +1455,7 @@ end
1453
1455
  For large data sets, you can use background jobs to parallelize reindexing.
1454
1456
 
1455
1457
  ```ruby
1456
- Product.reindex(async: true)
1458
+ Product.reindex(mode: :async)
1457
1459
  # {index_name: "products_production_20170111210018065"}
1458
1460
  ```
1459
1461
 
@@ -1478,7 +1480,7 @@ Searchkick.reindex_status(index_name)
1478
1480
  You can also have Searchkick wait for reindexing to complete
1479
1481
 
1480
1482
  ```ruby
1481
- Product.reindex(async: {wait: true})
1483
+ Product.reindex(mode: :async, wait: true)
1482
1484
  ```
1483
1485
 
1484
1486
  You can use [ActiveJob::TrafficControl](https://github.com/nickelser/activejob-traffic_control) to control concurrency. Install the gem:
@@ -1504,7 +1506,7 @@ This will allow only 3 jobs to run at once.
1504
1506
  You can specify a longer refresh interval while reindexing to increase performance.
1505
1507
 
1506
1508
  ```ruby
1507
- Product.reindex(async: true, refresh_interval: "30s")
1509
+ Product.reindex(mode: :async, refresh_interval: "30s")
1508
1510
  ```
1509
1511
 
1510
1512
  **Note:** This only makes a noticable difference with parallel reindexing.
@@ -1562,7 +1564,7 @@ end
1562
1564
  Reindex and search with:
1563
1565
 
1564
1566
  ```ruby
1565
- Business.search "ice cream", routing: params[:city_id]
1567
+ Business.search("ice cream", routing: params[:city_id])
1566
1568
  ```
1567
1569
 
1568
1570
  ### Partial Reindexing
@@ -1685,7 +1687,7 @@ end
1685
1687
  And use the `body` option to search:
1686
1688
 
1687
1689
  ```ruby
1688
- products = Product.search body: {query: {match: {name: "milk"}}}
1690
+ products = Product.search(body: {query: {match: {name: "milk"}}})
1689
1691
  ```
1690
1692
 
1691
1693
  View the response with:
@@ -1697,21 +1699,21 @@ products.response
1697
1699
  To modify the query generated by Searchkick, use:
1698
1700
 
1699
1701
  ```ruby
1700
- products = Product.search "milk", body_options: {min_score: 1}
1702
+ products = Product.search("milk", body_options: {min_score: 1})
1701
1703
  ```
1702
1704
 
1703
1705
  or
1704
1706
 
1705
1707
  ```ruby
1706
1708
  products =
1707
- Product.search "apples" do |body|
1709
+ Product.search("apples") do |body|
1708
1710
  body[:min_score] = 1
1709
1711
  end
1710
1712
  ```
1711
1713
 
1712
1714
  ### Client
1713
1715
 
1714
- Searchkick is built on top of the [elasticsearch](https://github.com/elastic/elasticsearch-ruby) gem. To access the client directly, use:
1716
+ To access the `Elasticsearch::Client` or `OpenSearch::Client` directly, use:
1715
1717
 
1716
1718
  ```ruby
1717
1719
  Searchkick.client
@@ -1736,7 +1738,7 @@ Then use `products` and `coupons` as typical results.
1736
1738
  Search across multiple models with:
1737
1739
 
1738
1740
  ```ruby
1739
- Searchkick.search "milk", models: [Product, Category]
1741
+ Searchkick.search("milk", models: [Product, Category])
1740
1742
  ```
1741
1743
 
1742
1744
  Boost specific models with:
@@ -1762,7 +1764,7 @@ end
1762
1764
  You can also scroll batches manually.
1763
1765
 
1764
1766
  ```ruby
1765
- products = Product.search "*", scroll: "1m"
1767
+ products = Product.search("*", scroll: "1m")
1766
1768
  while products.any?
1767
1769
  # process batch ...
1768
1770
 
@@ -1793,7 +1795,7 @@ Product.search("pears", body_options: {track_total_hits: true})
1793
1795
  To query nested data, use dot notation.
1794
1796
 
1795
1797
  ```ruby
1796
- User.search "san", fields: ["address.city"], where: {"address.zip_code" => 12345}
1798
+ Product.search("san", fields: ["store.city"], where: {"store.zip_code" => 12345})
1797
1799
  ```
1798
1800
 
1799
1801
  ## Reference
@@ -1923,7 +1925,7 @@ Searchkick.queue_name = :search_reindex
1923
1925
  Eager load associations
1924
1926
 
1925
1927
  ```ruby
1926
- Product.search "milk", includes: [:brand, :stores]
1928
+ Product.search("milk", includes: [:brand, :stores])
1927
1929
  ```
1928
1930
 
1929
1931
  Eager load different associations by model
@@ -1935,7 +1937,7 @@ Searchkick.search("*", models: [Product, Store], model_includes: {Product => [:
1935
1937
  Run additional scopes on results
1936
1938
 
1937
1939
  ```ruby
1938
- Product.search "milk", scope_results: ->(r) { r.with_attached_images }
1940
+ Product.search("milk", scope_results: ->(r) { r.with_attached_images })
1939
1941
  ```
1940
1942
 
1941
1943
  Specify default fields to search
@@ -2031,13 +2033,13 @@ rake searchkick:reindex:all
2031
2033
  Turn on misspellings after a certain number of characters
2032
2034
 
2033
2035
  ```ruby
2034
- Product.search "api", misspellings: {prefix_length: 2} # api, apt, no ahi
2036
+ Product.search("api", misspellings: {prefix_length: 2}) # api, apt, no ahi
2035
2037
  ```
2036
2038
 
2037
2039
  **Note:** With this option, if the query length is the same as `prefix_length`, misspellings are turned off with Elasticsearch 7 and OpenSearch
2038
2040
 
2039
2041
  ```ruby
2040
- Product.search "ah", misspellings: {prefix_length: 2} # ah, no aha
2042
+ Product.search("ah", misspellings: {prefix_length: 2}) # ah, no aha
2041
2043
  ```
2042
2044
 
2043
2045
  ## Gotchas
@@ -2087,9 +2089,17 @@ Product.search("milk")
2087
2089
  Product.search("milk").to_a
2088
2090
  ```
2089
2091
 
2092
+ You can reindex relations in the background:
2093
+
2094
+ ```ruby
2095
+ store.products.reindex(mode: :async)
2096
+ # or
2097
+ store.products.reindex(mode: :queue)
2098
+ ```
2099
+
2090
2100
  And there’s a [new option](#default-scopes) for models with default scopes.
2091
2101
 
2092
- Check out the [changelog](https://github.com/ankane/searchkick/blob/master/CHANGELOG.md) for the full list of changes.
2102
+ Check out the [changelog](https://github.com/ankane/searchkick/blob/master/CHANGELOG.md#500-2022-02-21) for the full list of changes.
2093
2103
 
2094
2104
  ## History
2095
2105
 
@@ -71,12 +71,12 @@ module Searchkick
71
71
  }
72
72
  )
73
73
 
74
- Searchkick::Results.new(nil, response).total_count
74
+ Results.new(nil, response).total_count
75
75
  end
76
76
 
77
77
  def promote(new_name, update_refresh_interval: false)
78
78
  if update_refresh_interval
79
- new_index = Searchkick::Index.new(new_name, @options)
79
+ new_index = Index.new(new_name, @options)
80
80
  settings = options[:settings] || {}
81
81
  refresh_interval = (settings[:index] && settings[:index][:refresh_interval]) || "1s"
82
82
  new_index.update_settings(index: {refresh_interval: refresh_interval})
@@ -123,7 +123,7 @@ module Searchkick
123
123
  def clean_indices
124
124
  indices = all_indices(unaliased: true)
125
125
  indices.each do |index|
126
- Searchkick::Index.new(index).delete
126
+ Index.new(index).delete
127
127
  end
128
128
  indices
129
129
  end
@@ -204,7 +204,7 @@ module Searchkick
204
204
  # queue
205
205
 
206
206
  def reindex_queue
207
- Searchkick::ReindexQueue.new(name)
207
+ ReindexQueue.new(name)
208
208
  end
209
209
 
210
210
  # reindex
@@ -237,13 +237,26 @@ module Searchkick
237
237
  self.refresh if refresh
238
238
  true
239
239
  else
240
+ async = options.delete(:async)
241
+ if async
242
+ if async.is_a?(Hash) && async[:wait]
243
+ # TODO warn in 5.1
244
+ # Searchkick.warn "async option is deprecated - use mode: :async, wait: true instead"
245
+ options[:wait] = true unless options.key?(:wait)
246
+ else
247
+ # TODO warn in 5.1
248
+ # Searchkick.warn "async option is deprecated - use mode: :async instead"
249
+ end
250
+ options[:mode] ||= :async
251
+ end
252
+
240
253
  full_reindex(relation, **options)
241
254
  end
242
255
  end
243
256
 
244
257
  def create_index(index_options: nil)
245
258
  index_options ||= self.index_options
246
- index = Searchkick::Index.new("#{name}_#{Time.now.strftime('%Y%m%d%H%M%S%L')}", @options)
259
+ index = Index.new("#{name}_#{Time.now.strftime('%Y%m%d%H%M%S%L')}", @options)
247
260
  index.create(index_options)
248
261
  index
249
262
  end
@@ -326,7 +339,7 @@ module Searchkick
326
339
  end
327
340
 
328
341
  def reindex_records(object, mode: nil, refresh: false, **options)
329
- mode ||= Searchkick.callbacks_value || @options[:callbacks] || true
342
+ mode ||= Searchkick.callbacks_value || @options[:callbacks] || :inline
330
343
  mode = :inline if mode == :bulk
331
344
 
332
345
  result = RecordIndexer.new(self).reindex(object, mode: mode, full: false, **options)
@@ -336,12 +349,13 @@ module Searchkick
336
349
 
337
350
  # https://gist.github.com/jarosan/3124884
338
351
  # http://www.elasticsearch.org/blog/changing-mapping-with-zero-downtime/
339
- # TODO deprecate async in favor of mode: :async, wait: true/false
340
- def full_reindex(relation, import: true, resume: false, retain: false, async: false, refresh_interval: nil, scope: nil)
352
+ def full_reindex(relation, import: true, resume: false, retain: false, mode: nil, refresh_interval: nil, scope: nil, wait: nil)
353
+ raise ArgumentError, "wait only available in :async mode" if !wait.nil? && mode != :async
354
+
341
355
  if resume
342
356
  index_name = all_indices.sort.last
343
- raise Searchkick::Error, "No index to resume" unless index_name
344
- index = Searchkick::Index.new(index_name, @options)
357
+ raise Error, "No index to resume" unless index_name
358
+ index = Index.new(index_name, @options)
345
359
  else
346
360
  clean_indices unless retain
347
361
 
@@ -351,7 +365,7 @@ module Searchkick
351
365
  end
352
366
 
353
367
  import_options = {
354
- mode: (async ? :async : :inline),
368
+ mode: (mode || :inline),
355
369
  full: true,
356
370
  resume: resume,
357
371
  scope: scope
@@ -365,7 +379,7 @@ module Searchkick
365
379
  import_before_promotion(index, relation, **import_options) if import
366
380
 
367
381
  # get existing indices to remove
368
- unless async
382
+ unless mode == :async
369
383
  check_uuid(uuid, index.uuid)
370
384
  promote(index.name, update_refresh_interval: !refresh_interval.nil?)
371
385
  clean_indices unless retain
@@ -378,8 +392,8 @@ module Searchkick
378
392
  index.import_scope(relation, **import_options) if import
379
393
  end
380
394
 
381
- if async
382
- if async.is_a?(Hash) && async[:wait]
395
+ if mode == :async
396
+ if wait
383
397
  puts "Created index: #{index.name}"
384
398
  puts "Jobs queued. Waiting..."
385
399
  loop do
@@ -417,7 +431,7 @@ module Searchkick
417
431
  # https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html#index-creation
418
432
  def check_uuid(old_uuid, new_uuid)
419
433
  if old_uuid != new_uuid
420
- raise Searchkick::Error, "Safety check failed - only run one Model.reindex per model at a time"
434
+ raise Error, "Safety check failed - only run one Model.reindex per model at a time"
421
435
  end
422
436
  end
423
437
 
@@ -513,7 +513,7 @@ module Searchkick
513
513
  else
514
514
  [:searchkick_search2, :searchkick_word_search].each do |analyzer|
515
515
  unless settings[:analysis][:analyzer][analyzer].key?(:filter)
516
- raise Searchkick::Error, "Search synonyms are not supported yet for language"
516
+ raise Error, "Search synonyms are not supported yet for language"
517
517
  end
518
518
 
519
519
  settings[:analysis][:analyzer][analyzer][:filter].insert(2, "searchkick_synonym_graph")
@@ -22,16 +22,18 @@ module Searchkick
22
22
  raise ArgumentError, "Invalid value for callbacks"
23
23
  end
24
24
 
25
+ base = self
26
+
25
27
  mod = Module.new
26
28
  include(mod)
27
29
  mod.module_eval do
28
30
  def reindex(method_name = nil, mode: nil, refresh: false)
29
31
  self.class.searchkick_index.reindex([self], method_name: method_name, mode: mode, refresh: refresh, single: true)
30
- end
32
+ end unless base.method_defined?(:reindex)
31
33
 
32
34
  def similar(**options)
33
35
  self.class.searchkick_index.similar_record(self, **options)
34
- end
36
+ end unless base.method_defined?(:similar)
35
37
 
36
38
  def search_data
37
39
  data = respond_to?(:to_hash) ? to_hash : serializable_hash
@@ -39,11 +41,11 @@ module Searchkick
39
41
  data.delete("_id")
40
42
  data.delete("_type")
41
43
  data
42
- end
44
+ end unless base.method_defined?(:search_data)
43
45
 
44
46
  def should_index?
45
47
  true
46
- end
48
+ end unless base.method_defined?(:should_index?)
47
49
  end
48
50
 
49
51
  class_eval do
@@ -64,10 +66,10 @@ module Searchkick
64
66
  alias_method Searchkick.search_method_name, :searchkick_search if Searchkick.search_method_name
65
67
 
66
68
  def searchkick_index(name: nil)
67
- index = name || searchkick_index_name
68
- index = index.call if index.respond_to?(:call)
69
+ index_name = name || searchkick_klass.searchkick_index_name
70
+ index_name = index_name.call if index_name.respond_to?(:call)
69
71
  index_cache = class_variable_get(:@@searchkick_index_cache)
70
- index_cache.fetch(index) { Searchkick::Index.new(index, searchkick_options) }
72
+ index_cache.fetch(index_name) { Searchkick::Index.new(index_name, searchkick_options) }
71
73
  end
72
74
  alias_method :search_index, :searchkick_index unless method_defined?(:search_index)
73
75
 
@@ -187,11 +187,11 @@ module Searchkick
187
187
  end
188
188
 
189
189
  # set execute for multi search
190
- @execute = Searchkick::Results.new(searchkick_klass, response, opts)
190
+ @execute = Results.new(searchkick_klass, response, opts)
191
191
  end
192
192
 
193
193
  def retry_misspellings?(response)
194
- @misspellings_below && Searchkick::Results.new(searchkick_klass, response).total_count < @misspellings_below
194
+ @misspellings_below && Results.new(searchkick_klass, response).total_count < @misspellings_below
195
195
  end
196
196
 
197
197
  private
@@ -25,6 +25,7 @@ module Searchkick
25
25
  {delete: record_data}
26
26
  end
27
27
 
28
+ # custom id can be useful for load: false
28
29
  def search_id
29
30
  id = record.respond_to?(:search_document_id) ? record.search_document_id : record.id
30
31
  id.is_a?(Numeric) ? id : id.to_s
@@ -14,7 +14,7 @@ module Searchkick
14
14
  case mode
15
15
  when :async
16
16
  unless defined?(ActiveJob)
17
- raise Searchkick::Error, "Active Job not found"
17
+ raise Error, "Active Job not found"
18
18
  end
19
19
 
20
20
  # we could likely combine ReindexV2Job, BulkReindexJob, and ProcessBatchJob
@@ -45,7 +45,7 @@ module Searchkick
45
45
  end
46
46
  when :queue
47
47
  if method_name
48
- raise Searchkick::Error, "Partial reindex not supported with queue option"
48
+ raise Error, "Partial reindex not supported with queue option"
49
49
  end
50
50
 
51
51
  index.reindex_queue.push_records(records)
@@ -5,7 +5,7 @@ module Searchkick
5
5
  def initialize(name)
6
6
  @name = name
7
7
 
8
- raise Searchkick::Error, "Searchkick.redis not set" unless Searchkick.redis
8
+ raise Error, "Searchkick.redis not set" unless Searchkick.redis
9
9
  end
10
10
 
11
11
  # supports single and multiple ids
@@ -1,13 +1,20 @@
1
1
  module Searchkick
2
2
  class Relation
3
+ NO_DEFAULT_VALUE = Object.new
4
+
3
5
  # note: modifying body directly is not supported
4
6
  # and has no impact on query after being executed
5
7
  # TODO freeze body object?
6
- delegate :body, :params, to: :@query
8
+ delegate :body, :params, to: :query
7
9
  delegate_missing_to :private_execute
8
10
 
9
11
  def initialize(model, term = "*", **options)
10
- @query = Query.new(model, term, **options)
12
+ @model = model
13
+ @term = term
14
+ @options = options
15
+
16
+ # generate query to validate options
17
+ query
11
18
  end
12
19
 
13
20
  # same as Active Record
@@ -23,14 +30,196 @@ module Searchkick
23
30
  self
24
31
  end
25
32
 
33
+ # experimental
34
+ def limit(value)
35
+ clone.limit!(value)
36
+ end
37
+
38
+ # experimental
39
+ def limit!(value)
40
+ check_loaded
41
+ @options[:limit] = value
42
+ self
43
+ end
44
+
45
+ # experimental
46
+ def offset(value = NO_DEFAULT_VALUE)
47
+ # TODO remove in Searchkick 6
48
+ if value == NO_DEFAULT_VALUE
49
+ private_execute.offset
50
+ else
51
+ clone.offset!(value)
52
+ end
53
+ end
54
+
55
+ # experimental
56
+ def offset!(value)
57
+ check_loaded
58
+ @options[:offset] = value
59
+ self
60
+ end
61
+
62
+ # experimental
63
+ def page(value)
64
+ clone.page!(value)
65
+ end
66
+
67
+ # experimental
68
+ def page!(value)
69
+ check_loaded
70
+ @options[:page] = value
71
+ self
72
+ end
73
+
74
+ # experimental
75
+ def per_page(value = NO_DEFAULT_VALUE)
76
+ # TODO remove in Searchkick 6
77
+ if value == NO_DEFAULT_VALUE
78
+ private_execute.per_page
79
+ else
80
+ clone.per_page!(value)
81
+ end
82
+ end
83
+
84
+ # experimental
85
+ def per_page!(value)
86
+ check_loaded
87
+ @options[:per_page] = value
88
+ self
89
+ end
90
+
91
+ # experimental
92
+ def where(value = NO_DEFAULT_VALUE)
93
+ if value == NO_DEFAULT_VALUE
94
+ Where.new(self)
95
+ else
96
+ clone.where!(value)
97
+ end
98
+ end
99
+
100
+ # experimental
101
+ def where!(value)
102
+ check_loaded
103
+ if @options[:where]
104
+ @options[:where] = {_and: [@options[:where], ensure_permitted(value)]}
105
+ else
106
+ @options[:where] = ensure_permitted(value)
107
+ end
108
+ self
109
+ end
110
+
111
+ # experimental
112
+ def rewhere(value)
113
+ clone.rewhere!(value)
114
+ end
115
+
116
+ # experimental
117
+ def rewhere!(value)
118
+ check_loaded
119
+ @options[:where] = ensure_permitted(value)
120
+ self
121
+ end
122
+
123
+ # experimental
124
+ def order(*values)
125
+ clone.order!(*values)
126
+ end
127
+
128
+ # experimental
129
+ def order!(*values)
130
+ values = values.first if values.size == 1 && values.first.is_a?(Array)
131
+ check_loaded
132
+ (@options[:order] ||= []).concat(values)
133
+ self
134
+ end
135
+
136
+ # experimental
137
+ def reorder(*values)
138
+ clone.reorder!(*values)
139
+ end
140
+
141
+ # experimental
142
+ def reorder!(*values)
143
+ check_loaded
144
+ @options[:order] = values
145
+ self
146
+ end
147
+
148
+ # experimental
149
+ def select(*values, &block)
150
+ if block_given?
151
+ private_execute.select(*values, &block)
152
+ else
153
+ clone.select!(*values)
154
+ end
155
+ end
156
+
157
+ # experimental
158
+ def select!(*values)
159
+ check_loaded
160
+ (@options[:select] ||= []).concat(values)
161
+ self
162
+ end
163
+
164
+ # experimental
165
+ def reselect(*values)
166
+ clone.reselect!(*values)
167
+ end
168
+
169
+ # experimental
170
+ def reselect!(*values)
171
+ check_loaded
172
+ @options[:select] = values
173
+ self
174
+ end
175
+
176
+ # experimental
177
+ def includes(*values)
178
+ clone.includes!(*values)
179
+ end
180
+
181
+ # experimental
182
+ def includes!(*values)
183
+ check_loaded
184
+ (@options[:includes] ||= []).concat(values)
185
+ self
186
+ end
187
+
188
+ # experimental
189
+ def only(*keys)
190
+ Relation.new(@model, @term, **@options.slice(*keys))
191
+ end
192
+
193
+ # experimental
194
+ def except(*keys)
195
+ Relation.new(@model, @term, **@options.except(*keys))
196
+ end
197
+
198
+ def loaded?
199
+ !@execute.nil?
200
+ end
201
+
26
202
  private
27
203
 
28
204
  def private_execute
29
- @execute ||= @query.execute
205
+ @execute ||= query.execute
30
206
  end
31
207
 
32
208
  def query
33
- @query
209
+ @query ||= Query.new(@model, @term, **@options)
210
+ end
211
+
212
+ def check_loaded
213
+ raise Error, "Relation loaded" if loaded?
214
+
215
+ # reset query since options will change
216
+ @query = nil
217
+ end
218
+
219
+ # provides *very* basic protection from unfiltered parameters
220
+ # this is not meant to be comprehensive and may be expanded in the future
221
+ def ensure_permitted(obj)
222
+ obj.to_h
34
223
  end
35
224
  end
36
225
  end
@@ -141,7 +141,7 @@ module Searchkick
141
141
 
142
142
  def hits
143
143
  if error
144
- raise Searchkick::Error, "Query error - use the error method to view it"
144
+ raise Error, "Query error - use the error method to view it"
145
145
  else
146
146
  @response["hits"]["hits"]
147
147
  end
@@ -178,7 +178,7 @@ module Searchkick
178
178
  end
179
179
 
180
180
  def scroll
181
- raise Searchkick::Error, "Pass `scroll` option to the search method for scrolling" unless scroll_id
181
+ raise Error, "Pass `scroll` option to the search method for scrolling" unless scroll_id
182
182
 
183
183
  if block_given?
184
184
  records = self
@@ -191,10 +191,10 @@ module Searchkick
191
191
  else
192
192
  begin
193
193
  # TODO Active Support notifications for this scroll call
194
- Searchkick::Results.new(@klass, Searchkick.client.scroll(scroll: options[:scroll], body: {scroll_id: scroll_id}), @options)
194
+ Results.new(@klass, Searchkick.client.scroll(scroll: options[:scroll], body: {scroll_id: scroll_id}), @options)
195
195
  rescue => e
196
196
  if Searchkick.not_found_error?(e) && e.message =~ /search_context_missing_exception/i
197
- raise Searchkick::Error, "Scroll id has expired"
197
+ raise Error, "Scroll id has expired"
198
198
  else
199
199
  raise e
200
200
  end
@@ -232,7 +232,7 @@ module Searchkick
232
232
  index_alias = index.split("_")[0..-2].join("_")
233
233
  Array((options[:index_mapping] || {})[index_alias])
234
234
  end
235
- raise Searchkick::Error, "Unknown model for index: #{index}. Pass the `models` option to the search method." unless models.any?
235
+ raise Error, "Unknown model for index: #{index}. Pass the `models` option to the search method." unless models.any?
236
236
  index_models[index] = models
237
237
  end
238
238
 
@@ -1,3 +1,3 @@
1
1
  module Searchkick
2
- VERSION = "5.0.0"
2
+ VERSION = "5.0.3"
3
3
  end
@@ -0,0 +1,11 @@
1
+ module Searchkick
2
+ class Where
3
+ def initialize(relation)
4
+ @relation = relation
5
+ end
6
+
7
+ def not(value)
8
+ @relation.where(_not: value)
9
+ end
10
+ end
11
+ end
data/lib/searchkick.rb CHANGED
@@ -27,6 +27,7 @@ require "searchkick/relation"
27
27
  require "searchkick/relation_indexer"
28
28
  require "searchkick/results"
29
29
  require "searchkick/version"
30
+ require "searchkick/where"
30
31
 
31
32
  # integrations
32
33
  require "searchkick/railtie" if defined?(Rails)
@@ -171,7 +172,7 @@ module Searchkick
171
172
  end
172
173
 
173
174
  options = options.merge(block: block) if block
174
- Searchkick::Relation.new(klass, term, **options)
175
+ Relation.new(klass, term, **options)
175
176
  end
176
177
 
177
178
  def self.multi_search(queries)
@@ -183,7 +184,7 @@ module Searchkick
183
184
  body: queries.flat_map { |q| [q.params.except(:body).to_json, q.body.to_json] }.map { |v| "#{v}\n" }.join,
184
185
  }
185
186
  ActiveSupport::Notifications.instrument("multi_search.searchkick", event) do
186
- Searchkick::MultiSearch.new(queries).perform
187
+ MultiSearch.new(queries).perform
187
188
  end
188
189
  end
189
190
 
@@ -241,9 +242,9 @@ module Searchkick
241
242
  end
242
243
 
243
244
  def self.reindex_status(index_name)
244
- raise Searchkick::Error, "Redis not configured" unless redis
245
+ raise Error, "Redis not configured" unless redis
245
246
 
246
- batches_left = Searchkick::Index.new(index_name).batches_left
247
+ batches_left = Index.new(index_name).batches_left
247
248
  {
248
249
  completed: batches_left == 0,
249
250
  batches_left: batches_left
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: searchkick
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0
4
+ version: 5.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-22 00:00:00.000000000 Z
11
+ date: 2022-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -71,6 +71,7 @@ files:
71
71
  - lib/searchkick/relation_indexer.rb
72
72
  - lib/searchkick/results.rb
73
73
  - lib/searchkick/version.rb
74
+ - lib/searchkick/where.rb
74
75
  - lib/tasks/searchkick.rake
75
76
  homepage: https://github.com/ankane/searchkick
76
77
  licenses:
@@ -91,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
92
  - !ruby/object:Gem::Version
92
93
  version: '0'
93
94
  requirements: []
94
- rubygems_version: 3.3.3
95
+ rubygems_version: 3.3.7
95
96
  signing_key:
96
97
  specification_version: 4
97
98
  summary: Intelligent search made easy with Rails and Elasticsearch or OpenSearch