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,27 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class ReindexV2JobTest < Minitest::Test
4
- def setup
5
- skip unless defined?(ActiveJob)
6
- super
7
- end
8
-
9
- def test_create
10
- product = Searchkick.callbacks(false) { Product.create!(name: "Boom") }
11
- Product.search_index.refresh
12
- assert_search "*", []
13
- Searchkick::ReindexV2Job.perform_later("Product", product.id.to_s)
14
- Product.search_index.refresh
15
- assert_search "*", ["Boom"]
16
- end
17
-
18
- def test_destroy
19
- product = Searchkick.callbacks(false) { Product.create!(name: "Boom") }
20
- Product.reindex
21
- assert_search "*", ["Boom"]
22
- Searchkick.callbacks(false) { product.destroy }
23
- Searchkick::ReindexV2Job.perform_later("Product", product.id.to_s)
24
- Product.search_index.refresh
25
- assert_search "*", []
26
- end
27
- end
@@ -1,23 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class RoutingTest < Minitest::Test
4
- def test_routing_query
5
- query = Store.search("Dollar Tree", routing: "Dollar Tree", execute: false)
6
- assert_equal query.params[:routing], "Dollar Tree"
7
- end
8
-
9
- def test_routing_mappings
10
- index_options = Store.searchkick_index.index_options
11
- assert_equal index_options[:mappings][:store][:_routing], required: true
12
- end
13
-
14
- def test_routing_correct_node
15
- store_names ["Dollar Tree"], Store
16
- assert_search "*", ["Dollar Tree"], {routing: "Dollar Tree"}, Store
17
- end
18
-
19
- def test_routing_incorrect_node
20
- store_names ["Dollar Tree"], Store
21
- assert_search "*", ["Dollar Tree"], {routing: "Boom"}, Store
22
- end
23
- end
@@ -1,32 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class ShouldIndexTest < Minitest::Test
4
- def test_basic
5
- store_names ["INDEX", "DO NOT INDEX"]
6
- assert_search "index", ["INDEX"]
7
- end
8
-
9
- def test_default_true
10
- assert Animal.new.should_index?
11
- end
12
-
13
- def test_change_to_true
14
- store_names ["DO NOT INDEX"]
15
- assert_search "index", []
16
- product = Product.first
17
- product.name = "INDEX"
18
- product.save!
19
- Product.searchkick_index.refresh
20
- assert_search "index", ["INDEX"]
21
- end
22
-
23
- def test_change_to_false
24
- store_names ["INDEX"]
25
- assert_search "index", ["INDEX"]
26
- product = Product.first
27
- product.name = "DO NOT INDEX"
28
- product.save!
29
- Product.searchkick_index.refresh
30
- assert_search "index", []
31
- end
32
- end
@@ -1,28 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class SimilarTest < Minitest::Test
4
- def test_similar
5
- store_names ["Annie's Naturals Organic Shiitake & Sesame Dressing"]
6
- assert_search "Annie's Naturals Shiitake & Sesame Vinaigrette", ["Annie's Naturals Organic Shiitake & Sesame Dressing"], similar: true, fields: [:name]
7
- end
8
-
9
- def test_fields
10
- store_names ["1% Organic Milk", "2% Organic Milk", "Popcorn"]
11
- assert_equal ["2% Organic Milk"], Product.where(name: "1% Organic Milk").first.similar(fields: ["name"]).map(&:name)
12
- end
13
-
14
- def test_order
15
- store_names ["Lucerne Milk Chocolate Fat Free", "Clover Fat Free Milk"]
16
- assert_order "Lucerne Fat Free Chocolate Milk", ["Lucerne Milk Chocolate Fat Free", "Clover Fat Free Milk"], similar: true, fields: [:name]
17
- end
18
-
19
- def test_limit
20
- store_names ["1% Organic Milk", "2% Organic Milk", "Fat Free Organic Milk", "Popcorn"]
21
- assert_equal ["2% Organic Milk"], Product.where(name: "1% Organic Milk").first.similar(fields: ["name"], order: ["name"], limit: 1).map(&:name)
22
- end
23
-
24
- def test_per_page
25
- store_names ["1% Organic Milk", "2% Organic Milk", "Fat Free Organic Milk", "Popcorn"]
26
- assert_equal ["2% Organic Milk"], Product.where(name: "1% Organic Milk").first.similar(fields: ["name"], order: ["name"], per_page: 1).map(&:name)
27
- end
28
- end
@@ -1,190 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class SqlTest < Minitest::Test
4
- def test_operator
5
- store_names ["Honey"]
6
- assert_search "fresh honey", []
7
- assert_search "fresh honey", ["Honey"], operator: "or"
8
- end
9
-
10
- def test_operator_scoring
11
- store_names ["Big Red Circle", "Big Green Circle", "Small Orange Circle"]
12
- assert_order "big red circle", ["Big Red Circle", "Big Green Circle", "Small Orange Circle"], operator: "or"
13
- end
14
-
15
- def test_fields_operator
16
- store [
17
- {name: "red", color: "red"},
18
- {name: "blue", color: "blue"},
19
- {name: "cyan", color: "blue green"},
20
- {name: "magenta", color: "red blue"},
21
- {name: "green", color: "green"}
22
- ]
23
- assert_search "red blue", ["red", "blue", "cyan", "magenta"], operator: "or", fields: ["color"]
24
- end
25
-
26
- def test_fields
27
- store [
28
- {name: "red", color: "light blue"},
29
- {name: "blue", color: "red fish"}
30
- ]
31
- assert_search "blue", ["red"], fields: ["color"]
32
- end
33
-
34
- def test_non_existent_field
35
- store_names ["Milk"]
36
- assert_search "milk", [], fields: ["not_here"]
37
- end
38
-
39
- def test_fields_both_match
40
- store [
41
- {name: "Blue A", color: "red"},
42
- {name: "Blue B", color: "light blue"}
43
- ]
44
- assert_first "blue", "Blue B", fields: [:name, :color]
45
- end
46
-
47
- def test_big_decimal
48
- store [
49
- {name: "Product", latitude: 80.0}
50
- ]
51
- assert_search "product", ["Product"], where: {latitude: {gt: 79}}
52
- end
53
-
54
- # body_options
55
-
56
- def test_body_options_should_merge_into_body
57
- query = Product.search("*", body_options: {min_score: 1.0}, execute: false)
58
- assert_equal 1.0, query.body[:min_score]
59
- end
60
-
61
- # load
62
-
63
- def test_load_default
64
- store_names ["Product A"]
65
- assert_kind_of Product, Product.search("product").first
66
- end
67
-
68
- def test_load_false
69
- store_names ["Product A"]
70
- assert_kind_of Hash, Product.search("product", load: false).first
71
- end
72
-
73
- def test_load_false_methods
74
- store_names ["Product A"]
75
- assert_equal "Product A", Product.search("product", load: false).first.name
76
- end
77
-
78
- def test_load_false_with_includes
79
- store_names ["Product A"]
80
- assert_kind_of Hash, Product.search("product", load: false, includes: [:store]).first
81
- end
82
-
83
- def test_load_false_nested_object
84
- aisle = {"id" => 1, "name" => "Frozen"}
85
- store [{name: "Product A", aisle: aisle}]
86
- assert_equal aisle, Product.search("product", load: false).first.aisle.to_hash
87
- end
88
-
89
- # select
90
-
91
- def test_select
92
- store [{name: "Product A", store_id: 1}]
93
- result = Product.search("product", load: false, select: [:name, :store_id]).first
94
- assert_equal %w(id name store_id), result.keys.reject { |k| k.start_with?("_") }.sort
95
- assert_equal "Product A", result.name
96
- assert_equal 1, result.store_id
97
- end
98
-
99
- def test_select_array
100
- store [{name: "Product A", user_ids: [1, 2]}]
101
- result = Product.search("product", load: false, select: [:user_ids]).first
102
- assert_equal [1, 2], result.user_ids
103
- end
104
-
105
- def test_select_single_field
106
- store [{name: "Product A", store_id: 1}]
107
- result = Product.search("product", load: false, select: :name).first
108
- assert_equal %w(id name), result.keys.reject { |k| k.start_with?("_") }.sort
109
- assert_equal "Product A", result.name
110
- assert_nil result.store_id
111
- end
112
-
113
- def test_select_all
114
- store [{name: "Product A", user_ids: [1, 2]}]
115
- hit = Product.search("product", select: true).hits.first
116
- assert_equal hit["_source"]["name"], "Product A"
117
- assert_equal hit["_source"]["user_ids"], [1, 2]
118
- end
119
-
120
- def test_select_none
121
- store [{name: "Product A", user_ids: [1, 2]}]
122
- hit = Product.search("product", select: []).hits.first
123
- assert_nil hit["_source"]
124
- hit = Product.search("product", select: false).hits.first
125
- assert_nil hit["_source"]
126
- end
127
-
128
- def test_select_includes
129
- store [{name: "Product A", user_ids: [1, 2]}]
130
- result = Product.search("product", load: false, select: {includes: [:name]}).first
131
- assert_equal %w(id name), result.keys.reject { |k| k.start_with?("_") }.sort
132
- assert_equal "Product A", result.name
133
- assert_nil result.store_id
134
- end
135
-
136
- def test_select_excludes
137
- store [{name: "Product A", user_ids: [1, 2], store_id: 1}]
138
- result = Product.search("product", load: false, select: {excludes: [:name]}).first
139
- assert_nil result.name
140
- assert_equal [1, 2], result.user_ids
141
- assert_equal 1, result.store_id
142
- end
143
-
144
- def test_select_include_and_excludes
145
- # let's take this to the next level
146
- store [{name: "Product A", user_ids: [1, 2], store_id: 1}]
147
- result = Product.search("product", load: false, select: {includes: [:store_id], excludes: [:name]}).first
148
- assert_equal 1, result.store_id
149
- assert_nil result.name
150
- assert_nil result.user_ids
151
- end
152
-
153
- # nested
154
-
155
- def test_nested_search
156
- store [{name: "Product A", aisle: {"id" => 1, "name" => "Frozen"}}], Speaker
157
- assert_search "frozen", ["Product A"], {fields: ["aisle.name"]}, Speaker
158
- end
159
-
160
- # other tests
161
-
162
- def test_includes
163
- skip unless defined?(ActiveRecord)
164
- store_names ["Product A"]
165
- assert Product.search("product", includes: [:store]).first.association(:store).loaded?
166
- end
167
-
168
- def test_model_includes
169
- skip unless defined?(ActiveRecord)
170
-
171
- store_names ["Product A"]
172
- store_names ["Store A"], Store
173
-
174
- associations = {Product => [:store], Store => [:products]}
175
- result = Searchkick.search("*", index_name: [Product, Store], model_includes: associations)
176
-
177
- assert_equal 2, result.length
178
-
179
- result.group_by(&:class).each_pair do |klass, records|
180
- assert records.first.association(associations[klass].first).loaded?
181
- end
182
- end
183
-
184
- def test_scope_results
185
- skip unless defined?(ActiveRecord)
186
-
187
- store_names ["Product A", "Product B"]
188
- assert_search "product", ["Product A"], scope_results: ->(r) { r.where(name: "Product A") }
189
- end
190
- end
@@ -1,100 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class SuggestTest < Minitest::Test
4
- def test_basic
5
- store_names ["Great White Shark", "Hammerhead Shark", "Tiger Shark"]
6
- assert_suggest "How Big is a Tigre Shar", "how big is a tiger shark", fields: [:name]
7
- end
8
-
9
- def test_perfect
10
- store_names ["Tiger Shark", "Great White Shark"]
11
- assert_suggest "Tiger Shark", nil, fields: [:name] # no correction
12
- end
13
-
14
- def test_phrase
15
- store_names ["Big Tiger Shark", "Tiger Sharp Teeth", "Tiger Sharp Mind"]
16
- assert_suggest "How to catch a big tiger shar", "how to catch a big tiger shark", fields: [:name]
17
- end
18
-
19
- def test_without_option
20
- store_names ["hi"] # needed to prevent ElasticsearchException - seed 668
21
- assert_raises(RuntimeError) { Product.search("hi").suggestions }
22
- end
23
-
24
- def test_multiple_fields
25
- store [
26
- {name: "Shark", color: "Sharp"},
27
- {name: "Shark", color: "Sharp"}
28
- ]
29
- assert_suggest_all "shar", ["shark", "sharp"]
30
- end
31
-
32
- def test_multiple_fields_highest_score_first
33
- store [
34
- {name: "Tiger Shark", color: "Sharp"}
35
- ]
36
- assert_suggest "tiger shar", "tiger shark"
37
- end
38
-
39
- def test_multiple_fields_same_value
40
- store [
41
- {name: "Shark", color: "Shark"}
42
- ]
43
- assert_suggest_all "shar", ["shark"]
44
- end
45
-
46
- def test_fields_option
47
- store [
48
- {name: "Shark", color: "Sharp"}
49
- ]
50
- assert_suggest_all "shar", ["shark"], fields: [:name]
51
- end
52
-
53
- def test_fields_option_multiple
54
- store [
55
- {name: "Shark"}
56
- ]
57
- assert_suggest "shar", "shark", fields: [:name, :unknown]
58
- end
59
-
60
- def test_fields_partial_match
61
- store_names ["Great White Shark", "Hammerhead Shark", "Tiger Shark"]
62
- assert_suggest "How Big is a Tigre Shar", "how big is a tiger shark", fields: [{name: :word_start}]
63
- end
64
-
65
- def test_fields_partial_match_boost
66
- store_names ["Great White Shark", "Hammerhead Shark", "Tiger Shark"]
67
- assert_suggest "How Big is a Tigre Shar", "how big is a tiger shark", fields: [{"name^2" => :word_start}]
68
- end
69
-
70
- def test_multiple_models
71
- skip # flaky test
72
- store_names ["Great White Shark", "Hammerhead Shark", "Tiger Shark"]
73
- assert_equal "how big is a tiger shark", Searchkick.search("How Big is a Tigre Shar", suggest: [:name], fields: [:name]).suggestions.first
74
- end
75
-
76
- def test_multiple_models_no_fields
77
- store_names ["Great White Shark", "Hammerhead Shark", "Tiger Shark"]
78
- assert_raises(ArgumentError) { Searchkick.search("How Big is a Tigre Shar", suggest: true) }
79
- end
80
-
81
- def test_star
82
- assert_equal [], Product.search("*", suggest: true).suggestions
83
- end
84
-
85
- protected
86
-
87
- def assert_suggest(term, expected, options = {})
88
- result = Product.search(term, options.merge(suggest: true)).suggestions.first
89
- if expected.nil?
90
- assert_nil result
91
- else
92
- assert_equal expected, result
93
- end
94
- end
95
-
96
- # any order
97
- def assert_suggest_all(term, expected, options = {})
98
- assert_equal expected.sort, Product.search(term, options.merge(suggest: true)).suggestions.sort
99
- end
100
- end
@@ -1,21 +0,0 @@
1
- en:
2
- views:
3
- pagination:
4
- first: "&laquo; First"
5
- last: "Last &raquo;"
6
- previous: "&lsaquo; Prev"
7
- next: "Next &rsaquo;"
8
- truncate: "&hellip;"
9
- helpers:
10
- page_entries_info:
11
- entry:
12
- zero: "entries"
13
- one: "entry"
14
- other: "entries"
15
- one_page:
16
- display_entries:
17
- zero: "No %{entry_name} found"
18
- one: "Displaying <b>1</b> %{entry_name}"
19
- other: "Displaying <b>all %{count}</b> %{entry_name}"
20
- more_pages:
21
- display_entries: "Displaying %{entry_name} <b>%{first}&nbsp;-&nbsp;%{last}</b> of <b>%{total}</b> in total"
@@ -1,69 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class SynonymsTest < Minitest::Test
4
- def test_bleach
5
- store_names ["Clorox Bleach", "Kroger Bleach"]
6
- assert_search "clorox", ["Clorox Bleach", "Kroger Bleach"]
7
- end
8
-
9
- def test_saran_wrap
10
- store_names ["Saran Wrap", "Kroger Plastic Wrap"]
11
- assert_search "saran wrap", ["Saran Wrap", "Kroger Plastic Wrap"]
12
- end
13
-
14
- def test_burger_buns
15
- store_names ["Hamburger Buns"]
16
- assert_search "burger buns", ["Hamburger Buns"]
17
- end
18
-
19
- def test_bandaids
20
- store_names ["Band-Aid", "Kroger 12-Pack Bandages"]
21
- assert_search "bandaids", ["Band-Aid", "Kroger 12-Pack Bandages"]
22
- end
23
-
24
- def test_qtips
25
- store_names ["Q Tips", "Kroger Cotton Swabs"]
26
- assert_search "q tips", ["Q Tips", "Kroger Cotton Swabs"]
27
- end
28
-
29
- def test_reverse
30
- store_names ["Scallions"]
31
- assert_search "green onions", ["Scallions"]
32
- end
33
-
34
- def test_exact
35
- store_names ["Green Onions", "Yellow Onions"]
36
- assert_search "scallion", ["Green Onions"]
37
- end
38
-
39
- def test_stemmed
40
- store_names ["Green Onions", "Yellow Onions"]
41
- assert_search "scallions", ["Green Onions"]
42
- end
43
-
44
- def test_word_start
45
- store_names ["Clorox Bleach", "Kroger Bleach"]
46
- assert_search "clorox", ["Clorox Bleach", "Kroger Bleach"], fields: [{name: :word_start}]
47
- end
48
-
49
- def test_wordnet
50
- # requires WordNet
51
- skip unless ENV["WORDNET"]
52
-
53
- store_names ["Creature", "Beast", "Dragon"], Animal
54
- assert_search "animal", ["Creature", "Beast"], {}, Animal
55
- end
56
-
57
- def test_directional
58
- store_names ["Lightbulb", "Green Onions", "Led"]
59
- assert_search "led", ["Lightbulb", "Led"]
60
- assert_search "Lightbulb", ["Lightbulb"]
61
- assert_search "Halogen Lamp", ["Lightbulb"]
62
- assert_search "onions", ["Green Onions"]
63
- end
64
-
65
- def test_case
66
- store_names ["Uppercase"]
67
- assert_search "lowercase", ["Uppercase"]
68
- end
69
- end