searchkick 2.3.2 → 5.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +377 -84
  3. data/LICENSE.txt +1 -1
  4. data/README.md +859 -602
  5. data/lib/searchkick/bulk_reindex_job.rb +13 -9
  6. data/lib/searchkick/controller_runtime.rb +40 -0
  7. data/lib/searchkick/hash_wrapper.rb +12 -0
  8. data/lib/searchkick/index.rb +281 -356
  9. data/lib/searchkick/index_cache.rb +30 -0
  10. data/lib/searchkick/index_options.rb +487 -281
  11. data/lib/searchkick/indexer.rb +15 -8
  12. data/lib/searchkick/log_subscriber.rb +57 -0
  13. data/lib/searchkick/middleware.rb +9 -2
  14. data/lib/searchkick/model.rb +72 -118
  15. data/lib/searchkick/multi_search.rb +9 -10
  16. data/lib/searchkick/process_batch_job.rb +12 -15
  17. data/lib/searchkick/process_queue_job.rb +22 -13
  18. data/lib/searchkick/query.rb +458 -217
  19. data/lib/searchkick/railtie.rb +7 -0
  20. data/lib/searchkick/record_data.rb +128 -0
  21. data/lib/searchkick/record_indexer.rb +164 -0
  22. data/lib/searchkick/reindex_queue.rb +51 -9
  23. data/lib/searchkick/reindex_v2_job.rb +10 -32
  24. data/lib/searchkick/relation.rb +247 -0
  25. data/lib/searchkick/relation_indexer.rb +155 -0
  26. data/lib/searchkick/results.rb +201 -82
  27. data/lib/searchkick/version.rb +1 -1
  28. data/lib/searchkick/where.rb +11 -0
  29. data/lib/searchkick.rb +269 -97
  30. data/lib/tasks/searchkick.rake +37 -0
  31. metadata +24 -178
  32. data/.gitignore +0 -22
  33. data/.travis.yml +0 -39
  34. data/Gemfile +0 -16
  35. data/Rakefile +0 -20
  36. data/benchmark/Gemfile +0 -23
  37. data/benchmark/benchmark.rb +0 -97
  38. data/lib/searchkick/logging.rb +0 -242
  39. data/lib/searchkick/tasks.rb +0 -33
  40. data/searchkick.gemspec +0 -28
  41. data/test/aggs_test.rb +0 -197
  42. data/test/autocomplete_test.rb +0 -75
  43. data/test/boost_test.rb +0 -202
  44. data/test/callbacks_test.rb +0 -59
  45. data/test/ci/before_install.sh +0 -17
  46. data/test/errors_test.rb +0 -19
  47. data/test/gemfiles/activerecord31.gemfile +0 -7
  48. data/test/gemfiles/activerecord32.gemfile +0 -7
  49. data/test/gemfiles/activerecord40.gemfile +0 -8
  50. data/test/gemfiles/activerecord41.gemfile +0 -8
  51. data/test/gemfiles/activerecord42.gemfile +0 -7
  52. data/test/gemfiles/activerecord50.gemfile +0 -7
  53. data/test/gemfiles/apartment.gemfile +0 -8
  54. data/test/gemfiles/cequel.gemfile +0 -8
  55. data/test/gemfiles/mongoid2.gemfile +0 -7
  56. data/test/gemfiles/mongoid3.gemfile +0 -6
  57. data/test/gemfiles/mongoid4.gemfile +0 -7
  58. data/test/gemfiles/mongoid5.gemfile +0 -7
  59. data/test/gemfiles/mongoid6.gemfile +0 -12
  60. data/test/gemfiles/nobrainer.gemfile +0 -8
  61. data/test/gemfiles/parallel_tests.gemfile +0 -8
  62. data/test/geo_shape_test.rb +0 -175
  63. data/test/highlight_test.rb +0 -78
  64. data/test/index_test.rb +0 -166
  65. data/test/inheritance_test.rb +0 -83
  66. data/test/marshal_test.rb +0 -8
  67. data/test/match_test.rb +0 -276
  68. data/test/misspellings_test.rb +0 -56
  69. data/test/model_test.rb +0 -42
  70. data/test/multi_search_test.rb +0 -36
  71. data/test/multi_tenancy_test.rb +0 -22
  72. data/test/order_test.rb +0 -46
  73. data/test/pagination_test.rb +0 -70
  74. data/test/partial_reindex_test.rb +0 -58
  75. data/test/query_test.rb +0 -35
  76. data/test/records_test.rb +0 -10
  77. data/test/reindex_test.rb +0 -64
  78. data/test/reindex_v2_job_test.rb +0 -32
  79. data/test/routing_test.rb +0 -23
  80. data/test/should_index_test.rb +0 -32
  81. data/test/similar_test.rb +0 -28
  82. data/test/sql_test.rb +0 -214
  83. data/test/suggest_test.rb +0 -95
  84. data/test/support/kaminari.yml +0 -21
  85. data/test/synonyms_test.rb +0 -67
  86. data/test/test_helper.rb +0 -567
  87. data/test/where_test.rb +0 -223
data/test/sql_test.rb DELETED
@@ -1,214 +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_include
129
- skip unless elasticsearch_below50?
130
- store [{name: "Product A", user_ids: [1, 2]}]
131
- result = Product.search("product", load: false, select: {include: [:name]}).first
132
- assert_equal %w(id name), result.keys.reject { |k| k.start_with?("_") }.sort
133
- assert_equal "Product A", result.name
134
- assert_nil result.store_id
135
- end
136
-
137
- def test_select_exclude
138
- skip unless elasticsearch_below50?
139
- store [{name: "Product A", user_ids: [1, 2], store_id: 1}]
140
- result = Product.search("product", load: false, select: {exclude: [:name]}).first
141
- assert_nil result.name
142
- assert_equal [1, 2], result.user_ids
143
- assert_equal 1, result.store_id
144
- end
145
-
146
- def test_select_include_and_exclude
147
- skip unless elasticsearch_below50?
148
- # let's take this to the next level
149
- store [{name: "Product A", user_ids: [1, 2], store_id: 1}]
150
- result = Product.search("product", load: false, select: {include: [:store_id], exclude: [:name]}).first
151
- assert_equal 1, result.store_id
152
- assert_nil result.name
153
- assert_nil result.user_ids
154
- end
155
-
156
- def test_select_includes
157
- skip if elasticsearch_below50?
158
- store [{name: "Product A", user_ids: [1, 2]}]
159
- result = Product.search("product", load: false, select: {includes: [:name]}).first
160
- assert_equal %w(id name), result.keys.reject { |k| k.start_with?("_") }.sort
161
- assert_equal "Product A", result.name
162
- assert_nil result.store_id
163
- end
164
-
165
- def test_select_excludes
166
- skip if elasticsearch_below50?
167
- store [{name: "Product A", user_ids: [1, 2], store_id: 1}]
168
- result = Product.search("product", load: false, select: {excludes: [:name]}).first
169
- assert_nil result.name
170
- assert_equal [1, 2], result.user_ids
171
- assert_equal 1, result.store_id
172
- end
173
-
174
- def test_select_include_and_excludes
175
- skip if elasticsearch_below50?
176
- # let's take this to the next level
177
- store [{name: "Product A", user_ids: [1, 2], store_id: 1}]
178
- result = Product.search("product", load: false, select: {includes: [:store_id], excludes: [:name]}).first
179
- assert_equal 1, result.store_id
180
- assert_nil result.name
181
- assert_nil result.user_ids
182
- end
183
-
184
- # nested
185
-
186
- def test_nested_search
187
- store [{name: "Product A", aisle: {"id" => 1, "name" => "Frozen"}}], Speaker
188
- assert_search "frozen", ["Product A"], {fields: ["aisle.name"]}, Speaker
189
- end
190
-
191
- # other tests
192
-
193
- def test_includes
194
- skip unless defined?(ActiveRecord)
195
- store_names ["Product A"]
196
- assert Product.search("product", includes: [:store]).first.association(:store).loaded?
197
- end
198
-
199
- def test_model_includes
200
- skip unless defined?(ActiveRecord)
201
-
202
- store_names ["Product A"]
203
- store_names ["Store A"], Store
204
-
205
- associations = {Product => [:store], Store => [:products]}
206
- result = Searchkick.search("*", index_name: [Product, Store], model_includes: associations)
207
-
208
- assert_equal 2, result.length
209
-
210
- result.group_by(&:class).each_pair do |klass, records|
211
- assert records.first.association(associations[klass].first).loaded?
212
- end
213
- end
214
- end
data/test/suggest_test.rb DELETED
@@ -1,95 +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
- store_names ["Great White Shark", "Hammerhead Shark", "Tiger Shark"]
72
- assert_equal "how big is a tiger shark", Searchkick.search("How Big is a Tigre Shar", suggest: [:name], fields: [:name]).suggestions.first
73
- end
74
-
75
- def test_multiple_models_no_fields
76
- store_names ["Great White Shark", "Hammerhead Shark", "Tiger Shark"]
77
- assert_raises(ArgumentError) { Searchkick.search("How Big is a Tigre Shar", suggest: true) }
78
- end
79
-
80
- protected
81
-
82
- def assert_suggest(term, expected, options = {})
83
- result = Product.search(term, options.merge(suggest: true)).suggestions.first
84
- if expected.nil?
85
- assert_nil result
86
- else
87
- assert_equal expected, result
88
- end
89
- end
90
-
91
- # any order
92
- def assert_suggest_all(term, expected, options = {})
93
- assert_equal expected.sort, Product.search(term, options.merge(suggest: true)).suggestions.sort
94
- end
95
- 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,67 +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
- skip unless ENV["TEST_WORDNET"]
51
- store_names ["Creature", "Beast", "Dragon"], Animal
52
- assert_search "animal", ["Creature", "Beast"], {}, Animal
53
- end
54
-
55
- def test_directional
56
- store_names ["Lightbulb", "Green Onions", "Led"]
57
- assert_search "led", ["Lightbulb", "Led"]
58
- assert_search "Lightbulb", ["Lightbulb"]
59
- assert_search "Halogen Lamp", ["Lightbulb"]
60
- assert_search "onions", ["Green Onions"]
61
- end
62
-
63
- def test_case
64
- store_names ["Uppercase"]
65
- assert_search "lowercase", ["Uppercase"]
66
- end
67
- end