searchkick 0.5.2 → 0.5.3

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: 74cd357aadff8dc7f80b5db94f74dde7940abcd8
4
- data.tar.gz: ae9c5f086a639fbb18e0848a862231f188ee7624
3
+ metadata.gz: 6b20e3f5f346c6ef75c257cf2b2aafa23884ee2b
4
+ data.tar.gz: f8c6e426340f0602037a3204e8d38a40d28cf430
5
5
  SHA512:
6
- metadata.gz: 22c8007b1672a5ca1d6def91d812509f50fc795b0744817f8af52feaa024c569b6f993f41b138f47c2aa5d42a7709faa2e6a51f1ff3a5005ff0c8e084ae1a4e9
7
- data.tar.gz: ce18c6e5766bfc8a203c1a6ebe77f9d717b7a88c6ce361858ad15fa3049a4722cb5dcc23bc41f0e3d3be9e12f34a47d70a6783b458b2fe9701cb5d673376711f
6
+ metadata.gz: 210eecb919e7491f84acdc1f4f69f2c1bf898b808033ed31f8adc63cc4ac636d0e242cd9136cf1467842aafcd0e358b570b02e9eb0f2e1a7d158807c096e6b3d
7
+ data.tar.gz: b4907fb7bde4d2a7c13a68b26b84527f8deb00bd41da7216a0637f15f62923f39d0589151edbcd44b1bc0f1eec61e3ae8e5e0be1cc95e440f09b6a694d10f007
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.5.3
2
+
3
+ - Fixed bug w/ word_* queries
4
+
1
5
  ## 0.5.2
2
6
 
3
7
  - Use after_commit hook for ActiveRecord to prevent data inconsistencies
data/README.md CHANGED
@@ -494,8 +494,9 @@ Dog.reindex # equivalent
494
494
  And to search, use:
495
495
 
496
496
  ```ruby
497
- Animal.search "*" # all animals
498
- Dog.search "*" # just dogs
497
+ Animal.search "*" # all animals
498
+ Dog.search "*" # just dogs
499
+ Animal.search "*", type: [Dog, Cat] # just cats and dogs [master]
499
500
  ```
500
501
 
501
502
  **Note:** The `suggest` option retrieves suggestions from the parent at the moment.
@@ -747,11 +748,14 @@ For convenience, this is set by default in the test environment.
747
748
 
748
749
  Thanks to Karel Minarik for [Tire](https://github.com/karmi/tire), Jaroslav Kalistsuk for [zero downtime reindexing](https://gist.github.com/jarosan/3124884), and Alex Leschenko for [Elasticsearch autocomplete](https://github.com/leschenko/elasticsearch_autocomplete).
749
750
 
750
- ## TODO
751
+ ## Roadmap
751
752
 
752
- - Generate autocomplete predictions from past search queries
753
- - Automatic failover
754
- - Make Searchkick work with any language
753
+ - Search multiple fields for different terms
754
+ - Search across models
755
+ - Search nested objects
756
+ - Add section on testing
757
+ - Much finer customization
758
+ - More transparency into generated queries (for advanced use)
755
759
 
756
760
  ## History
757
761
 
@@ -765,3 +769,11 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
765
769
  - Fix bugs and [submit pull requests](https://github.com/ankane/searchkick/pulls)
766
770
  - Write, clarify, or fix documentation
767
771
  - Suggest or add new features
772
+
773
+ To get started with development and testing:
774
+
775
+ 1. Clone the repo
776
+ 2. Install PostgreSQL and create a database called `searchkick_test` (`psql -d postgres -c "create database searchkick_test"`)
777
+ 3. Install Elasticsearch
778
+ 4. `bundle`
779
+ 5. `rake test`
@@ -51,7 +51,8 @@ module Searchkick
51
51
  end
52
52
 
53
53
  def self.extended(klass)
54
- (@descendents ||= []) << klass
54
+ @descendents ||= []
55
+ @descendents << klass unless @descendents.include?(klass)
55
56
  end
56
57
 
57
58
  private
@@ -124,6 +125,11 @@ module Searchkick
124
125
  tokenizer: "keyword",
125
126
  filter: ["lowercase", "asciifolding"]
126
127
  },
128
+ searchkick_word_search: {
129
+ type: "custom",
130
+ tokenizer: "standard",
131
+ filter: ["lowercase", "asciifolding"]
132
+ },
127
133
  searchkick_suggest_index: {
128
134
  type: "custom",
129
135
  tokenizer: "standard",
@@ -92,11 +92,12 @@ module Searchkick
92
92
  ]
93
93
  end
94
94
  else
95
+ analyzer = field.match(/\.word_(start|middle|end)\z/) ? "searchkick_word_search" : "searchkick_autocomplete_search"
95
96
  queries << {
96
97
  multi_match: {
97
98
  fields: [field],
98
99
  query: term,
99
- analyzer: "searchkick_autocomplete_search"
100
+ analyzer: analyzer
100
101
  }
101
102
  }
102
103
  end
@@ -159,6 +160,15 @@ module Searchkick
159
160
  }
160
161
  end
161
162
 
163
+ if options[:personalize]
164
+ custom_filters << {
165
+ filter: {
166
+ term: options[:personalize]
167
+ },
168
+ boost: 100
169
+ }
170
+ end
171
+
162
172
  if custom_filters.any?
163
173
  payload = {
164
174
  custom_filters_score: {
@@ -215,30 +225,29 @@ module Searchkick
215
225
  end
216
226
 
217
227
  if value.is_a?(Hash)
218
- if value[:near]
219
- filters << {
220
- geo_distance: {
221
- field => value.delete(:near).map(&:to_f).reverse,
222
- distance: value.delete(:within) || "50mi"
228
+ value.each do |op, op_value|
229
+ case op
230
+ when :within, :bottom_right
231
+ # do nothing
232
+ when :near
233
+ filters << {
234
+ geo_distance: {
235
+ field => op_value.map(&:to_f).reverse,
236
+ distance: value[:within] || "50mi"
237
+ }
223
238
  }
224
- }
225
- end
226
-
227
- if value[:top_left]
228
- filters << {
229
- geo_bounding_box: {
230
- field => {
231
- top_left: value.delete(:top_left).map(&:to_f).reverse,
232
- bottom_right: value.delete(:bottom_right).map(&:to_f).reverse
239
+ when :top_left
240
+ filters << {
241
+ geo_bounding_box: {
242
+ field => {
243
+ top_left: op_value.map(&:to_f).reverse,
244
+ bottom_right: value[:bottom_right].map(&:to_f).reverse
245
+ }
233
246
  }
234
247
  }
235
- }
236
- end
237
-
238
- value.each do |op, op_value|
239
- if op == :not # not equal
248
+ when :not # not equal
240
249
  filters << {not: term_filters.call(field, op_value)}
241
- elsif op == :all
250
+ when :all
242
251
  filters << {terms: {field => op_value, execution: "and"}}
243
252
  else
244
253
  range_query =
@@ -254,7 +263,12 @@ module Searchkick
254
263
  else
255
264
  raise "Unknown where operator"
256
265
  end
257
- filters << {range: {field => range_query}}
266
+ # issue 132
267
+ if existing = filters.find{ |f| f[:range] && f[:range][field] }
268
+ existing[:range][field].merge!(range_query)
269
+ else
270
+ filters << {range: {field => range_query}}
271
+ end
258
272
  end
259
273
  end
260
274
  else
@@ -350,7 +364,9 @@ module Searchkick
350
364
  payload[:fields] = [] if load
351
365
 
352
366
  tire_options = {load: load, payload: payload, size: per_page, from: offset}
353
- tire_options[:type] = document_type if self != searchkick_klass
367
+ if options[:type] or self != searchkick_klass
368
+ tire_options[:type] = [options[:type] || self].flatten.map(&:document_type)
369
+ end
354
370
  search = Tire::Search::Search.new(index_name, tire_options)
355
371
  begin
356
372
  response = search.json
@@ -1,3 +1,3 @@
1
1
  module Searchkick
2
- VERSION = "0.5.2"
2
+ VERSION = "0.5.3"
3
3
  end
@@ -18,33 +18,38 @@ class TestAutocomplete < Minitest::Unit::TestCase
18
18
  end
19
19
 
20
20
  def test_text_start
21
- store_names ["Where in the World is Carmen San Diego?"]
22
- assert_search "whe", ["Where in the World is Carmen San Diego?"], fields: [{name: :text_start}]
21
+ store_names ["Where in the World is Carmen San Diego"]
22
+ assert_search "where in the world is", ["Where in the World is Carmen San Diego"], fields: [{name: :text_start}]
23
+ assert_search "in the world", [], fields: [{name: :text_start}]
23
24
  end
24
25
 
25
26
  def test_text_middle
26
- store_names ["Where in the World is Carmen San Diego?"]
27
- assert_search "n the wor", ["Where in the World is Carmen San Diego?"], fields: [{name: :text_middle}]
27
+ store_names ["Where in the World is Carmen San Diego"]
28
+ assert_search "where in the world is", ["Where in the World is Carmen San Diego"], fields: [{name: :text_middle}]
29
+ assert_search "n the wor", ["Where in the World is Carmen San Diego"], fields: [{name: :text_middle}]
30
+ assert_search "men san diego", ["Where in the World is Carmen San Diego"], fields: [{name: :text_middle}]
31
+ assert_search "world carmen", [], fields: [{name: :text_middle}]
28
32
  end
29
33
 
30
34
  def test_text_end
31
- store_names ["Where in the World is Carmen San Diego?"]
32
- assert_search "ego?", ["Where in the World is Carmen San Diego?"], fields: [{name: :text_end}]
35
+ store_names ["Where in the World is Carmen San Diego"]
36
+ assert_search "men san diego", ["Where in the World is Carmen San Diego"], fields: [{name: :text_end}]
37
+ assert_search "carmen san", [], fields: [{name: :text_end}]
33
38
  end
34
39
 
35
40
  def test_word_start
36
- store_names ["Where in the World is Carmen San Diego?"]
37
- assert_search "car", ["Where in the World is Carmen San Diego?"], fields: [{name: :word_start}]
41
+ store_names ["Where in the World is Carmen San Diego"]
42
+ assert_search "car san wor", ["Where in the World is Carmen San Diego"], fields: [{name: :word_start}]
38
43
  end
39
44
 
40
45
  def test_word_middle
41
- store_names ["Where in the World is Carmen San Diego?"]
42
- assert_search "orl", ["Where in the World is Carmen San Diego?"], fields: [{name: :word_middle}]
46
+ store_names ["Where in the World is Carmen San Diego"]
47
+ assert_search "orl", ["Where in the World is Carmen San Diego"], fields: [{name: :word_middle}]
43
48
  end
44
49
 
45
50
  def test_word_end
46
- store_names ["Where in the World is Carmen San Diego?"]
47
- assert_search "men", ["Where in the World is Carmen San Diego?"], fields: [{name: :word_end}]
51
+ store_names ["Where in the World is Carmen San Diego"]
52
+ assert_search "rld men ego", ["Where in the World is Carmen San Diego"], fields: [{name: :word_end}]
48
53
  end
49
54
 
50
55
  end
data/test/boost_test.rb CHANGED
@@ -57,4 +57,14 @@ class TestBoost < Minitest::Unit::TestCase
57
57
  assert_first "tomato", "Tomato B", user_id: 2
58
58
  end
59
59
 
60
+ def test_personalize
61
+ store [
62
+ {name: "Tomato A"},
63
+ {name: "Tomato B", user_ids: [1, 2, 3]},
64
+ {name: "Tomato C"},
65
+ {name: "Tomato D"}
66
+ ]
67
+ assert_first "tomato", "Tomato B", personalize: {user_ids: 2}
68
+ end
69
+
60
70
  end
@@ -25,6 +25,19 @@ class TestInheritance < Minitest::Unit::TestCase
25
25
  assert_equal 2, Animal.search("bear").size
26
26
  end
27
27
 
28
+ def test_force_one_type
29
+ store_names ["Green Bear"], Dog
30
+ store_names ["Blue Bear"], Cat
31
+ assert_equal ["Blue Bear"], Animal.search("bear", type: [Cat]).map(&:name)
32
+ end
33
+
34
+ def test_force_multiple_types
35
+ store_names ["Green Bear"], Dog
36
+ store_names ["Blue Bear"], Cat
37
+ store_names ["Red Bear"], Animal
38
+ assert_equal ["Green Bear", "Blue Bear"], Animal.search("bear", type: [Dog, Cat]).map(&:name)
39
+ end
40
+
28
41
  def test_child_autocomplete
29
42
  store_names ["Max"], Cat
30
43
  store_names ["Mark"], Dog
data/test/sql_test.rb CHANGED
@@ -60,6 +60,7 @@ class TestSql < Minitest::Unit::TestCase
60
60
  assert_search "product", ["Product A", "Product B"], where: {store_id: [1, 2]}
61
61
  assert_search "product", ["Product B", "Product C", "Product D"], where: {store_id: {not: 1}}
62
62
  assert_search "product", ["Product C", "Product D"], where: {store_id: {not: [1, 2]}}
63
+ assert_search "product", ["Product A"], where: {user_ids: {lte: 2, gte: 2}}
63
64
  # or
64
65
  assert_search "product", ["Product A", "Product B", "Product C"], where: {or: [[{in_stock: true}, {store_id: 3}]]}
65
66
  assert_search "product", ["Product A", "Product B", "Product C"], where: {or: [[{orders_count: [2, 4]}, {store_id: [1, 2]}]]}
@@ -105,6 +106,25 @@ class TestSql < Minitest::Unit::TestCase
105
106
  assert_search "product", [], where: {store_id: []}
106
107
  end
107
108
 
109
+ # http://elasticsearch-users.115913.n3.nabble.com/Numeric-range-quey-or-filter-in-an-array-field-possible-or-not-td4042967.html
110
+ # https://gist.github.com/jprante/7099463
111
+ def test_where_range_array
112
+ store [
113
+ {name: "Product A", user_ids: [11, 23, 13, 16, 17, 23.6]},
114
+ {name: "Product B", user_ids: [1, 2, 3, 4, 5, 6, 7, 8, 8.9, 9.1, 9.4]},
115
+ {name: "Product C", user_ids: [101, 230, 150, 200]}
116
+ ]
117
+ assert_search "product", ["Product A"], where: {user_ids: {gt: 10, lt: 23.9}}
118
+ end
119
+
120
+ def test_where_range_array_again
121
+ store [
122
+ {name: "Product A", user_ids: [19, 32, 42]},
123
+ {name: "Product B", user_ids: [13, 40, 52]}
124
+ ]
125
+ assert_search "product", ["Product A"], where: {user_ids: {gt: 26, lt: 36}}
126
+ end
127
+
108
128
  def test_near
109
129
  store [
110
130
  {name: "San Francisco", latitude: 37.7833, longitude: -122.4167},
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.5.2
4
+ version: 0.5.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: 2014-02-13 00:00:00.000000000 Z
11
+ date: 2014-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tire