searchkick 3.1.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/CONTRIBUTING.md +9 -7
  4. data/README.md +86 -24
  5. data/lib/searchkick/bulk_indexer.rb +1 -1
  6. data/lib/searchkick/index_options.rb +12 -0
  7. data/lib/searchkick/model.rb +2 -2
  8. data/lib/searchkick/query.rb +36 -21
  9. data/lib/searchkick/record_data.rb +2 -2
  10. data/lib/searchkick/results.rb +2 -2
  11. data/lib/searchkick/version.rb +1 -1
  12. metadata +8 -106
  13. data/.github/ISSUE_TEMPLATE.md +0 -7
  14. data/.gitignore +0 -22
  15. data/.travis.yml +0 -33
  16. data/Gemfile +0 -16
  17. data/Rakefile +0 -16
  18. data/benchmark/Gemfile +0 -24
  19. data/benchmark/index.rb +0 -99
  20. data/benchmark/search.rb +0 -48
  21. data/docs/Searchkick-3-Upgrade.md +0 -57
  22. data/searchkick.gemspec +0 -30
  23. data/test/aggs_test.rb +0 -217
  24. data/test/autocomplete_test.rb +0 -81
  25. data/test/boost_test.rb +0 -225
  26. data/test/callbacks_test.rb +0 -59
  27. data/test/ci/before_install.sh +0 -17
  28. data/test/errors_test.rb +0 -19
  29. data/test/gemfiles/activerecord42.gemfile +0 -7
  30. data/test/gemfiles/activerecord50.gemfile +0 -7
  31. data/test/gemfiles/activerecord51.gemfile +0 -7
  32. data/test/gemfiles/apartment.gemfile +0 -8
  33. data/test/gemfiles/cequel.gemfile +0 -8
  34. data/test/gemfiles/mongoid5.gemfile +0 -7
  35. data/test/gemfiles/mongoid6.gemfile +0 -12
  36. data/test/gemfiles/nobrainer.gemfile +0 -8
  37. data/test/gemfiles/parallel_tests.gemfile +0 -8
  38. data/test/geo_shape_test.rb +0 -171
  39. data/test/highlight_test.rb +0 -109
  40. data/test/index_test.rb +0 -168
  41. data/test/inheritance_test.rb +0 -82
  42. data/test/language_test.rb +0 -79
  43. data/test/marshal_test.rb +0 -13
  44. data/test/match_test.rb +0 -293
  45. data/test/misspellings_test.rb +0 -56
  46. data/test/model_test.rb +0 -40
  47. data/test/multi_search_test.rb +0 -37
  48. data/test/multi_tenancy_test.rb +0 -22
  49. data/test/order_test.rb +0 -40
  50. data/test/pagination_test.rb +0 -96
  51. data/test/partial_reindex_test.rb +0 -65
  52. data/test/query_test.rb +0 -43
  53. data/test/reindex_test.rb +0 -87
  54. data/test/reindex_v2_job_test.rb +0 -27
  55. data/test/routing_test.rb +0 -23
  56. data/test/should_index_test.rb +0 -32
  57. data/test/similar_test.rb +0 -28
  58. data/test/sql_test.rb +0 -190
  59. data/test/suggest_test.rb +0 -100
  60. data/test/support/kaminari.yml +0 -21
  61. data/test/synonyms_test.rb +0 -69
  62. data/test/test_helper.rb +0 -593
  63. data/test/where_test.rb +0 -249
@@ -1,56 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class MisspellingsTest < Minitest::Test
4
- def test_misspellings
5
- store_names ["abc", "abd", "aee"]
6
- assert_search "abc", ["abc"], misspellings: false
7
- end
8
-
9
- def test_misspellings_distance
10
- store_names ["abbb", "aabb"]
11
- assert_search "aaaa", ["aabb"], misspellings: {distance: 2}
12
- end
13
-
14
- def test_misspellings_prefix_length
15
- store_names ["ap", "api", "apt", "any", "nap", "ah", "ahi"]
16
- assert_search "ap", ["ap"], misspellings: {prefix_length: 2}
17
- assert_search "api", ["ap", "api", "apt"], misspellings: {prefix_length: 2}
18
- end
19
-
20
- def test_misspellings_prefix_length_operator
21
- store_names ["ap", "api", "apt", "any", "nap", "ah", "aha"]
22
- assert_search "ap ah", ["ap", "ah"], operator: "or", misspellings: {prefix_length: 2}
23
- assert_search "api ahi", ["ap", "api", "apt", "ah", "aha"], operator: "or", misspellings: {prefix_length: 2}
24
- end
25
-
26
- def test_misspellings_fields_operator
27
- store [
28
- {name: "red", color: "red"},
29
- {name: "blue", color: "blue"},
30
- {name: "cyan", color: "blue green"},
31
- {name: "magenta", color: "red blue"},
32
- {name: "green", color: "green"}
33
- ]
34
- assert_search "red blue", ["red", "blue", "cyan", "magenta"], operator: "or", fields: ["color"], misspellings: false
35
- end
36
-
37
- def test_misspellings_below_unmet
38
- store_names ["abc", "abd", "aee"]
39
- assert_search "abc", ["abc", "abd"], misspellings: {below: 2}
40
- end
41
-
42
- def test_misspellings_below_unmet_result
43
- store_names ["abc", "abd", "aee"]
44
- assert Product.search("abc", misspellings: {below: 2}).misspellings?
45
- end
46
-
47
- def test_misspellings_below_met
48
- store_names ["abc", "abd", "aee"]
49
- assert_search "abc", ["abc"], misspellings: {below: 1}
50
- end
51
-
52
- def test_misspellings_below_met_result
53
- store_names ["abc", "abd", "aee"]
54
- assert !Product.search("abc", misspellings: {below: 1}).misspellings?
55
- end
56
- end
@@ -1,40 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class ModelTest < Minitest::Test
4
- def test_disable_callbacks_model
5
- store_names ["product a"]
6
-
7
- Searchkick.callbacks(false) do
8
- store_names ["product b"]
9
- end
10
- assert_search "product", ["product a"]
11
-
12
- Product.reindex
13
-
14
- assert_search "product", ["product a", "product b"]
15
- end
16
-
17
- def test_disable_callbacks_global
18
- # make sure callbacks default to on
19
- assert Searchkick.callbacks?
20
-
21
- store_names ["product a"]
22
-
23
- Searchkick.disable_callbacks
24
- assert !Searchkick.callbacks?
25
-
26
- store_names ["product b"]
27
- assert_search "product", ["product a"]
28
-
29
- Searchkick.enable_callbacks
30
- Product.reindex
31
-
32
- assert_search "product", ["product a", "product b"]
33
- end
34
-
35
- def test_multiple_models
36
- store_names ["Product A"]
37
- store_names ["Product B"], Speaker
38
- assert_equal Product.all.to_a + Speaker.all.to_a, Searchkick.search("product", index_name: [Product, Speaker], fields: [:name], order: "name").to_a
39
- end
40
- end
@@ -1,37 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class MultiSearchTest < Minitest::Test
4
- def test_basic
5
- store_names ["Product A"]
6
- store_names ["Store A"], Store
7
- products = Product.search("*", execute: false)
8
- stores = Store.search("*", execute: false)
9
- Searchkick.multi_search([products, stores])
10
- assert_equal ["Product A"], products.map(&:name)
11
- assert_equal ["Store A"], stores.map(&:name)
12
- end
13
-
14
- def test_error
15
- store_names ["Product A"]
16
- products = Product.search("*", execute: false)
17
- stores = Store.search("*", order: [:bad_field], execute: false)
18
- Searchkick.multi_search([products, stores])
19
- assert !products.error
20
- assert stores.error
21
- end
22
-
23
- def test_misspellings_below_unmet
24
- store_names ["abc", "abd", "aee"]
25
- products = Product.search("abc", misspellings: {below: 5}, execute: false)
26
- Searchkick.multi_search([products])
27
- assert_equal ["abc", "abd"], products.map(&:name)
28
- end
29
-
30
- def test_error
31
- products = Product.search("*", order: {bad_column: :asc}, execute: false)
32
- Searchkick.multi_search([products])
33
- assert products.error
34
- error = assert_raises(Searchkick::Error) { products.results }
35
- assert_equal error.message, "Query error - use the error method to view it"
36
- end
37
- end
@@ -1,22 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class MultiTenancyTest < Minitest::Test
4
- def setup
5
- skip unless defined?(Apartment)
6
- end
7
-
8
- def test_basic
9
- Apartment::Tenant.switch!("tenant1")
10
- store_names ["Product A"], Tenant
11
- Apartment::Tenant.switch!("tenant2")
12
- store_names ["Product B"], Tenant
13
- Apartment::Tenant.switch!("tenant1")
14
- assert_search "product", ["Product A"], {load: false}, Tenant
15
- Apartment::Tenant.switch!("tenant2")
16
- assert_search "product", ["Product B"], {load: false}, Tenant
17
- end
18
-
19
- def teardown
20
- Apartment::Tenant.reset if defined?(Apartment)
21
- end
22
- end
@@ -1,40 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class OrderTest < Minitest::Test
4
- def test_order_hash
5
- store_names ["Product A", "Product B", "Product C", "Product D"]
6
- assert_order "product", ["Product D", "Product C", "Product B", "Product A"], order: {name: :desc}
7
- end
8
-
9
- def test_order_string
10
- store_names ["Product A", "Product B", "Product C", "Product D"]
11
- assert_order "product", ["Product A", "Product B", "Product C", "Product D"], order: "name"
12
- end
13
-
14
- def test_order_id
15
- skip if cequel?
16
-
17
- store_names ["Product A", "Product B"]
18
- product_a = Product.where(name: "Product A").first
19
- product_b = Product.where(name: "Product B").first
20
- assert_order "product", [product_a, product_b].sort_by(&:id).map(&:name), order: {id: :asc}
21
- end
22
-
23
- def test_order_multiple
24
- store [
25
- {name: "Product A", color: "blue", store_id: 1},
26
- {name: "Product B", color: "red", store_id: 3},
27
- {name: "Product C", color: "red", store_id: 2}
28
- ]
29
- assert_order "product", ["Product A", "Product B", "Product C"], order: {color: :asc, store_id: :desc}
30
- end
31
-
32
- def test_order_unmapped_type
33
- assert_order "product", [], order: {not_mapped: {unmapped_type: "long"}}
34
- end
35
-
36
- def test_order_array
37
- store [{name: "San Francisco", latitude: 37.7833, longitude: -122.4167}]
38
- assert_order "francisco", ["San Francisco"], order: [{_geo_distance: {location: "0,0"}}]
39
- end
40
- end
@@ -1,96 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class PaginationTest < Minitest::Test
4
- def test_limit
5
- store_names ["Product A", "Product B", "Product C", "Product D"]
6
- assert_order "product", ["Product A", "Product B"], order: {name: :asc}, limit: 2
7
- end
8
-
9
- def test_no_limit
10
- names = 20.times.map { |i| "Product #{i}" }
11
- store_names names
12
- assert_search "product", names
13
- end
14
-
15
- def test_offset
16
- store_names ["Product A", "Product B", "Product C", "Product D"]
17
- assert_order "product", ["Product C", "Product D"], order: {name: :asc}, offset: 2, limit: 100
18
- end
19
-
20
- def test_pagination
21
- store_names ["Product A", "Product B", "Product C", "Product D", "Product E", "Product F"]
22
- products = Product.search("product", order: {name: :asc}, page: 2, per_page: 2, padding: 1)
23
- assert_equal ["Product D", "Product E"], products.map(&:name)
24
- assert_equal "product", products.entry_name
25
- assert_equal 2, products.current_page
26
- assert_equal 1, products.padding
27
- assert_equal 2, products.per_page
28
- assert_equal 2, products.size
29
- assert_equal 2, products.length
30
- assert_equal 3, products.total_pages
31
- assert_equal 6, products.total_count
32
- assert_equal 6, products.total_entries
33
- assert_equal 2, products.limit_value
34
- assert_equal 3, products.offset_value
35
- assert_equal 3, products.offset
36
- assert_equal 3, products.next_page
37
- assert_equal 1, products.previous_page
38
- assert_equal 1, products.prev_page
39
- assert !products.first_page?
40
- assert !products.last_page?
41
- assert !products.empty?
42
- assert !products.out_of_range?
43
- assert products.any?
44
- end
45
-
46
- def test_pagination_body
47
- store_names ["Product A", "Product B", "Product C", "Product D", "Product E", "Product F"]
48
- products = Product.search("product", body: {query: {match_all: {}}, sort: [{name: "asc"}]}, page: 2, per_page: 2, padding: 1)
49
- assert_equal ["Product D", "Product E"], products.map(&:name)
50
- assert_equal "product", products.entry_name
51
- assert_equal 2, products.current_page
52
- assert_equal 1, products.padding
53
- assert_equal 2, products.per_page
54
- assert_equal 2, products.size
55
- assert_equal 2, products.length
56
- assert_equal 3, products.total_pages
57
- assert_equal 6, products.total_count
58
- assert_equal 6, products.total_entries
59
- assert_equal 2, products.limit_value
60
- assert_equal 3, products.offset_value
61
- assert_equal 3, products.offset
62
- assert_equal 3, products.next_page
63
- assert_equal 1, products.previous_page
64
- assert_equal 1, products.prev_page
65
- assert !products.first_page?
66
- assert !products.last_page?
67
- assert !products.empty?
68
- assert !products.out_of_range?
69
- assert products.any?
70
- end
71
-
72
- def test_pagination_nil_page
73
- store_names ["Product A", "Product B", "Product C", "Product D", "Product E"]
74
- products = Product.search("product", order: {name: :asc}, page: nil, per_page: 2)
75
- assert_equal ["Product A", "Product B"], products.map(&:name)
76
- assert_equal 1, products.current_page
77
- assert products.first_page?
78
- end
79
-
80
- def test_kaminari
81
- skip unless defined?(Kaminari)
82
-
83
- require "action_view"
84
-
85
- I18n.load_path = Dir["test/support/kaminari.yml"]
86
- I18n.backend.load_translations
87
-
88
- view = ActionView::Base.new
89
-
90
- store_names ["Product A"]
91
- assert_equal "Displaying <b>1</b> product", view.page_entries_info(Product.search("product"))
92
-
93
- store_names ["Product B"]
94
- assert_equal "Displaying <b>all 2</b> products", view.page_entries_info(Product.search("product"))
95
- end
96
- end
@@ -1,65 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class PartialReindexTest < Minitest::Test
4
- def test_class_method
5
- store [{name: "Hi", color: "Blue"}]
6
-
7
- # normal search
8
- assert_search "hi", ["Hi"], fields: [:name], load: false
9
- assert_search "blue", ["Hi"], fields: [:color], load: false
10
-
11
- # update
12
- product = Product.first
13
- product.name = "Bye"
14
- product.color = "Red"
15
- Searchkick.callbacks(false) do
16
- product.save!
17
- end
18
- Product.searchkick_index.refresh
19
-
20
- # index not updated
21
- assert_search "hi", ["Hi"], fields: [:name], load: false
22
- assert_search "blue", ["Hi"], fields: [:color], load: false
23
-
24
- # partial reindex
25
- Product.reindex(:search_name)
26
-
27
- # name updated, but not color
28
- assert_search "bye", ["Bye"], fields: [:name], load: false
29
- assert_search "blue", ["Bye"], fields: [:color], load: false
30
- end
31
-
32
- def test_instance_method
33
- store [{name: "Hi", color: "Blue"}]
34
-
35
- # normal search
36
- assert_search "hi", ["Hi"], fields: [:name], load: false
37
- assert_search "blue", ["Hi"], fields: [:color], load: false
38
-
39
- # update
40
- product = Product.first
41
- product.name = "Bye"
42
- product.color = "Red"
43
- Searchkick.callbacks(false) do
44
- product.save!
45
- end
46
- Product.searchkick_index.refresh
47
-
48
- # index not updated
49
- assert_search "hi", ["Hi"], fields: [:name], load: false
50
- assert_search "blue", ["Hi"], fields: [:color], load: false
51
-
52
- product.reindex(:search_name, refresh: true)
53
-
54
- # name updated, but not color
55
- assert_search "bye", ["Bye"], fields: [:name], load: false
56
- assert_search "blue", ["Bye"], fields: [:color], load: false
57
- end
58
-
59
- def test_instance_method_async
60
- skip unless defined?(ActiveJob)
61
-
62
- product = Product.create!(name: "Hi")
63
- product.reindex(:search_data, mode: :async)
64
- end
65
- end
@@ -1,43 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class QueryTest < Minitest::Test
4
- def test_basic
5
- store_names ["Milk", "Apple"]
6
- query = Product.search("milk", execute: false)
7
- # query.body = {query: {match_all: {}}}
8
- # query.body = {query: {match: {name: "Apple"}}}
9
- query.body[:query] = {match_all: {}}
10
- assert_equal ["Apple", "Milk"], query.map(&:name).sort
11
- assert_equal ["Apple", "Milk"], query.execute.map(&:name).sort
12
- end
13
-
14
- def test_with_effective_min_score
15
- store_names ["Milk", "Milk2"]
16
- assert_search "milk", ["Milk"], body_options: {min_score: 1}
17
- end
18
-
19
- def test_with_uneffective_min_score
20
- store_names ["Milk", "Milk2"]
21
- assert_search "milk", ["Milk", "Milk2"], body_options: {min_score: 0.0001}
22
- end
23
-
24
- def test_default_timeout
25
- assert_equal "6s", Product.search("*", execute: false).body[:timeout]
26
- end
27
-
28
- def test_timeout_override
29
- assert_equal "1s", Product.search("*", body_options: {timeout: "1s"}, execute: false).body[:timeout]
30
- end
31
-
32
- def test_request_params
33
- assert_equal "dfs_query_then_fetch", Product.search("*", request_params: {search_type: "dfs_query_then_fetch"}, execute: false).params[:search_type]
34
- end
35
-
36
- def test_debug
37
- store_names ["Milk"]
38
- out, _ = capture_io do
39
- assert_search "milk", ["Milk"], debug: true
40
- end
41
- refute_includes out, "Error"
42
- end
43
- end
@@ -1,87 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class ReindexTest < Minitest::Test
4
- def setup
5
- super
6
- Sku.destroy_all
7
- end
8
-
9
- def test_scoped
10
- skip if nobrainer? || cequel?
11
-
12
- store_names ["Product A"]
13
- Searchkick.callbacks(false) do
14
- store_names ["Product B", "Product C"]
15
- end
16
- Product.where(name: "Product B").reindex(refresh: true)
17
- assert_search "product", ["Product A", "Product B"]
18
- end
19
-
20
- def test_associations
21
- skip if nobrainer? || cequel?
22
-
23
- store_names ["Product A"]
24
- store = Store.create!(name: "Test")
25
- Product.create!(name: "Product B", store_id: store.id)
26
- store.products.reindex(refresh: true)
27
- assert_search "product", ["Product A", "Product B"]
28
- end
29
-
30
- def test_async
31
- skip unless defined?(ActiveJob)
32
-
33
- Searchkick.callbacks(false) do
34
- store_names ["Product A"]
35
- end
36
- reindex = Product.reindex(async: true)
37
- assert_search "product", [], conversions: false
38
-
39
- index = Searchkick::Index.new(reindex[:index_name])
40
- index.refresh
41
- assert_equal 1, index.total_docs
42
-
43
- if defined?(Redis)
44
- assert Searchkick.reindex_status(reindex[:name])
45
- end
46
-
47
- Product.searchkick_index.promote(reindex[:index_name])
48
- assert_search "product", ["Product A"]
49
- end
50
-
51
- def test_async_wait
52
- skip unless defined?(ActiveJob) && defined?(Redis)
53
-
54
- Searchkick.callbacks(false) do
55
- store_names ["Product A"]
56
- end
57
-
58
- capture_io do
59
- Product.reindex(async: {wait: true})
60
- end
61
-
62
- assert_search "product", ["Product A"]
63
- end
64
-
65
- def test_async_non_integer_pk
66
- skip unless defined?(ActiveJob)
67
-
68
- Sku.create(id: SecureRandom.hex, name: "Test")
69
- reindex = Sku.reindex(async: true)
70
- assert_search "sku", [], conversions: false
71
-
72
- index = Searchkick::Index.new(reindex[:index_name])
73
- index.refresh
74
- assert_equal 1, index.total_docs
75
- end
76
-
77
- def test_refresh_interval
78
- reindex = Product.reindex(refresh_interval: "30s", async: true, import: false)
79
- index = Searchkick::Index.new(reindex[:index_name])
80
- assert_nil Product.search_index.refresh_interval
81
- assert_equal "30s", index.refresh_interval
82
-
83
- Product.search_index.promote(index.name, update_refresh_interval: true)
84
- assert_equal "1s", index.refresh_interval
85
- assert_equal "1s", Product.search_index.refresh_interval
86
- end
87
- end