searchkick 2.2.0 → 2.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 85108ff6dc90bd7075f66c5627fc06eba581657f
4
- data.tar.gz: 062420bd6cd4c9601026425d40923cc82e649364
3
+ metadata.gz: e592f63efa26867238f106cdede925736897c39e
4
+ data.tar.gz: b873c66a18f69cffcd9227fe92a1cf314e602090
5
5
  SHA512:
6
- metadata.gz: 680ef536ba5e15456b0df70412eec5e47d13f43424c02e7d039921abf3c83b06fbaefa95d824fa2ae0efeecde8c6488ad56b4aabed442eb6c191a309f2204c6c
7
- data.tar.gz: d118d331ffd37c1fbec228bba2cc043f03730510a0ca45d7bd9afe9c04aa31a8ebeeaba82b57113c070fd7af3b1c8c347f0b22bd8cff43565f9246ed408a0c77
6
+ metadata.gz: 74566048b5471575f1c7f2e269a6fa23fa62dbbd717696a077a26875f43883be128cbbb731578634ec948c51a5e9d336ed3595ea631717ac3056f784c813f19c
7
+ data.tar.gz: 5c1a40b9633f70201a13e003a1852d5a3cfcf0d16d23024cea19ddce523b2f32e5675119e5899b1b4c3e7f057466cd09a80a788a655933923a78172b5b95ebb0
data/.travis.yml CHANGED
@@ -19,7 +19,7 @@ gemfile:
19
19
  - test/gemfiles/mongoid5.gemfile
20
20
  - test/gemfiles/mongoid6.gemfile
21
21
  env:
22
- - ELASTICSEARCH_VERSION=5.2.0
22
+ - ELASTICSEARCH_VERSION=5.3.0
23
23
  jdk: oraclejdk8
24
24
  matrix:
25
25
  include:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 2.2.1
2
+
3
+ - Added `avg`, `cardinality`, `max`, `min`, and `sum` aggregations
4
+ - Added `load: {dumpable: true}` option
5
+ - Added `index_suffix` option
6
+ - Accept string for `exclude` option
7
+
1
8
  ## 2.2.0
2
9
 
3
10
  - Fixed bug with text values longer than 256 characters and `_all` field - see [#850](https://github.com/ankane/searchkick/issues/850)
data/README.md CHANGED
@@ -294,13 +294,17 @@ end
294
294
  ```ruby
295
295
  class Product < ActiveRecord::Base
296
296
  searchkick synonyms: [["scallion", "green onion"], ["qtip", "cotton swab"]]
297
- # or
298
- # searchkick synonyms: -> { CSV.read("/some/path/synonyms.csv") }
299
297
  end
300
298
  ```
301
299
 
302
300
  Call `Product.reindex` after changing synonyms.
303
301
 
302
+ To read synonyms from a file, use:
303
+
304
+ ```ruby
305
+ synonyms: -> { CSV.read("/some/path/synonyms.csv") }
306
+ ```
307
+
304
308
  For directional synonyms, use:
305
309
 
306
310
  ```ruby
@@ -388,7 +392,7 @@ You can map queries and terms to exclude with:
388
392
  ```ruby
389
393
  exclude_queries = {
390
394
  "butter" => ["peanut butter"],
391
- "cream" => ["ice cream"]
395
+ "cream" => ["ice cream", "whipped cream"]
392
396
  }
393
397
 
394
398
  Product.search query, exclude: exclude_queries[query]
@@ -1766,6 +1770,14 @@ product = FactoryGirl.create(:product)
1766
1770
  product.reindex(refresh: true)
1767
1771
  ```
1768
1772
 
1773
+ ### Parallel Tests
1774
+
1775
+ Set:
1776
+
1777
+ ```ruby
1778
+ Searchkick.index_suffix = ENV["TEST_ENV_NUMBER"]
1779
+ ```
1780
+
1769
1781
  ## Multi-Tenancy
1770
1782
 
1771
1783
  Check out [this great post](https://www.tiagoamaro.com.br/2014/12/11/multi-tenancy-with-searchkick/) on the [Apartment](https://github.com/influitive/apartment) gem. Follow a similar pattern if you use another gem.
data/Rakefile CHANGED
@@ -1,6 +1,13 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
3
 
4
+ begin
5
+ require "parallel_tests/tasks"
6
+ require "shellwords"
7
+ rescue LoadError
8
+ # do nothing
9
+ end
10
+
4
11
  task default: :test
5
12
  Rake::TestTask.new do |t|
6
13
  t.libs << "test"
data/lib/searchkick.rb CHANGED
@@ -36,7 +36,7 @@ module Searchkick
36
36
  class ImportError < Error; end
37
37
 
38
38
  class << self
39
- attr_accessor :search_method_name, :wordnet_path, :timeout, :models, :client_options, :redis
39
+ attr_accessor :search_method_name, :wordnet_path, :timeout, :models, :client_options, :redis, :index_suffix
40
40
  attr_writer :client, :env, :search_timeout
41
41
  attr_reader :aws_credentials
42
42
  end
@@ -21,8 +21,8 @@ module Searchkick
21
21
  class_variable_set :@@searchkick_klass, self
22
22
  class_variable_set :@@searchkick_callbacks, callbacks
23
23
  class_variable_set :@@searchkick_index, options[:index_name] ||
24
- (options[:index_prefix].respond_to?(:call) && proc { [options[:index_prefix].call, model_name.plural, Searchkick.env].compact.join("_") }) ||
25
- [options[:index_prefix], model_name.plural, Searchkick.env].compact.join("_")
24
+ (options[:index_prefix].respond_to?(:call) && proc { [options[:index_prefix].call, model_name.plural, Searchkick.env, Searchkick.index_suffix].compact.join("_") }) ||
25
+ [options[:index_prefix], model_name.plural, Searchkick.env, Searchkick.index_suffix].compact.join("_")
26
26
 
27
27
  class << self
28
28
  def searchkick_search(term = "*", **options, &block)
@@ -2,6 +2,8 @@ module Searchkick
2
2
  class Query
3
3
  extend Forwardable
4
4
 
5
+ @@metric_aggs = [:avg, :cardinality, :max, :min, :sum]
6
+
5
7
  attr_reader :klass, :term, :options
6
8
  attr_accessor :body
7
9
 
@@ -328,7 +330,7 @@ module Searchkick
328
330
 
329
331
  if options[:exclude]
330
332
  must_not =
331
- options[:exclude].map do |phrase|
333
+ Array(options[:exclude]).map do |phrase|
332
334
  {
333
335
  match_phrase: {
334
336
  exclude_field => {
@@ -643,6 +645,12 @@ module Searchkick
643
645
  interval: interval
644
646
  }
645
647
  }
648
+ elsif metric = @@metric_aggs.find { |k| agg_options.has_key?(k) }
649
+ payload[:aggs][field] = {
650
+ metric => {
651
+ field: agg_options[metric][:field] || field
652
+ }
653
+ }
646
654
  else
647
655
  payload[:aggs][field] = {
648
656
  terms: {
@@ -33,7 +33,7 @@ module Searchkick
33
33
  # sort
34
34
  hits.map do |hit|
35
35
  result = results[hit["_type"]][hit["_id"].to_s]
36
- if result
36
+ if result && !(options[:load].is_a?(Hash) && options[:load][:dumpable])
37
37
  unless result.respond_to?(:search_hit)
38
38
  result.define_singleton_method(:search_hit) do
39
39
  hit
@@ -1,3 +1,3 @@
1
1
  module Searchkick
2
- VERSION = "2.2.0"
2
+ VERSION = "2.2.1"
3
3
  end
data/test/aggs_test.rb CHANGED
@@ -116,6 +116,68 @@ class AggsTest < Minitest::Test
116
116
  assert_equal 4, products.aggs["products_per_year"]["buckets"].size
117
117
  end
118
118
 
119
+ def test_aggs_avg
120
+ products =
121
+ Product.search("*", {
122
+ aggs: {
123
+ avg_price: {
124
+ avg: {
125
+ field: :price
126
+ }
127
+ }
128
+ }
129
+ })
130
+ assert_equal 16.5, products.aggs["avg_price"]["value"]
131
+ end
132
+
133
+ def test_aggs_cardinality
134
+ products =
135
+ Product.search("*", {
136
+ aggs: {
137
+ total_stores: {
138
+ cardinality: {
139
+ field: :store_id
140
+ }
141
+ }
142
+ }
143
+ })
144
+ assert_equal 3, products.aggs["total_stores"]["value"]
145
+ end
146
+
147
+ def test_aggs_min_max
148
+ products =
149
+ Product.search("*", {
150
+ aggs: {
151
+ min_price: {
152
+ min: {
153
+ field: :price
154
+ }
155
+ },
156
+ max_price: {
157
+ max: {
158
+ field: :price
159
+ }
160
+ }
161
+ }
162
+ })
163
+ assert_equal 5, products.aggs["min_price"]["value"]
164
+ assert_equal 25, products.aggs["max_price"]["value"]
165
+ end
166
+
167
+ def test_aggs_sum
168
+ products =
169
+ Product.search("*", {
170
+ aggs: {
171
+ sum_price: {
172
+ sum: {
173
+ field: :price
174
+ }
175
+ }
176
+ }
177
+ })
178
+ assert_equal 66, products.aggs["sum_price"]["value"]
179
+ end
180
+
119
181
  protected
120
182
 
121
183
  def buckets_as_hash(agg)
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in searchkick.gemspec
4
+ gemspec path: "../../"
5
+
6
+ gem "sqlite3"
7
+ gem "activerecord", "~> 5.0.0"
8
+ gem "parallel_tests"
data/test/index_test.rb CHANGED
@@ -7,8 +7,9 @@ class IndexTest < Minitest::Test
7
7
  end
8
8
 
9
9
  def test_clean_indices
10
- old_index = Searchkick::Index.new("products_test_20130801000000000")
11
- different_index = Searchkick::Index.new("items_test_20130801000000000")
10
+ suffix = Searchkick.index_suffix ? "_#{Searchkick.index_suffix}" : ""
11
+ old_index = Searchkick::Index.new("products_test#{suffix}_20130801000000000")
12
+ different_index = Searchkick::Index.new("items_test#{suffix}_20130801000000000")
12
13
 
13
14
  old_index.delete if old_index.exists?
14
15
  different_index.delete if different_index.exists?
@@ -25,7 +26,8 @@ class IndexTest < Minitest::Test
25
26
  end
26
27
 
27
28
  def test_clean_indices_old_format
28
- old_index = Searchkick::Index.new("products_test_20130801000000")
29
+ suffix = Searchkick.index_suffix ? "_#{Searchkick.index_suffix}" : ""
30
+ old_index = Searchkick::Index.new("products_test#{suffix}_20130801000000")
29
31
  old_index.create
30
32
 
31
33
  Product.searchkick_index.clean_indices
@@ -0,0 +1,8 @@
1
+ require_relative "test_helper"
2
+
3
+ class MarshalTest < Minitest::Test
4
+ def test_marshal
5
+ store_names ["Product A"]
6
+ assert Marshal.dump(Product.search("*", load: {dumpable: true}).results)
7
+ end
8
+ end
data/test/match_test.rb CHANGED
@@ -186,6 +186,11 @@ class MatchTest < Minitest::Test
186
186
  assert_search "egg", ["eggs"], exclude: ["eggplant"], match: :word_start
187
187
  end
188
188
 
189
+ def test_exclude_string
190
+ store_names ["Butter Tub", "Peanut Butter Tub"]
191
+ assert_search "butter", ["Butter Tub"], exclude: "peanut butter"
192
+ end
193
+
189
194
  # other
190
195
 
191
196
  def test_all
data/test/sql_test.rb CHANGED
@@ -7,6 +7,11 @@ class SqlTest < Minitest::Test
7
7
  assert_search "fresh honey", ["Honey"], operator: "or"
8
8
  end
9
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
+
10
15
  def test_fields_operator
11
16
  store [
12
17
  {name: "red", color: "red"},
data/test/test_helper.rb CHANGED
@@ -6,11 +6,16 @@ require "logger"
6
6
  require "active_support/core_ext" if defined?(NoBrainer)
7
7
  require "active_support/notifications"
8
8
 
9
+ Searchkick.index_suffix = ENV["TEST_ENV_NUMBER"]
10
+
9
11
  ENV["RACK_ENV"] = "test"
10
12
 
11
13
  Minitest::Test = Minitest::Unit::TestCase unless defined?(Minitest::Test)
12
14
 
13
- File.delete("elasticsearch.log") if File.exist?("elasticsearch.log")
15
+ if !defined?(ParallelTests) || ParallelTests.first_process?
16
+ File.delete("elasticsearch.log") if File.exist?("elasticsearch.log")
17
+ end
18
+
14
19
  Searchkick.client.transport.logger = Logger.new("elasticsearch.log")
15
20
  Searchkick.search_timeout = 5
16
21
 
@@ -466,7 +471,7 @@ class Animal
466
471
  searchkick \
467
472
  text_start: [:name],
468
473
  suggest: [:name],
469
- index_name: -> { "#{name.tableize}-#{Date.today.year}" },
474
+ index_name: -> { "#{name.tableize}-#{Date.today.year}#{Searchkick.index_suffix}" },
470
475
  callbacks: defined?(ActiveJob) ? :async : true
471
476
  # wordnet: true
472
477
  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: 2.2.0
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-19 00:00:00.000000000 Z
11
+ date: 2017-04-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -147,10 +147,12 @@ files:
147
147
  - test/gemfiles/mongoid5.gemfile
148
148
  - test/gemfiles/mongoid6.gemfile
149
149
  - test/gemfiles/nobrainer.gemfile
150
+ - test/gemfiles/parallel_tests.gemfile
150
151
  - test/geo_shape_test.rb
151
152
  - test/highlight_test.rb
152
153
  - test/index_test.rb
153
154
  - test/inheritance_test.rb
155
+ - test/marshal_test.rb
154
156
  - test/match_test.rb
155
157
  - test/misspellings_test.rb
156
158
  - test/model_test.rb
@@ -220,10 +222,12 @@ test_files:
220
222
  - test/gemfiles/mongoid5.gemfile
221
223
  - test/gemfiles/mongoid6.gemfile
222
224
  - test/gemfiles/nobrainer.gemfile
225
+ - test/gemfiles/parallel_tests.gemfile
223
226
  - test/geo_shape_test.rb
224
227
  - test/highlight_test.rb
225
228
  - test/index_test.rb
226
229
  - test/inheritance_test.rb
230
+ - test/marshal_test.rb
227
231
  - test/match_test.rb
228
232
  - test/misspellings_test.rb
229
233
  - test/model_test.rb