chewy 0.8.3 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +43 -11
  3. data/Appraisals +39 -12
  4. data/CHANGELOG.md +42 -0
  5. data/Gemfile +1 -1
  6. data/README.md +60 -7
  7. data/chewy.gemspec +12 -5
  8. data/gemfiles/{rails.4.0.mongoid.gemfile → rails.4.0.mongoid.4.0.0.gemfile} +1 -1
  9. data/gemfiles/{rails.4.0.mongoid.kaminari.gemfile → rails.4.0.mongoid.4.0.0.kaminari.gemfile} +1 -1
  10. data/gemfiles/{rails.4.0.mongoid.will_paginate.gemfile → rails.4.0.mongoid.4.0.0.will_paginate.gemfile} +1 -1
  11. data/gemfiles/rails.4.0.mongoid.5.1.0.gemfile +15 -0
  12. data/gemfiles/rails.4.0.mongoid.5.1.0.kaminari.gemfile +14 -0
  13. data/gemfiles/rails.4.0.mongoid.5.1.0.will_paginate.gemfile +14 -0
  14. data/gemfiles/{rails.4.1.mongoid.gemfile → rails.4.1.mongoid.4.0.0.gemfile} +1 -1
  15. data/gemfiles/{rails.4.1.mongoid.kaminari.gemfile → rails.4.1.mongoid.4.0.0.kaminari.gemfile} +1 -1
  16. data/gemfiles/{rails.4.1.mongoid.will_paginate.gemfile → rails.4.1.mongoid.4.0.0.will_paginate.gemfile} +1 -1
  17. data/gemfiles/rails.4.1.mongoid.5.1.0.gemfile +15 -0
  18. data/gemfiles/rails.4.1.mongoid.5.1.0.kaminari.gemfile +14 -0
  19. data/gemfiles/rails.4.1.mongoid.5.1.0.will_paginate.gemfile +14 -0
  20. data/gemfiles/{rails.4.2.mongoid.gemfile → rails.4.2.mongoid.4.0.0.gemfile} +1 -1
  21. data/gemfiles/{rails.4.2.mongoid.kaminari.gemfile → rails.4.2.mongoid.4.0.0.kaminari.gemfile} +1 -1
  22. data/gemfiles/{rails.4.2.mongoid.will_paginate.gemfile → rails.4.2.mongoid.4.0.0.will_paginate.gemfile} +1 -1
  23. data/gemfiles/rails.4.2.mongoid.5.1.0.gemfile +15 -0
  24. data/gemfiles/rails.4.2.mongoid.5.1.0.kaminari.gemfile +14 -0
  25. data/gemfiles/rails.4.2.mongoid.5.1.0.will_paginate.gemfile +14 -0
  26. data/gemfiles/rails.5.0.0.beta3.activerecord.gemfile +16 -0
  27. data/gemfiles/rails.5.0.0.beta3.activerecord.kaminari.gemfile +16 -0
  28. data/gemfiles/rails.5.0.0.beta3.activerecord.will_paginate.gemfile +15 -0
  29. data/gemfiles/{sequel.4.28.gemfile → sequel.4.31.gemfile} +1 -1
  30. data/lib/chewy.rb +7 -1
  31. data/lib/chewy/errors.rb +6 -0
  32. data/lib/chewy/fields/base.rb +12 -8
  33. data/lib/chewy/fields/root.rb +1 -1
  34. data/lib/chewy/index.rb +17 -8
  35. data/lib/chewy/index/actions.rb +4 -4
  36. data/lib/chewy/query.rb +8 -13
  37. data/lib/chewy/query/compose.rb +2 -2
  38. data/lib/chewy/query/criteria.rb +2 -2
  39. data/lib/chewy/query/loading.rb +1 -1
  40. data/lib/chewy/query/nodes/bool.rb +1 -1
  41. data/lib/chewy/query/nodes/regexp.rb +2 -2
  42. data/lib/chewy/railtie.rb +15 -3
  43. data/lib/chewy/rake_helper.rb +5 -2
  44. data/lib/chewy/rspec/update_index.rb +17 -6
  45. data/lib/chewy/strategy.rb +7 -3
  46. data/lib/chewy/strategy/active_job.rb +2 -2
  47. data/lib/chewy/strategy/resque.rb +2 -2
  48. data/lib/chewy/strategy/sidekiq.rb +2 -2
  49. data/lib/chewy/type.rb +14 -0
  50. data/lib/chewy/type/adapter/active_record.rb +11 -1
  51. data/lib/chewy/type/adapter/orm.rb +13 -11
  52. data/lib/chewy/type/adapter/sequel.rb +10 -12
  53. data/lib/chewy/type/import.rb +53 -22
  54. data/lib/chewy/type/witchcraft.rb +208 -0
  55. data/lib/chewy/type/wrapper.rb +25 -7
  56. data/lib/chewy/version.rb +1 -1
  57. data/lib/tasks/chewy.rake +22 -14
  58. data/spec/chewy/fields/base_spec.rb +6 -2
  59. data/spec/chewy/fields/time_fields_spec.rb +4 -4
  60. data/spec/chewy/index/actions_spec.rb +32 -18
  61. data/spec/chewy/index_spec.rb +19 -0
  62. data/spec/chewy/query/pagination_spec.rb +1 -1
  63. data/spec/chewy/query_spec.rb +77 -21
  64. data/spec/chewy/rspec/update_index_spec.rb +75 -62
  65. data/spec/chewy/runtime_spec.rb +1 -1
  66. data/spec/chewy/strategy/active_job_spec.rb +6 -1
  67. data/spec/chewy/strategy/atomic_spec.rb +5 -5
  68. data/spec/chewy/strategy/resque_spec.rb +7 -2
  69. data/spec/chewy/strategy/sidekiq_spec.rb +6 -1
  70. data/spec/chewy/strategy_spec.rb +13 -1
  71. data/spec/chewy/type/actions_spec.rb +4 -1
  72. data/spec/chewy/type/import_spec.rb +71 -2
  73. data/spec/chewy/type/observe_spec.rb +9 -9
  74. data/spec/chewy/type/witchcraft_spec.rb +154 -0
  75. data/spec/chewy/type/wrapper_spec.rb +30 -5
  76. data/spec/chewy/type_spec.rb +10 -0
  77. data/spec/chewy_spec.rb +29 -5
  78. data/spec/spec_helper.rb +2 -0
  79. data/spec/support/class_helpers.rb +15 -0
  80. data/spec/support/mongoid.rb +5 -0
  81. metadata +64 -21
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "mongoid", "~> 4.0.0"
5
+ gem "mongoid", "> 4.0.0"
6
6
  gem "activesupport", "~> 4.1.0"
7
7
  gem "resque", :require => false
8
8
  gem "sidekiq", :require => false
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "mongoid", "~> 4.0.0"
5
+ gem "mongoid", "> 4.0.0"
6
6
  gem "activesupport", "~> 4.1.0"
7
7
  gem "kaminari", "0.16.3", :require => false
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "mongoid", "~> 4.0.0"
5
+ gem "mongoid", "> 4.0.0"
6
6
  gem "activesupport", "~> 4.1.0"
7
7
  gem "will_paginate", :require => false
8
8
 
@@ -0,0 +1,15 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "mongoid", "> 5.1.0"
6
+ gem "activesupport", "~> 4.1.0"
7
+ gem "resque", :require => false
8
+ gem "sidekiq", :require => false
9
+
10
+ group :test do
11
+ gem "guard"
12
+ gem "guard-rspec"
13
+ end
14
+
15
+ gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "mongoid", "> 5.1.0"
6
+ gem "activesupport", "~> 4.1.0"
7
+ gem "kaminari", "0.16.3", :require => false
8
+
9
+ group :test do
10
+ gem "guard"
11
+ gem "guard-rspec"
12
+ end
13
+
14
+ gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "mongoid", "> 5.1.0"
6
+ gem "activesupport", "~> 4.1.0"
7
+ gem "will_paginate", :require => false
8
+
9
+ group :test do
10
+ gem "guard"
11
+ gem "guard-rspec"
12
+ end
13
+
14
+ gemspec :path => "../"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "mongoid", "~> 4.0.0"
5
+ gem "mongoid", "> 4.0.0"
6
6
  gem "activesupport", "~> 4.2.0"
7
7
  gem "resque", :require => false
8
8
  gem "sidekiq", :require => false
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "mongoid", "~> 4.0.0"
5
+ gem "mongoid", "> 4.0.0"
6
6
  gem "activesupport", "~> 4.2.0"
7
7
  gem "kaminari", "0.16.3", :require => false
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "mongoid", "~> 4.0.0"
5
+ gem "mongoid", "> 4.0.0"
6
6
  gem "activesupport", "~> 4.2.0"
7
7
  gem "will_paginate", :require => false
8
8
 
@@ -0,0 +1,15 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "mongoid", "> 5.1.0"
6
+ gem "activesupport", "~> 4.2.0"
7
+ gem "resque", :require => false
8
+ gem "sidekiq", :require => false
9
+
10
+ group :test do
11
+ gem "guard"
12
+ gem "guard-rspec"
13
+ end
14
+
15
+ gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "mongoid", "> 5.1.0"
6
+ gem "activesupport", "~> 4.2.0"
7
+ gem "kaminari", "0.16.3", :require => false
8
+
9
+ group :test do
10
+ gem "guard"
11
+ gem "guard-rspec"
12
+ end
13
+
14
+ gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "mongoid", "> 5.1.0"
6
+ gem "activesupport", "~> 4.2.0"
7
+ gem "will_paginate", :require => false
8
+
9
+ group :test do
10
+ gem "guard"
11
+ gem "guard-rspec"
12
+ end
13
+
14
+ gemspec :path => "../"
@@ -0,0 +1,16 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 5.0.0.beta3"
6
+ gem "activesupport", "~> 5.0.0.beta3"
7
+ gem "activejob", "~> 5.0.0.beta3"
8
+ gem "resque", :require => false
9
+ gem "sidekiq", :require => false
10
+
11
+ group :test do
12
+ gem "guard"
13
+ gem "guard-rspec"
14
+ end
15
+
16
+ gemspec :path => "../"
@@ -0,0 +1,16 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 5.0.0.beta3"
6
+ gem "activesupport", "~> 5.0.0.beta3"
7
+ gem "activejob", "~> 5.0.0.beta3"
8
+ gem "actionpack", "~> 5.0.0.beta3"
9
+ gem "kaminari", "0.16.3", :require => false
10
+
11
+ group :test do
12
+ gem "guard"
13
+ gem "guard-rspec"
14
+ end
15
+
16
+ gemspec :path => "../"
@@ -0,0 +1,15 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 5.0.0.beta3"
6
+ gem "activesupport", "~> 5.0.0.beta3"
7
+ gem "activejob", "~> 5.0.0.beta3"
8
+ gem "will_paginate", :require => false
9
+
10
+ group :test do
11
+ gem "guard"
12
+ gem "guard-rspec"
13
+ end
14
+
15
+ gemspec :path => "../"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "sequel", "~> 4.28.0"
5
+ gem "sequel", "~> 4.31.0"
6
6
  gem "activesupport", "~> 4.2.0"
7
7
 
8
8
  group :test do
@@ -8,6 +8,7 @@ require 'active_support/core_ext/array/wrap'
8
8
  require 'active_support/core_ext/enumerable'
9
9
  require 'active_support/core_ext/hash/reverse_merge'
10
10
  require 'active_support/core_ext/numeric/time'
11
+ require 'active_support/core_ext/numeric/bytes'
11
12
  require 'active_support/core_ext/object/blank'
12
13
  require 'active_support/core_ext/object/inclusion'
13
14
  require 'active_support/core_ext/string/inflections'
@@ -122,7 +123,12 @@ module Chewy
122
123
  # Main elasticsearch-ruby client instance
123
124
  #
124
125
  def client
125
- Thread.current[:chewy_client] ||= ::Elasticsearch::Client.new configuration
126
+ Thread.current[:chewy_client] ||= begin
127
+ client_configuration = configuration.deep_dup
128
+ client_configuration.delete(:prefix) # used by Chewy, not relevant to Elasticsearch::Client
129
+ block = client_configuration[:transport_options].try(:delete, :proc)
130
+ ::Elasticsearch::Client.new(client_configuration, &block)
131
+ end
126
132
  end
127
133
 
128
134
  # Sends wait_for_status request to ElasticSearch with status
@@ -36,4 +36,10 @@ Please wrap your code with `Chewy.strategy(:strategy_name) block.`
36
36
  super message
37
37
  end
38
38
  end
39
+
40
+ class RemovedFeature < Error
41
+ end
42
+
43
+ class PluginMissing < Error
44
+ end
39
45
  end
@@ -11,19 +11,19 @@ module Chewy
11
11
  end
12
12
 
13
13
  def multi_field?
14
- children.any? && !object_field?
14
+ children.present? && !object_field?
15
15
  end
16
16
 
17
17
  def object_field?
18
- (children.any? && options[:type].blank?) || ['object', 'nested'].include?(options[:type].to_s)
18
+ (children.present? && options[:type].blank?) || ['object', 'nested'].include?(options[:type].to_s)
19
19
  end
20
20
 
21
21
  def mappings_hash
22
- mapping = children.any? ? {
22
+ mapping = children.present? ? {
23
23
  (multi_field? ? :fields : :properties) => children.map(&:mappings_hash).inject(:merge)
24
24
  } : {}
25
25
  mapping.reverse_merge!(options)
26
- mapping.reverse_merge!(type: (children.any? ? 'object' : 'string'))
26
+ mapping.reverse_merge!(type: (children.present? ? 'object' : 'string'))
27
27
  {name => mapping}
28
28
  end
29
29
 
@@ -39,16 +39,20 @@ module Chewy
39
39
  value.call(*objects.first(value.arity))
40
40
  end
41
41
  elsif object.is_a?(Hash)
42
- object[name] || object[name.to_s]
42
+ if object.has_key?(name)
43
+ object[name]
44
+ else
45
+ object[name.to_s]
46
+ end
43
47
  else
44
48
  object.send(name)
45
49
  end
46
50
 
47
51
  result = if result.respond_to?(:to_ary)
48
- result.to_ary.map { |result| compose_children(result, *objects) }
52
+ result.to_ary.map { |item| compose_children(item, *objects) }
49
53
  else
50
54
  compose_children(result, *objects)
51
- end if children.any? && !multi_field?
55
+ end if children.present? && !multi_field?
52
56
 
53
57
  {name => result.as_json(root: false)}
54
58
  end
@@ -56,7 +60,7 @@ module Chewy
56
60
  private
57
61
 
58
62
  def compose_children(value, *parent_objects)
59
- children.map { |field| field.compose(value, *parent_objects) if value }.compact.inject(:merge)
63
+ children.map { |field| field.compose(value, *parent_objects) }.compact.inject(:merge) if value
60
64
  end
61
65
  end
62
66
  end
@@ -21,7 +21,7 @@ module Chewy
21
21
  mappings = super
22
22
  mappings[name].delete(:type)
23
23
 
24
- if dynamic_templates.any?
24
+ if dynamic_templates.present?
25
25
  mappings[name][:dynamic_templates] ||= []
26
26
  mappings[name][:dynamic_templates].concat dynamic_templates
27
27
  end
@@ -30,18 +30,24 @@ module Chewy
30
30
  #
31
31
  def self.index_name(suggest = nil)
32
32
  if suggest
33
- @index_name = build_index_name(suggest, prefix: Chewy.configuration[:prefix])
33
+ @index_name = build_index_name(suggest, prefix: default_prefix)
34
34
  else
35
35
  @index_name ||= begin
36
36
  build_index_name(
37
37
  name.sub(/Index\Z/, '').demodulize.underscore,
38
- prefix: Chewy.configuration[:prefix]
38
+ prefix: default_prefix
39
39
  ) if name
40
40
  end
41
41
  end
42
42
  @index_name or raise UndefinedIndex
43
43
  end
44
44
 
45
+ # Prefix to use
46
+ #
47
+ def self.default_prefix
48
+ Chewy.configuration[:prefix]
49
+ end
50
+
45
51
  # Defines type for the index. Arguments depends on adapter used. For
46
52
  # ActiveRecord you can pass model or scope and options
47
53
  #
@@ -80,11 +86,14 @@ module Chewy
80
86
  type_class = Chewy.create_type(self, target, options, &block)
81
87
  self.type_hash = type_hash.merge(type_class.type_name => type_class)
82
88
 
83
- class_eval <<-METHOD, __FILE__, __LINE__ + 1
84
- def self.#{type_class.type_name}
85
- type_hash['#{type_class.type_name}']
86
- end
87
- METHOD
89
+ unless respond_to?(type_class.type_name)
90
+ class_eval <<-METHOD, __FILE__, __LINE__ + 1
91
+ def self.#{type_class.type_name}
92
+ ActiveSupport::Deprecation.warn("`#{self}.#{type_class.type_name}` accessor is deprecated and will be removed soon. Use `#{type_class}` directly instead.")
93
+ type_hash['#{type_class.type_name}']
94
+ end
95
+ METHOD
96
+ end
88
97
  end
89
98
 
90
99
  # Types method has double usage.
@@ -99,7 +108,7 @@ module Chewy
99
108
  # UsersIndex.types(:admin, :manager).filters { name =~ 'ro' } # the same as the first example
100
109
  #
101
110
  def self.types *args
102
- if args.any?
111
+ if args.present?
103
112
  all.types *args
104
113
  else
105
114
  type_hash.values
@@ -24,8 +24,8 @@ module Chewy
24
24
  # method creates index with suffix and makes unsuffixed alias
25
25
  # for it.
26
26
  #
27
- # UsersIndex.create '01-2013' # creates index `uses_01-2013` and alias `users` for it
28
- # UsersIndex.create '01-2013', alias: false # creates index `uses_01-2013` only and no alias
27
+ # UsersIndex.create '01-2013' # creates index `users_01-2013` and alias `users` for it
28
+ # UsersIndex.create '01-2013', alias: false # creates index `users_01-2013` only and no alias
29
29
  #
30
30
  # Suffixed index names might be used for zero-downtime mapping change, for example.
31
31
  # Description: (http://www.elasticsearch.org/blog/changing-mapping-with-zero-downtime/).
@@ -161,7 +161,7 @@ module Chewy
161
161
  # UsersIndex.reset! Time.now.to_i
162
162
  #
163
163
  def reset! suffix = nil
164
- if suffix.present? && (indexes = self.indexes).any?
164
+ if suffix.present? && (indexes = self.indexes).present?
165
165
  create! suffix, alias: false
166
166
  result = import suffix: suffix
167
167
  client.indices.update_aliases body: {actions: [
@@ -170,7 +170,7 @@ module Chewy
170
170
  end,
171
171
  {add: {index: build_index_name(suffix: suffix), alias: index_name}}
172
172
  ]}
173
- client.indices.delete index: indexes if indexes.any?
173
+ client.indices.delete index: indexes if indexes.present?
174
174
  result
175
175
  else
176
176
  purge! suffix
@@ -18,16 +18,6 @@ module Chewy
18
18
  include Loading
19
19
  include Pagination
20
20
 
21
- RESULT_MERGER = lambda do |key, old_value, new_value|
22
- if old_value.is_a?(Hash) && new_value.is_a?(Hash)
23
- old_value.merge(new_value, &RESULT_MERGER)
24
- elsif new_value.is_a?(Array) && new_value.count > 1
25
- new_value
26
- else
27
- old_value.is_a?(Array) ? new_value : new_value.first
28
- end
29
- end
30
-
31
21
  delegate :each, :count, :size, to: :_collection
32
22
  alias_method :to_ary, :to_a
33
23
 
@@ -353,6 +343,7 @@ module Chewy
353
343
  # Returns empty hash if no facets was requested or resulted.
354
344
  #
355
345
  def facets params = nil
346
+ raise RemovedFeature, 'removed in elasticsearch 2.0' if Runtime.version >= '2.0'
356
347
  if params
357
348
  chain { criteria.update_facets params }
358
349
  else
@@ -906,6 +897,10 @@ module Chewy
906
897
  # UsersIndex::User.filter{ age <= 42 }.delete_all
907
898
  #
908
899
  def delete_all
900
+ if Runtime.version > '2.0'
901
+ plugins = Chewy.client.nodes.info(plugins: true)["nodes"].values.map { |item| item["plugins"] }.flatten
902
+ raise PluginMissing, "install delete-by-query plugin" unless plugins.find { |item| item["name"] == 'delete-by-query' }
903
+ end
909
904
  request = chain { criteria.update_options simple: true }.send(:_request)
910
905
  ActiveSupport::Notifications.instrument 'delete_query.chewy',
911
906
  request: request, indexes: _indexes, types: _types,
@@ -992,7 +987,7 @@ module Chewy
992
987
  begin
993
988
  Chewy.client.search(_request)
994
989
  rescue Elasticsearch::Transport::Transport::Errors::NotFound => e
995
- raise e if e.message !~ /IndexMissingException/
990
+ raise e if e.message !~ /IndexMissingException/ && e.message !~ /index_not_found_exception/
996
991
  {}
997
992
  end
998
993
  end
@@ -1000,8 +995,8 @@ module Chewy
1000
995
 
1001
996
  def _results
1002
997
  @_results ||= (criteria.none? || _response == {} ? [] : _response['hits']['hits']).map do |hit|
1003
- attributes = (hit['_source'] || {}).merge(hit['highlight'] || {}, &RESULT_MERGER)
1004
- attributes.reverse_merge!(id: hit['_id'])
998
+ attributes = (hit['_source'] || {})
999
+ .reverse_merge(id: hit['_id'])
1005
1000
  .merge!(_score: hit['_score'])
1006
1001
  .merge!(_explanation: hit['_explanation'])
1007
1002