searchkick 0.4.1 → 0.4.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 84aa6414f91ce1c76d0c247e9a11dfce4417c2ee
4
- data.tar.gz: f072c08de08bac3808112ad165199b98b5b2e507
3
+ metadata.gz: 93348e8748debeefc0be073340665c5024b961af
4
+ data.tar.gz: a4c73f4e8147ba2120d7e3388205fa056128d392
5
5
  SHA512:
6
- metadata.gz: b866b6ba7f26bca01b13043c42ae1e9917b664be9bf77ce0c269dde30298fc8d2a08a54ce247dd465e500ebe8e122e804685ab4855984c1a09088b46422900e7
7
- data.tar.gz: ab9bae0de9a80123cb85e0a34f221b6dce56efc91471c3037fbce10b2c7e284635291704965c1894c419e3b7610da8e1ffa4d83cde4a76039a530ef0b26e7407
6
+ metadata.gz: 1f75f44631fee7348ff9aaf3d24f99b1954d5cef1868cc17f73c44c1dc17918f6eaa158dd35c46a582b31ec7d226384782421cd3c15f33b5a5e1b1f426266d90
7
+ data.tar.gz: 6be3ea5ed0ac0002b4628ad3cc067c0352b4724b9318836e2affe2c05c167132113e00b1ea8515f9e806054a57e3d7cb98a6f3c904f549885960fad72caa4e98
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.4.2
2
+
3
+ - Added `should_index?` method to control which records are indexed
4
+ - Added ability to temporarily disable callbacks
5
+ - Added custom mappings
6
+
1
7
  ## 0.4.1
2
8
 
3
9
  - Fixed issue w/ inheritance mapping
data/README.md CHANGED
@@ -72,6 +72,8 @@ Query like SQL
72
72
  Product.search "2% Milk", where: {in_stock: true}, limit: 10, offset: 50
73
73
  ```
74
74
 
75
+ **Note:** If you prefer the Elasticsearch DSL, see the [Advanced section](#advanced)
76
+
75
77
  Search specific fields
76
78
 
77
79
  ```ruby
@@ -195,6 +197,16 @@ class Product < ActiveRecord::Base
195
197
  end
196
198
  ```
197
199
 
200
+ By default, all records are indexed. To control which records are indexed, use the `should_index?` method.
201
+
202
+ ```ruby
203
+ class Product < ActiveRecord::Base
204
+ def should_index?
205
+ active # only index active records
206
+ end
207
+ end
208
+ ```
209
+
198
210
  ### To Reindex, or Not to Reindex
199
211
 
200
212
  #### Reindex
@@ -494,6 +506,30 @@ Then deploy and reindex:
494
506
  rake searchkick:reindex CLASS=Product
495
507
  ```
496
508
 
509
+ ## Advanced
510
+
511
+ Prefer to use the [Elasticsearch DSL](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-queries.html) but still want awesome features like zero-downtime reindexing?
512
+
513
+ Create a custom mapping:
514
+
515
+ ```ruby
516
+ class Product < ActiveRecord::Base
517
+ searchkick mappings: {
518
+ product: {
519
+ properties: {
520
+ name: {type: "string", analyzer: "keyword"}
521
+ }
522
+ }
523
+ }
524
+ end
525
+ ```
526
+
527
+ And use the `query` option to search:
528
+
529
+ ```ruby
530
+ Product.search query: {match: {name: "milk"}}
531
+ ```
532
+
497
533
  ## Reference
498
534
 
499
535
  Searchkick requires Elasticsearch `0.90.0` or higher.
@@ -527,7 +563,7 @@ class Product < ActiveRecord::Base
527
563
  end
528
564
  ```
529
565
 
530
- Turn off callbacks
566
+ Turn off callbacks permanently
531
567
 
532
568
  ```ruby
533
569
  class Product < ActiveRecord::Base
@@ -535,6 +571,15 @@ class Product < ActiveRecord::Base
535
571
  end
536
572
  ```
537
573
 
574
+ or temporarily
575
+
576
+ ```ruby
577
+ Product.disable_search_callbacks # use Searchkick.disable_callbacks for all models
578
+ ExpensiveProductsTask.execute
579
+ Product.enable_search_callbacks
580
+ Product.reindex
581
+ ```
582
+
538
583
  Eager load associations
539
584
 
540
585
  ```ruby
@@ -8,6 +8,7 @@ module Searchkick
8
8
  class_variable_set :@@searchkick_options, options.dup
9
9
  class_variable_set :@@searchkick_env, ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development"
10
10
  class_variable_set :@@searchkick_klass, self
11
+ class_variable_set :@@searchkick_callbacks, options[:callbacks] != false
11
12
 
12
13
  # set index name
13
14
  # TODO support proc
@@ -18,19 +19,34 @@ module Searchkick
18
19
  extend Searchkick::Reindex
19
20
  include Searchkick::Similar
20
21
 
21
- def reindex
22
- index = self.class.searchkick_index
23
- if destroyed?
24
- index.remove self
25
- else
26
- index.store self
27
- end
22
+ after_save :reindex
23
+ after_destroy :reindex
24
+
25
+ def self.enable_search_callbacks
26
+ class_variable_set :@@searchkick_callbacks, true
27
+ end
28
+
29
+ def self.disable_search_callbacks
30
+ class_variable_set :@@searchkick_callbacks, false
31
+ end
32
+
33
+ def self.search_callbacks?
34
+ class_variable_get(:@@searchkick_callbacks) && Searchkick.callbacks?
35
+ end
36
+
37
+ def should_index?
38
+ true
28
39
  end
29
40
 
30
- unless options[:callbacks] == false
31
- # TODO ability to temporarily disable
32
- after_save :reindex
33
- after_destroy :reindex
41
+ def reindex
42
+ if self.class.search_callbacks?
43
+ index = self.class.searchkick_index
44
+ if destroyed? or !should_index?
45
+ index.remove self
46
+ else
47
+ index.store self
48
+ end
49
+ end
34
50
  end
35
51
 
36
52
  def search_data
@@ -62,14 +62,14 @@ module Searchkick
62
62
  scope = scope.search_import if scope.respond_to?(:search_import)
63
63
  if scope.respond_to?(:find_in_batches)
64
64
  scope.find_in_batches do |batch|
65
- index.import batch
65
+ index.import batch.select{|item| item.should_index? }
66
66
  end
67
67
  else
68
68
  # https://github.com/karmi/tire/blob/master/lib/tire/model/import.rb
69
69
  # use cursor for Mongoid
70
70
  items = []
71
71
  scope.all.each do |item|
72
- items << item
72
+ items << item if item.should_index?
73
73
  if items.length % 1000 == 0
74
74
  index.import items
75
75
  items = []
@@ -82,174 +82,179 @@ module Searchkick
82
82
  def searchkick_index_options
83
83
  options = searchkick_options
84
84
 
85
- settings = {
86
- analysis: {
87
- analyzer: {
88
- searchkick_keyword: {
89
- type: "custom",
90
- tokenizer: "keyword",
91
- filter: ["lowercase", "snowball"]
92
- },
93
- default_index: {
94
- type: "custom",
95
- tokenizer: "standard",
96
- # synonym should come last, after stemming and shingle
97
- # shingle must come before snowball
98
- filter: ["standard", "lowercase", "asciifolding", "stop", "searchkick_index_shingle", "snowball"]
99
- },
100
- searchkick_search: {
101
- type: "custom",
102
- tokenizer: "standard",
103
- filter: ["standard", "lowercase", "asciifolding", "stop", "searchkick_search_shingle", "snowball"]
104
- },
105
- searchkick_search2: {
106
- type: "custom",
107
- tokenizer: "standard",
108
- filter: ["standard", "lowercase", "asciifolding", "stop", "snowball"]
109
- },
110
- # https://github.com/leschenko/elasticsearch_autocomplete/blob/master/lib/elasticsearch_autocomplete/analyzers.rb
111
- searchkick_autocomplete_index: {
112
- type: "custom",
113
- tokenizer: "searchkick_autocomplete_ngram",
114
- filter: ["lowercase", "asciifolding"]
115
- },
116
- searchkick_autocomplete_search: {
117
- type: "custom",
118
- tokenizer: "keyword",
119
- filter: ["lowercase", "asciifolding"]
120
- },
121
- searchkick_suggest_index: {
122
- type: "custom",
123
- tokenizer: "standard",
124
- filter: ["lowercase", "asciifolding", "searchkick_suggest_shingle"]
125
- }
126
- },
127
- filter: {
128
- searchkick_index_shingle: {
129
- type: "shingle",
130
- token_separator: ""
85
+ if options[:mappings]
86
+ settings = options[:settings] || {}
87
+ mappings = options[:mappings]
88
+ else
89
+ settings = {
90
+ analysis: {
91
+ analyzer: {
92
+ searchkick_keyword: {
93
+ type: "custom",
94
+ tokenizer: "keyword",
95
+ filter: ["lowercase", "snowball"]
96
+ },
97
+ default_index: {
98
+ type: "custom",
99
+ tokenizer: "standard",
100
+ # synonym should come last, after stemming and shingle
101
+ # shingle must come before snowball
102
+ filter: ["standard", "lowercase", "asciifolding", "stop", "searchkick_index_shingle", "snowball"]
103
+ },
104
+ searchkick_search: {
105
+ type: "custom",
106
+ tokenizer: "standard",
107
+ filter: ["standard", "lowercase", "asciifolding", "stop", "searchkick_search_shingle", "snowball"]
108
+ },
109
+ searchkick_search2: {
110
+ type: "custom",
111
+ tokenizer: "standard",
112
+ filter: ["standard", "lowercase", "asciifolding", "stop", "snowball"]
113
+ },
114
+ # https://github.com/leschenko/elasticsearch_autocomplete/blob/master/lib/elasticsearch_autocomplete/analyzers.rb
115
+ searchkick_autocomplete_index: {
116
+ type: "custom",
117
+ tokenizer: "searchkick_autocomplete_ngram",
118
+ filter: ["lowercase", "asciifolding"]
119
+ },
120
+ searchkick_autocomplete_search: {
121
+ type: "custom",
122
+ tokenizer: "keyword",
123
+ filter: ["lowercase", "asciifolding"]
124
+ },
125
+ searchkick_suggest_index: {
126
+ type: "custom",
127
+ tokenizer: "standard",
128
+ filter: ["lowercase", "asciifolding", "searchkick_suggest_shingle"]
129
+ }
131
130
  },
132
- # lucky find http://web.archiveorange.com/archive/v/AAfXfQ17f57FcRINsof7
133
- searchkick_search_shingle: {
134
- type: "shingle",
135
- token_separator: "",
136
- output_unigrams: false,
137
- output_unigrams_if_no_shingles: true
131
+ filter: {
132
+ searchkick_index_shingle: {
133
+ type: "shingle",
134
+ token_separator: ""
135
+ },
136
+ # lucky find http://web.archiveorange.com/archive/v/AAfXfQ17f57FcRINsof7
137
+ searchkick_search_shingle: {
138
+ type: "shingle",
139
+ token_separator: "",
140
+ output_unigrams: false,
141
+ output_unigrams_if_no_shingles: true
142
+ },
143
+ searchkick_suggest_shingle: {
144
+ type: "shingle",
145
+ max_shingle_size: 5
146
+ }
138
147
  },
139
- searchkick_suggest_shingle: {
140
- type: "shingle",
141
- max_shingle_size: 5
142
- }
143
- },
144
- tokenizer: {
145
- searchkick_autocomplete_ngram: {
146
- type: "edgeNGram",
147
- min_gram: 1,
148
- max_gram: 50
148
+ tokenizer: {
149
+ searchkick_autocomplete_ngram: {
150
+ type: "edgeNGram",
151
+ min_gram: 1,
152
+ max_gram: 50
153
+ }
149
154
  }
150
155
  }
151
156
  }
152
- }
153
157
 
154
- if searchkick_env == "test"
155
- settings.merge!(number_of_shards: 1, number_of_replicas: 0)
156
- end
158
+ if searchkick_env == "test"
159
+ settings.merge!(number_of_shards: 1, number_of_replicas: 0)
160
+ end
157
161
 
158
- settings.merge!(options[:settings] || {})
162
+ settings.merge!(options[:settings] || {})
159
163
 
160
- # synonyms
161
- synonyms = options[:synonyms] || []
162
- if synonyms.any?
163
- settings[:analysis][:filter][:searchkick_synonym] = {
164
- type: "synonym",
165
- synonyms: synonyms.select{|s| s.size > 1 }.map{|s| s.join(",") }
166
- }
167
- # choosing a place for the synonym filter when stemming is not easy
168
- # https://groups.google.com/forum/#!topic/elasticsearch/p7qcQlgHdB8
169
- # TODO use a snowball stemmer on synonyms when creating the token filter
164
+ # synonyms
165
+ synonyms = options[:synonyms] || []
166
+ if synonyms.any?
167
+ settings[:analysis][:filter][:searchkick_synonym] = {
168
+ type: "synonym",
169
+ synonyms: synonyms.select{|s| s.size > 1 }.map{|s| s.join(",") }
170
+ }
171
+ # choosing a place for the synonym filter when stemming is not easy
172
+ # https://groups.google.com/forum/#!topic/elasticsearch/p7qcQlgHdB8
173
+ # TODO use a snowball stemmer on synonyms when creating the token filter
170
174
 
171
- # http://elasticsearch-users.115913.n3.nabble.com/synonym-multi-words-search-td4030811.html
172
- # I find the following approach effective if you are doing multi-word synonyms (synonym phrases):
173
- # - Only apply the synonym expansion at index time
174
- # - Don't have the synonym filter applied search
175
- # - Use directional synonyms where appropriate. You want to make sure that you're not injecting terms that are too general.
176
- settings[:analysis][:analyzer][:default_index][:filter].insert(4, "searchkick_synonym")
177
- settings[:analysis][:analyzer][:default_index][:filter] << "searchkick_synonym"
178
- end
175
+ # http://elasticsearch-users.115913.n3.nabble.com/synonym-multi-words-search-td4030811.html
176
+ # I find the following approach effective if you are doing multi-word synonyms (synonym phrases):
177
+ # - Only apply the synonym expansion at index time
178
+ # - Don't have the synonym filter applied search
179
+ # - Use directional synonyms where appropriate. You want to make sure that you're not injecting terms that are too general.
180
+ settings[:analysis][:analyzer][:default_index][:filter].insert(4, "searchkick_synonym")
181
+ settings[:analysis][:analyzer][:default_index][:filter] << "searchkick_synonym"
182
+ end
179
183
 
180
- if options[:special_characters] == false
181
- settings[:analysis][:analyzer].each do |analyzer, analyzer_settings|
182
- analyzer_settings[:filter].reject!{|f| f == "asciifolding" }
184
+ if options[:special_characters] == false
185
+ settings[:analysis][:analyzer].each do |analyzer, analyzer_settings|
186
+ analyzer_settings[:filter].reject!{|f| f == "asciifolding" }
187
+ end
183
188
  end
184
- end
185
189
 
186
- mapping = {}
190
+ mapping = {}
187
191
 
188
- # conversions
189
- if options[:conversions]
190
- mapping[:conversions] = {
191
- type: "nested",
192
- properties: {
193
- query: {type: "string", analyzer: "searchkick_keyword"},
194
- count: {type: "integer"}
192
+ # conversions
193
+ if options[:conversions]
194
+ mapping[:conversions] = {
195
+ type: "nested",
196
+ properties: {
197
+ query: {type: "string", analyzer: "searchkick_keyword"},
198
+ count: {type: "integer"}
199
+ }
195
200
  }
196
- }
197
- end
201
+ end
198
202
 
199
- # autocomplete and suggest
200
- autocomplete = (options[:autocomplete] || []).map(&:to_s)
201
- suggest = (options[:suggest] || []).map(&:to_s)
202
- (autocomplete + suggest).uniq.each do |field|
203
- field_mapping = {
204
- type: "multi_field",
205
- fields: {
206
- field => {type: "string", index: "not_analyzed"},
207
- "analyzed" => {type: "string", index: "analyzed"}
208
- # term_vector: "with_positions_offsets" for fast / correct highlighting
209
- # http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-highlighting.html#_fast_vector_highlighter
203
+ # autocomplete and suggest
204
+ autocomplete = (options[:autocomplete] || []).map(&:to_s)
205
+ suggest = (options[:suggest] || []).map(&:to_s)
206
+ (autocomplete + suggest).uniq.each do |field|
207
+ field_mapping = {
208
+ type: "multi_field",
209
+ fields: {
210
+ field => {type: "string", index: "not_analyzed"},
211
+ "analyzed" => {type: "string", index: "analyzed"}
212
+ # term_vector: "with_positions_offsets" for fast / correct highlighting
213
+ # http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-highlighting.html#_fast_vector_highlighter
214
+ }
210
215
  }
211
- }
212
- if autocomplete.include?(field)
213
- field_mapping[:fields]["autocomplete"] = {type: "string", index: "analyzed", analyzer: "searchkick_autocomplete_index"}
214
- end
215
- if suggest.include?(field)
216
- field_mapping[:fields]["suggest"] = {type: "string", index: "analyzed", analyzer: "searchkick_suggest_index"}
216
+ if autocomplete.include?(field)
217
+ field_mapping[:fields]["autocomplete"] = {type: "string", index: "analyzed", analyzer: "searchkick_autocomplete_index"}
218
+ end
219
+ if suggest.include?(field)
220
+ field_mapping[:fields]["suggest"] = {type: "string", index: "analyzed", analyzer: "searchkick_suggest_index"}
221
+ end
222
+ mapping[field] = field_mapping
217
223
  end
218
- mapping[field] = field_mapping
219
- end
220
224
 
221
- (options[:locations] || []).each do |field|
222
- mapping[field] = {
223
- type: "geo_point"
224
- }
225
- end
225
+ (options[:locations] || []).each do |field|
226
+ mapping[field] = {
227
+ type: "geo_point"
228
+ }
229
+ end
226
230
 
227
- mappings = {
228
- _default_: {
229
- properties: mapping,
230
- # https://gist.github.com/kimchy/2898285
231
- dynamic_templates: [
232
- {
233
- string_template: {
234
- match: "*",
235
- match_mapping_type: "string",
236
- mapping: {
237
- # http://www.elasticsearch.org/guide/reference/mapping/multi-field-type/
238
- type: "multi_field",
239
- fields: {
240
- # analyzed field must be the default field for include_in_all
231
+ mappings = {
232
+ _default_: {
233
+ properties: mapping,
234
+ # https://gist.github.com/kimchy/2898285
235
+ dynamic_templates: [
236
+ {
237
+ string_template: {
238
+ match: "*",
239
+ match_mapping_type: "string",
240
+ mapping: {
241
241
  # http://www.elasticsearch.org/guide/reference/mapping/multi-field-type/
242
- # however, we can include the not_analyzed field in _all
243
- # and the _all index analyzer will take care of it
244
- "{name}" => {type: "string", index: "not_analyzed"},
245
- "analyzed" => {type: "string", index: "analyzed"}
242
+ type: "multi_field",
243
+ fields: {
244
+ # analyzed field must be the default field for include_in_all
245
+ # http://www.elasticsearch.org/guide/reference/mapping/multi-field-type/
246
+ # however, we can include the not_analyzed field in _all
247
+ # and the _all index analyzer will take care of it
248
+ "{name}" => {type: "string", index: "not_analyzed"},
249
+ "analyzed" => {type: "string", index: "analyzed"}
250
+ }
246
251
  }
247
252
  }
248
253
  }
249
- }
250
- ]
254
+ ]
255
+ }
251
256
  }
252
- }
257
+ end
253
258
 
254
259
  {
255
260
  settings: settings,
@@ -2,7 +2,13 @@ module Searchkick
2
2
  module Search
3
3
 
4
4
  def search(term, options = {})
5
- term = term.to_s
5
+ if term.is_a?(Hash)
6
+ options = term
7
+ term = nil
8
+ else
9
+ term = term.to_s
10
+ end
11
+
6
12
  fields =
7
13
  if options[:fields]
8
14
  if options[:autocomplete]
@@ -35,7 +41,9 @@ module Searchkick
35
41
 
36
42
  all = term == "*"
37
43
 
38
- if options[:similar]
44
+ if options[:query]
45
+ payload = options[:query]
46
+ elsif options[:similar]
39
47
  payload = {
40
48
  more_like_this: {
41
49
  fields: fields,
@@ -1,3 +1,3 @@
1
1
  module Searchkick
2
- VERSION = "0.4.1"
2
+ VERSION = "0.4.2"
3
3
  end
data/lib/searchkick.rb CHANGED
@@ -8,6 +8,22 @@ require "searchkick/model"
8
8
  require "searchkick/tasks"
9
9
  require "searchkick/logger" if defined?(Rails)
10
10
 
11
+ module Searchkick
12
+ @callbacks = true
13
+
14
+ def self.enable_callbacks
15
+ @callbacks = true
16
+ end
17
+
18
+ def self.disable_callbacks
19
+ @callbacks = false
20
+ end
21
+
22
+ def self.callbacks?
23
+ @callbacks
24
+ end
25
+ end
26
+
11
27
  # TODO find better ActiveModel hook
12
28
  ActiveModel::Callbacks.send(:include, Searchkick::Model)
13
29
  ActiveRecord::Base.send(:extend, Searchkick::Model) if defined?(ActiveRecord)
data/test/index_test.rb CHANGED
@@ -26,4 +26,10 @@ class TestIndex < Minitest::Unit::TestCase
26
26
  assert !old_index.exists?
27
27
  end
28
28
 
29
+ def test_mapping
30
+ store_names ["Dollar Tree"], Store
31
+ assert_equal [], Store.search(query: {match: {name: "dollar"}}).map(&:name)
32
+ assert_equal ["Dollar Tree"], Store.search(query: {match: {name: "Dollar Tree"}}).map(&:name)
33
+ end
34
+
29
35
  end
@@ -2,11 +2,6 @@ require_relative "test_helper"
2
2
 
3
3
  class TestInheritance < Minitest::Unit::TestCase
4
4
 
5
- def setup
6
- super
7
- Animal.destroy_all
8
- end
9
-
10
5
  def test_child_reindex
11
6
  store_names ["Max"], Cat
12
7
  assert Dog.reindex
@@ -0,0 +1,35 @@
1
+ require_relative "test_helper"
2
+
3
+ class TestModel < Minitest::Unit::TestCase
4
+
5
+ def test_disable_callbacks_model
6
+ store_names ["product a"]
7
+
8
+ Product.disable_search_callbacks
9
+ assert !Product.search_callbacks?
10
+
11
+ store_names ["product b"]
12
+ assert_search "product", ["product a"]
13
+
14
+ Product.enable_search_callbacks
15
+ Product.reindex
16
+
17
+ assert_search "product", ["product a", "product b"]
18
+ end
19
+
20
+ def test_disable_callbacks_global
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
+ end
@@ -0,0 +1,34 @@
1
+ require_relative "test_helper"
2
+
3
+ class TestShouldIndex < Minitest::Unit::TestCase
4
+
5
+ def test_basic
6
+ store_names ["INDEX", "DO NOT INDEX"]
7
+ assert_search "index", ["INDEX"]
8
+ end
9
+
10
+ def test_default_true
11
+ assert Animal.new.should_index?
12
+ end
13
+
14
+ def test_change_to_true
15
+ store_names ["DO NOT INDEX"]
16
+ assert_search "index", []
17
+ product = Product.first
18
+ product.name = "INDEX"
19
+ product.save!
20
+ Product.searchkick_index.refresh
21
+ assert_search "index", ["INDEX"]
22
+ end
23
+
24
+ def test_change_to_false
25
+ store_names ["INDEX"]
26
+ assert_search "index", ["INDEX"]
27
+ product = Product.first
28
+ product.name = "DO NOT INDEX"
29
+ product.save!
30
+ Product.searchkick_index.refresh
31
+ assert_search "index", []
32
+ end
33
+
34
+ end
data/test/test_helper.rb CHANGED
@@ -33,6 +33,8 @@ if defined?(Mongoid)
33
33
 
34
34
  class Store
35
35
  include Mongoid::Document
36
+
37
+ field :name
36
38
  end
37
39
 
38
40
  class Animal
@@ -73,6 +75,7 @@ else
73
75
  end
74
76
 
75
77
  ActiveRecord::Migration.create_table :stores, :force => true do |t|
78
+ t.string :name
76
79
  end
77
80
 
78
81
  ActiveRecord::Migration.create_table :animals, :force => true do |t|
@@ -119,6 +122,20 @@ class Product
119
122
  def search_data
120
123
  serializable_hash.merge conversions: conversions, user_ids: user_ids, location: [latitude, longitude], multiple_locations: [[latitude, longitude], [0, 0]]
121
124
  end
125
+
126
+ def should_index?
127
+ name != "DO NOT INDEX"
128
+ end
129
+ end
130
+
131
+ class Store
132
+ searchkick mappings: {
133
+ store: {
134
+ properties: {
135
+ name: {type: "string", analyzer: "keyword"}
136
+ }
137
+ }
138
+ }
122
139
  end
123
140
 
124
141
  class Animal
@@ -129,12 +146,14 @@ Product.searchkick_index.delete if Product.searchkick_index.exists?
129
146
  Product.reindex
130
147
  Product.reindex # run twice for both index paths
131
148
 
149
+ Store.reindex
132
150
  Animal.reindex
133
151
 
134
152
  class Minitest::Unit::TestCase
135
153
 
136
154
  def setup
137
155
  Product.destroy_all
156
+ Animal.destroy_all
138
157
  end
139
158
 
140
159
  protected
@@ -151,16 +170,16 @@ class Minitest::Unit::TestCase
151
170
  end
152
171
 
153
172
  # no order
154
- def assert_search(term, expected, options = {})
155
- assert_equal expected.sort, Product.search(term, options).map(&:name).sort
173
+ def assert_search(term, expected, options = {}, klass = Product)
174
+ assert_equal expected.sort, klass.search(term, options).map(&:name).sort
156
175
  end
157
176
 
158
- def assert_order(term, expected, options = {})
159
- assert_equal expected, Product.search(term, options).map(&:name)
177
+ def assert_order(term, expected, options = {}, klass = Product)
178
+ assert_equal expected, klass.search(term, options).map(&:name)
160
179
  end
161
180
 
162
- def assert_first(term, expected, options = {})
163
- assert_equal expected, Product.search(term, options).map(&:name).first
181
+ def assert_first(term, expected, options = {}, klass = Product)
182
+ assert_equal expected, klass.search(term, options).map(&:name).first
164
183
  end
165
184
 
166
185
  end
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: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-20 00:00:00.000000000 Z
11
+ date: 2013-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tire
@@ -141,6 +141,8 @@ files:
141
141
  - test/index_test.rb
142
142
  - test/inheritance_test.rb
143
143
  - test/match_test.rb
144
+ - test/model_test.rb
145
+ - test/should_index_test.rb
144
146
  - test/similar_test.rb
145
147
  - test/sql_test.rb
146
148
  - test/suggest_test.rb
@@ -178,6 +180,8 @@ test_files:
178
180
  - test/index_test.rb
179
181
  - test/inheritance_test.rb
180
182
  - test/match_test.rb
183
+ - test/model_test.rb
184
+ - test/should_index_test.rb
181
185
  - test/similar_test.rb
182
186
  - test/sql_test.rb
183
187
  - test/suggest_test.rb