chewy 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (265) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +24 -2
  4. data/.rubocop_todo.yml +2 -2
  5. data/.travis.yml +38 -21
  6. data/.yardopts +5 -0
  7. data/Appraisals +55 -27
  8. data/CHANGELOG.md +57 -12
  9. data/Gemfile +14 -10
  10. data/LEGACY_DSL.md +497 -0
  11. data/README.md +249 -515
  12. data/chewy.gemspec +5 -4
  13. data/gemfiles/rails.4.0.activerecord.gemfile +14 -0
  14. data/gemfiles/rails.4.1.activerecord.gemfile +14 -0
  15. data/gemfiles/rails.4.2.activerecord.gemfile +8 -10
  16. data/gemfiles/rails.4.2.mongoid.5.1.gemfile +9 -10
  17. data/gemfiles/rails.5.0.activerecord.gemfile +8 -10
  18. data/gemfiles/rails.5.0.mongoid.6.0.gemfile +15 -0
  19. data/gemfiles/rails.5.1.activerecord.gemfile +15 -0
  20. data/gemfiles/rails.5.1.mongoid.6.1.gemfile +15 -0
  21. data/gemfiles/sequel.4.45.gemfile +11 -0
  22. data/lib/chewy.rb +77 -43
  23. data/lib/chewy/config.rb +44 -7
  24. data/lib/chewy/errors.rb +2 -2
  25. data/lib/chewy/fields/base.rb +39 -32
  26. data/lib/chewy/fields/root.rb +33 -7
  27. data/lib/chewy/index.rb +237 -149
  28. data/lib/chewy/index/actions.rb +85 -28
  29. data/lib/chewy/index/aliases.rb +2 -1
  30. data/lib/chewy/index/settings.rb +9 -5
  31. data/lib/chewy/index/specification.rb +58 -0
  32. data/lib/chewy/journal.rb +40 -92
  33. data/lib/chewy/query.rb +43 -27
  34. data/lib/chewy/query/compose.rb +13 -13
  35. data/lib/chewy/query/criteria.rb +13 -13
  36. data/lib/chewy/query/filters.rb +1 -1
  37. data/lib/chewy/query/loading.rb +1 -1
  38. data/lib/chewy/query/nodes/and.rb +2 -2
  39. data/lib/chewy/query/nodes/bool.rb +1 -1
  40. data/lib/chewy/query/nodes/equal.rb +2 -2
  41. data/lib/chewy/query/nodes/exists.rb +1 -1
  42. data/lib/chewy/query/nodes/has_relation.rb +2 -2
  43. data/lib/chewy/query/nodes/match_all.rb +1 -1
  44. data/lib/chewy/query/nodes/missing.rb +1 -1
  45. data/lib/chewy/query/nodes/not.rb +2 -2
  46. data/lib/chewy/query/nodes/or.rb +2 -2
  47. data/lib/chewy/query/nodes/prefix.rb +1 -1
  48. data/lib/chewy/query/nodes/query.rb +2 -2
  49. data/lib/chewy/query/nodes/range.rb +4 -4
  50. data/lib/chewy/query/nodes/regexp.rb +4 -4
  51. data/lib/chewy/query/nodes/script.rb +3 -3
  52. data/lib/chewy/query/pagination.rb +10 -1
  53. data/lib/chewy/railtie.rb +1 -0
  54. data/lib/chewy/rake_helper.rb +265 -48
  55. data/lib/chewy/rspec/update_index.rb +30 -22
  56. data/lib/chewy/search.rb +78 -21
  57. data/lib/chewy/search/loader.rb +83 -0
  58. data/lib/chewy/{query → search}/pagination/kaminari.rb +13 -5
  59. data/lib/chewy/search/pagination/will_paginate.rb +41 -0
  60. data/lib/chewy/search/parameters.rb +150 -0
  61. data/lib/chewy/search/parameters/aggs.rb +16 -0
  62. data/lib/chewy/search/parameters/concerns/bool_storage.rb +24 -0
  63. data/lib/chewy/search/parameters/concerns/hash_storage.rb +23 -0
  64. data/lib/chewy/search/parameters/concerns/integer_storage.rb +14 -0
  65. data/lib/chewy/search/parameters/concerns/query_storage.rb +237 -0
  66. data/lib/chewy/search/parameters/concerns/string_array_storage.rb +23 -0
  67. data/lib/chewy/search/parameters/concerns/string_storage.rb +14 -0
  68. data/lib/chewy/search/parameters/docvalue_fields.rb +12 -0
  69. data/lib/chewy/search/parameters/explain.rb +16 -0
  70. data/lib/chewy/search/parameters/filter.rb +47 -0
  71. data/lib/chewy/search/parameters/highlight.rb +16 -0
  72. data/lib/chewy/search/parameters/indices_boost.rb +52 -0
  73. data/lib/chewy/search/parameters/limit.rb +17 -0
  74. data/lib/chewy/search/parameters/load.rb +32 -0
  75. data/lib/chewy/search/parameters/min_score.rb +16 -0
  76. data/lib/chewy/search/parameters/none.rb +27 -0
  77. data/lib/chewy/search/parameters/offset.rb +17 -0
  78. data/lib/chewy/search/parameters/order.rb +64 -0
  79. data/lib/chewy/search/parameters/post_filter.rb +19 -0
  80. data/lib/chewy/search/parameters/preference.rb +16 -0
  81. data/lib/chewy/search/parameters/profile.rb +16 -0
  82. data/lib/chewy/search/parameters/query.rb +19 -0
  83. data/lib/chewy/search/parameters/request_cache.rb +27 -0
  84. data/lib/chewy/search/parameters/rescore.rb +29 -0
  85. data/lib/chewy/search/parameters/script_fields.rb +16 -0
  86. data/lib/chewy/search/parameters/search_after.rb +20 -0
  87. data/lib/chewy/search/parameters/search_type.rb +16 -0
  88. data/lib/chewy/search/parameters/source.rb +73 -0
  89. data/lib/chewy/search/parameters/storage.rb +95 -0
  90. data/lib/chewy/search/parameters/stored_fields.rb +63 -0
  91. data/lib/chewy/search/parameters/suggest.rb +16 -0
  92. data/lib/chewy/search/parameters/terminate_after.rb +16 -0
  93. data/lib/chewy/search/parameters/timeout.rb +16 -0
  94. data/lib/chewy/search/parameters/track_scores.rb +16 -0
  95. data/lib/chewy/search/parameters/types.rb +20 -0
  96. data/lib/chewy/search/parameters/version.rb +16 -0
  97. data/lib/chewy/search/query_proxy.rb +257 -0
  98. data/lib/chewy/search/request.rb +1021 -0
  99. data/lib/chewy/search/response.rb +119 -0
  100. data/lib/chewy/search/scoping.rb +50 -0
  101. data/lib/chewy/search/scrolling.rb +136 -0
  102. data/lib/chewy/stash.rb +70 -0
  103. data/lib/chewy/strategy.rb +10 -3
  104. data/lib/chewy/strategy/active_job.rb +1 -0
  105. data/lib/chewy/strategy/atomic.rb +1 -3
  106. data/lib/chewy/strategy/bypass.rb +1 -1
  107. data/lib/chewy/strategy/resque.rb +1 -0
  108. data/lib/chewy/strategy/shoryuken.rb +40 -0
  109. data/lib/chewy/strategy/sidekiq.rb +13 -3
  110. data/lib/chewy/type.rb +29 -7
  111. data/lib/chewy/type/actions.rb +26 -2
  112. data/lib/chewy/type/adapter/active_record.rb +44 -29
  113. data/lib/chewy/type/adapter/base.rb +27 -7
  114. data/lib/chewy/type/adapter/mongoid.rb +18 -7
  115. data/lib/chewy/type/adapter/object.rb +187 -26
  116. data/lib/chewy/type/adapter/orm.rb +59 -32
  117. data/lib/chewy/type/adapter/sequel.rb +32 -16
  118. data/lib/chewy/type/import.rb +145 -191
  119. data/lib/chewy/type/import/bulk_builder.rb +122 -0
  120. data/lib/chewy/type/import/bulk_request.rb +76 -0
  121. data/lib/chewy/type/import/journal_builder.rb +45 -0
  122. data/lib/chewy/type/import/routine.rb +138 -0
  123. data/lib/chewy/type/mapping.rb +11 -1
  124. data/lib/chewy/type/observe.rb +1 -1
  125. data/lib/chewy/type/syncer.rb +220 -0
  126. data/lib/chewy/type/witchcraft.rb +27 -13
  127. data/lib/chewy/type/wrapper.rb +28 -2
  128. data/lib/chewy/version.rb +1 -1
  129. data/lib/tasks/chewy.rake +84 -26
  130. data/spec/chewy/config_spec.rb +82 -1
  131. data/spec/chewy/fields/base_spec.rb +147 -112
  132. data/spec/chewy/fields/root_spec.rb +75 -18
  133. data/spec/chewy/fields/time_fields_spec.rb +2 -3
  134. data/spec/chewy/index/actions_spec.rb +180 -50
  135. data/spec/chewy/index/aliases_spec.rb +2 -2
  136. data/spec/chewy/index/settings_spec.rb +67 -38
  137. data/spec/chewy/index/specification_spec.rb +160 -0
  138. data/spec/chewy/index_spec.rb +57 -66
  139. data/spec/chewy/journal_spec.rb +149 -54
  140. data/spec/chewy/minitest/helpers_spec.rb +4 -4
  141. data/spec/chewy/minitest/search_index_receiver_spec.rb +1 -1
  142. data/spec/chewy/query/criteria_spec.rb +179 -179
  143. data/spec/chewy/query/filters_spec.rb +15 -15
  144. data/spec/chewy/query/loading_spec.rb +22 -20
  145. data/spec/chewy/query/nodes/and_spec.rb +2 -2
  146. data/spec/chewy/query/nodes/bool_spec.rb +4 -4
  147. data/spec/chewy/query/nodes/equal_spec.rb +19 -19
  148. data/spec/chewy/query/nodes/exists_spec.rb +6 -6
  149. data/spec/chewy/query/nodes/has_child_spec.rb +19 -19
  150. data/spec/chewy/query/nodes/has_parent_spec.rb +19 -19
  151. data/spec/chewy/query/nodes/missing_spec.rb +5 -5
  152. data/spec/chewy/query/nodes/not_spec.rb +3 -2
  153. data/spec/chewy/query/nodes/or_spec.rb +2 -2
  154. data/spec/chewy/query/nodes/prefix_spec.rb +5 -5
  155. data/spec/chewy/query/nodes/query_spec.rb +2 -2
  156. data/spec/chewy/query/nodes/range_spec.rb +18 -18
  157. data/spec/chewy/query/nodes/raw_spec.rb +1 -1
  158. data/spec/chewy/query/nodes/regexp_spec.rb +14 -14
  159. data/spec/chewy/query/nodes/script_spec.rb +4 -4
  160. data/spec/chewy/query/pagination/kaminari_spec.rb +3 -55
  161. data/spec/chewy/query/pagination/will_paginate_spec.rb +5 -0
  162. data/spec/chewy/query/pagination_spec.rb +25 -21
  163. data/spec/chewy/query_spec.rb +501 -560
  164. data/spec/chewy/rake_helper_spec.rb +368 -0
  165. data/spec/chewy/repository_spec.rb +4 -4
  166. data/spec/chewy/rspec/update_index_spec.rb +89 -56
  167. data/spec/chewy/runtime_spec.rb +2 -2
  168. data/spec/chewy/search/loader_spec.rb +117 -0
  169. data/spec/chewy/search/pagination/kaminari_examples.rb +71 -0
  170. data/spec/chewy/search/pagination/kaminari_spec.rb +17 -0
  171. data/spec/chewy/search/pagination/will_paginate_examples.rb +63 -0
  172. data/spec/chewy/search/pagination/will_paginate_spec.rb +17 -0
  173. data/spec/chewy/search/parameters/aggs_spec.rb +5 -0
  174. data/spec/chewy/search/parameters/bool_storage_examples.rb +53 -0
  175. data/spec/chewy/search/parameters/docvalue_fields_spec.rb +5 -0
  176. data/spec/chewy/search/parameters/explain_spec.rb +5 -0
  177. data/spec/chewy/search/parameters/filter_spec.rb +5 -0
  178. data/spec/chewy/search/parameters/hash_storage_examples.rb +59 -0
  179. data/spec/chewy/search/parameters/highlight_spec.rb +5 -0
  180. data/spec/chewy/search/parameters/indices_boost_spec.rb +83 -0
  181. data/spec/chewy/search/parameters/integer_storage_examples.rb +32 -0
  182. data/spec/chewy/search/parameters/limit_spec.rb +5 -0
  183. data/spec/chewy/search/parameters/load_spec.rb +60 -0
  184. data/spec/chewy/search/parameters/min_score_spec.rb +32 -0
  185. data/spec/chewy/search/parameters/none_spec.rb +5 -0
  186. data/spec/chewy/search/parameters/offset_spec.rb +5 -0
  187. data/spec/chewy/search/parameters/order_spec.rb +65 -0
  188. data/spec/chewy/search/parameters/post_filter_spec.rb +5 -0
  189. data/spec/chewy/search/parameters/preference_spec.rb +5 -0
  190. data/spec/chewy/search/parameters/profile_spec.rb +5 -0
  191. data/spec/chewy/search/parameters/query_spec.rb +5 -0
  192. data/spec/chewy/search/parameters/query_storage_examples.rb +388 -0
  193. data/spec/chewy/search/parameters/request_cache_spec.rb +67 -0
  194. data/spec/chewy/search/parameters/rescore_spec.rb +62 -0
  195. data/spec/chewy/search/parameters/script_fields_spec.rb +5 -0
  196. data/spec/chewy/search/parameters/search_after_spec.rb +32 -0
  197. data/spec/chewy/search/parameters/search_type_spec.rb +5 -0
  198. data/spec/chewy/search/parameters/source_spec.rb +156 -0
  199. data/spec/chewy/search/parameters/storage_spec.rb +60 -0
  200. data/spec/chewy/search/parameters/stored_fields_spec.rb +126 -0
  201. data/spec/chewy/search/parameters/string_array_storage_examples.rb +63 -0
  202. data/spec/chewy/search/parameters/string_storage_examples.rb +32 -0
  203. data/spec/chewy/search/parameters/suggest_spec.rb +5 -0
  204. data/spec/chewy/search/parameters/terminate_after_spec.rb +5 -0
  205. data/spec/chewy/search/parameters/timeout_spec.rb +5 -0
  206. data/spec/chewy/search/parameters/track_scores_spec.rb +5 -0
  207. data/spec/chewy/search/parameters/types_spec.rb +5 -0
  208. data/spec/chewy/search/parameters/version_spec.rb +5 -0
  209. data/spec/chewy/search/parameters_spec.rb +130 -0
  210. data/spec/chewy/search/query_proxy_spec.rb +68 -0
  211. data/spec/chewy/search/request_spec.rb +669 -0
  212. data/spec/chewy/search/response_spec.rb +192 -0
  213. data/spec/chewy/search/scrolling_spec.rb +169 -0
  214. data/spec/chewy/search_spec.rb +13 -6
  215. data/spec/chewy/stash_spec.rb +95 -0
  216. data/spec/chewy/strategy/active_job_spec.rb +6 -0
  217. data/spec/chewy/strategy/resque_spec.rb +6 -0
  218. data/spec/chewy/strategy/shoryuken_spec.rb +64 -0
  219. data/spec/chewy/strategy/sidekiq_spec.rb +8 -0
  220. data/spec/chewy/strategy_spec.rb +6 -6
  221. data/spec/chewy/type/actions_spec.rb +29 -10
  222. data/spec/chewy/type/adapter/active_record_spec.rb +203 -91
  223. data/spec/chewy/type/adapter/mongoid_spec.rb +112 -54
  224. data/spec/chewy/type/adapter/object_spec.rb +101 -28
  225. data/spec/chewy/type/adapter/sequel_spec.rb +149 -82
  226. data/spec/chewy/type/import/bulk_builder_spec.rb +279 -0
  227. data/spec/chewy/type/import/bulk_request_spec.rb +102 -0
  228. data/spec/chewy/type/import/journal_builder_spec.rb +95 -0
  229. data/spec/chewy/type/import/routine_spec.rb +110 -0
  230. data/spec/chewy/type/import_spec.rb +350 -271
  231. data/spec/chewy/type/mapping_spec.rb +54 -18
  232. data/spec/chewy/type/observe_spec.rb +5 -1
  233. data/spec/chewy/type/syncer_spec.rb +123 -0
  234. data/spec/chewy/type/witchcraft_spec.rb +45 -29
  235. data/spec/chewy/type/wrapper_spec.rb +63 -23
  236. data/spec/chewy/type_spec.rb +28 -7
  237. data/spec/chewy_spec.rb +75 -7
  238. data/spec/spec_helper.rb +5 -2
  239. data/spec/support/active_record.rb +5 -1
  240. data/spec/support/class_helpers.rb +0 -14
  241. data/spec/support/mongoid.rb +15 -3
  242. data/spec/support/sequel.rb +6 -1
  243. metadata +198 -37
  244. data/gemfiles/rails.3.2.activerecord.gemfile +0 -16
  245. data/gemfiles/rails.3.2.activerecord.kaminari.gemfile +0 -15
  246. data/gemfiles/rails.3.2.activerecord.will_paginate.gemfile +0 -15
  247. data/gemfiles/rails.4.2.activerecord.kaminari.gemfile +0 -16
  248. data/gemfiles/rails.4.2.activerecord.will_paginate.gemfile +0 -16
  249. data/gemfiles/rails.4.2.mongoid.4.0.gemfile +0 -16
  250. data/gemfiles/rails.4.2.mongoid.4.0.kaminari.gemfile +0 -15
  251. data/gemfiles/rails.4.2.mongoid.4.0.will_paginate.gemfile +0 -15
  252. data/gemfiles/rails.4.2.mongoid.5.1.kaminari.gemfile +0 -15
  253. data/gemfiles/rails.4.2.mongoid.5.1.will_paginate.gemfile +0 -15
  254. data/gemfiles/rails.5.0.activerecord.kaminari.gemfile +0 -16
  255. data/gemfiles/rails.5.0.activerecord.will_paginate.gemfile +0 -16
  256. data/gemfiles/sequel.4.38.gemfile +0 -14
  257. data/lib/chewy/journal/apply.rb +0 -31
  258. data/lib/chewy/journal/clean.rb +0 -24
  259. data/lib/chewy/journal/entry.rb +0 -83
  260. data/lib/chewy/journal/query.rb +0 -87
  261. data/lib/chewy/query/pagination/will_paginate.rb +0 -27
  262. data/lib/chewy/query/scoping.rb +0 -20
  263. data/spec/chewy/journal/apply_spec.rb +0 -120
  264. data/spec/chewy/journal/entry_spec.rb +0 -237
  265. data/spec/chewy/query/pagination/will_paginage_spec.rb +0 -59
@@ -35,17 +35,20 @@ module Chewy
35
35
  !!_witchcraft
36
36
  end
37
37
 
38
- def cauldron
39
- @cauldron ||= Cauldron.new(self)
38
+ def cauldron(**options)
39
+ (@cauldron ||= {})[options] ||= Cauldron.new(self, **options)
40
40
  end
41
41
  end
42
42
 
43
43
  class Cauldron
44
44
  attr_reader :locals
45
45
 
46
- def initialize(type)
46
+ # @param type [Chewy::Type] type for composition
47
+ # @param fields [Array<Symbol>] restricts the fields for composition
48
+ def initialize(type, fields: [])
47
49
  @type = type
48
50
  @locals = []
51
+ @fields = fields
49
52
  end
50
53
 
51
54
  def brew(object, crutches = nil)
@@ -91,7 +94,7 @@ module Chewy
91
94
  end
92
95
 
93
96
  def non_proc_values(field, nesting)
94
- non_proc_fields = non_proc_fields_for(field)
97
+ non_proc_fields = non_proc_fields_for(field, nesting)
95
98
  object = "object#{nesting}"
96
99
 
97
100
  if non_proc_fields.present?
@@ -100,13 +103,13 @@ module Chewy
100
103
  {
101
104
  #{non_proc_fields.map do |f|
102
105
  fetcher = "#{object}.has_key?(:#{f.name}) ? #{object}[:#{f.name}] : #{object}['#{f.name}']"
103
- "#{f.name}: #{composed_value(f, fetcher, nesting)}"
106
+ "'#{f.name}'.freeze => #{composed_value(f, fetcher, nesting)}"
104
107
  end.join(', ')}
105
108
  }
106
109
  else
107
110
  {
108
111
  #{non_proc_fields.map do |f|
109
- "#{f.name}: #{composed_value(f, "#{object}.#{f.name}", nesting)}"
112
+ "'#{f.name}'.freeze => #{composed_value(f, "#{object}.#{f.name}", nesting)}"
110
113
  end.join(', ')}
111
114
  }
112
115
  end)
@@ -117,13 +120,13 @@ module Chewy
117
120
  end
118
121
 
119
122
  def proc_values(field, nesting)
120
- proc_fields = proc_fields_for(field)
123
+ proc_fields = proc_fields_for(field, nesting)
121
124
 
122
125
  if proc_fields.present?
123
126
  <<-RUBY
124
127
  {
125
128
  #{proc_fields.map do |f|
126
- "#{f.name}: (#{composed_value(f, source_for(f.value, nesting), nesting)})"
129
+ "'#{f.name}'.freeze => (#{composed_value(f, source_for(f.value, nesting), nesting)})"
127
130
  end.join(', ')}
128
131
  }
129
132
  RUBY
@@ -132,14 +135,26 @@ module Chewy
132
135
  end
133
136
  end
134
137
 
135
- def non_proc_fields_for(parent)
138
+ def non_proc_fields_for(parent, nesting)
136
139
  return [] unless parent
137
- (parent.children || []).select { |field| !(field.value && field.value.is_a?(Proc)) }
140
+ fields = (parent.children || []).reject { |field| field.value && field.value.is_a?(Proc) }
141
+
142
+ if nesting.zero? && @fields.present?
143
+ fields.select { |f| @fields.include?(f.name) }
144
+ else
145
+ fields
146
+ end
138
147
  end
139
148
 
140
- def proc_fields_for(parent)
149
+ def proc_fields_for(parent, nesting)
141
150
  return [] unless parent
142
- (parent.children || []).select { |field| field.value && field.value.is_a?(Proc) }
151
+ fields = (parent.children || []).select { |field| field.value && field.value.is_a?(Proc) }
152
+
153
+ if nesting.zero? && @fields.present?
154
+ fields.select { |f| @fields.include?(f.name) }
155
+ else
156
+ fields
157
+ end
143
158
  end
144
159
 
145
160
  def source_for(proc, nesting)
@@ -166,7 +181,6 @@ module Chewy
166
181
  locals.push(proc.binding.eval(variable.to_s))
167
182
  source = replace_local(source, variable, locals.size - 1)
168
183
  end
169
-
170
184
  end
171
185
 
172
186
  Unparser.unparse(source)
@@ -3,22 +3,48 @@ module Chewy
3
3
  module Wrapper
4
4
  extend ActiveSupport::Concern
5
5
 
6
- attr_accessor :attributes, :_data, :_object
6
+ included do
7
+ attr_accessor :_data, :_object
8
+ attr_reader :attributes
9
+ end
10
+
11
+ module ClassMethods
12
+ def build(hit)
13
+ attributes = (hit['_source'] || {})
14
+ .reverse_merge(id: hit['_id'])
15
+ .merge!(_score: hit['_score'])
16
+ .merge!(_explanation: hit['_explanation'])
17
+
18
+ wrapper = new(attributes)
19
+ wrapper._data = hit
20
+ wrapper
21
+ end
22
+ end
7
23
 
8
24
  def initialize(attributes = {})
9
25
  @attributes = attributes.stringify_keys
10
26
  end
11
27
 
12
28
  def ==(other)
29
+ return true if super
30
+
13
31
  if other.is_a?(Chewy::Type)
14
32
  self.class == other.class && (respond_to?(:id) ? id == other.id : attributes == other.attributes)
15
33
  elsif other.respond_to?(:id)
16
- id.to_s == other.id.to_s
34
+ self.class.adapter.target.is_a?(Class) &&
35
+ other.is_a?(self.class.adapter.target) &&
36
+ id.to_s == other.id.to_s
17
37
  else
18
38
  false
19
39
  end
20
40
  end
21
41
 
42
+ %w[_id _type _index].each do |name|
43
+ define_method name do
44
+ data[name]
45
+ end
46
+ end
47
+
22
48
  def method_missing(method, *args, &block)
23
49
  m = method.to_s
24
50
  if (name = highlight_name(m))
@@ -1,3 +1,3 @@
1
1
  module Chewy
2
- VERSION = '0.9.0'.freeze
2
+ VERSION = '0.10.0'.freeze
3
3
  end
@@ -1,34 +1,96 @@
1
1
  require 'chewy/rake_helper'
2
2
 
3
+ def parse_classes(args)
4
+ if args.present? && args.first.tr!('-', '')
5
+ {except: args}
6
+ else
7
+ {only: args}
8
+ end
9
+ end
10
+
11
+ def parse_parallel_args(args)
12
+ options = {}
13
+ options[:parallel] = args.first =~ /\A\d+\z/ ? Integer(args.shift) : true
14
+ options.merge!(parse_classes(args))
15
+ end
16
+
17
+ def parse_journal_args(args)
18
+ options = {}
19
+ options[:time] = Time.parse(args.shift) if args.first =~ /\A\d+/
20
+ options.merge!(parse_classes(args))
21
+ end
22
+
3
23
  namespace :chewy do
4
- desc 'Destroy, recreate and import data to specified index'
24
+ desc 'Destroys, recreates and imports data for the specified indexes or all of them'
5
25
  task reset: :environment do |_task, args|
6
- Chewy::RakeHelper.subscribed_task_stats do
7
- indexes = args.extras
26
+ Chewy::RakeHelper.reset(parse_classes(args.extras))
27
+ end
8
28
 
9
- if indexes.empty? || indexes.first.tr!('-', '')
10
- Chewy::RakeHelper.reset_all(indexes)
11
- else
12
- Chewy::RakeHelper.reset_index(indexes)
13
- end
14
- end
29
+ desc 'Resets data for the specified indexes or all of them only if the index specification is changed'
30
+ task upgrade: :environment do |_task, args|
31
+ Chewy::RakeHelper.upgrade(parse_classes(args.extras))
15
32
  end
16
33
 
17
- desc 'Updates data specified index'
34
+ desc 'Updates data for the specified indexes/types or all of them'
18
35
  task update: :environment do |_task, args|
19
- Chewy::RakeHelper.subscribed_task_stats do
20
- indexes = args.extras
36
+ Chewy::RakeHelper.update(parse_classes(args.extras))
37
+ end
21
38
 
22
- if indexes.empty? || indexes.first.tr!('-', '')
23
- Chewy::RakeHelper.update_all(indexes)
24
- else
25
- Chewy::RakeHelper.update_index(indexes)
26
- end
39
+ desc 'Synchronizes data for the specified indexes/types or all of them'
40
+ task sync: :environment do |_task, args|
41
+ Chewy::RakeHelper.sync(parse_classes(args.extras))
42
+ end
43
+
44
+ desc 'Resets all the indexes with the specification changed and synchronizes the rest of them'
45
+ task deploy: :environment do
46
+ processed = Chewy::RakeHelper.upgrade
47
+ Chewy::RakeHelper.sync(except: processed)
48
+ end
49
+
50
+ namespace :parallel do
51
+ desc 'Parallel version of `rake chewy:reset`'
52
+ task reset: :environment do |_task, args|
53
+ Chewy::RakeHelper.reset(parse_parallel_args(args.extras))
54
+ end
55
+
56
+ desc 'Parallel version of `rake chewy:upgrade`'
57
+ task upgrade: :environment do |_task, args|
58
+ Chewy::RakeHelper.upgrade(parse_parallel_args(args.extras))
59
+ end
60
+
61
+ desc 'Parallel version of `rake chewy:update`'
62
+ task update: :environment do |_task, args|
63
+ Chewy::RakeHelper.update(parse_parallel_args(args.extras))
64
+ end
65
+
66
+ desc 'Parallel version of `rake chewy:sync`'
67
+ task sync: :environment do |_task, args|
68
+ Chewy::RakeHelper.sync(parse_parallel_args(args.extras))
69
+ end
70
+
71
+ desc 'Parallel version of `rake chewy:deploy`'
72
+ task deploy: :environment do |_task, args|
73
+ parallel = args.extras.first =~ /\A\d+\z/ ? Integer(args.extras.first) : true
74
+ processed = Chewy::RakeHelper.upgrade(parallel: parallel)
75
+ Chewy::RakeHelper.sync(except: processed, parallel: parallel)
76
+ end
77
+ end
78
+
79
+ namespace :journal do
80
+ desc 'Applies changes that were done after the specified time for the specified indexes/types or all of them'
81
+ task apply: :environment do |_task, args|
82
+ Chewy::RakeHelper.journal_apply(parse_journal_args(args.extras))
83
+ end
84
+
85
+ desc 'Removes journal records created before the specified timestamp for the specified indexes/types or all of them'
86
+ task clean: :environment do |_task, args|
87
+ Chewy::RakeHelper.journal_clean(parse_journal_args(args.extras))
27
88
  end
28
89
  end
29
90
 
30
- desc 'Applies changes that were done from specified moment (as a timestamp)'
31
91
  task apply_changes_from: :environment do |_task, args|
92
+ ActiveSupport::Deprecation.warn '`rake chewy:apply_changes_from` is deprecated and will be removed soon, use `rake chewy:journal:apply` instead'
93
+
32
94
  Chewy::RakeHelper.subscribed_task_stats do
33
95
  params = args.extras
34
96
 
@@ -37,18 +99,14 @@ namespace :chewy do
37
99
  else
38
100
  timestamp, retries = params
39
101
  time = Time.at(timestamp.to_i)
40
- Chewy::Journal::Apply.since(time, retries: (retries.to_i if retries))
102
+ Chewy::Journal.new.apply(time, retries: (retries.to_i if retries))
41
103
  end
42
104
  end
43
105
  end
44
106
 
45
- desc 'Cleans journal index. It accepts timestamp until which journal will be cleaned'
46
107
  task clean_journal: :environment do |_task, args|
47
- timestamp = args.extras.first
48
- if timestamp
49
- Chewy::Journal::Clean.until(Time.at(timestamp.to_i))
50
- else
51
- Chewy::Journal.delete!
52
- end
108
+ ActiveSupport::Deprecation.warn '`rake chewy:clean_journal` is deprecated and will be removed soon, use `rake chewy:journal:clean` instead'
109
+
110
+ Chewy::Journal.new.clean(args.extras.first)
53
111
  end
54
112
  end
@@ -13,6 +13,10 @@ describe Chewy::Config do
13
13
  its(:request_strategy) { should == :atomic }
14
14
  its(:use_after_commit_callbacks) { should == true }
15
15
  its(:indices_path) { should == 'app/chewy' }
16
+ its(:reset_disable_refresh_interval) { should == false }
17
+ its(:reset_no_replicas) { should == false }
18
+ its(:disable_refresh_async) { should == false }
19
+ its(:search_class) { should be < Chewy::Search::Request }
16
20
 
17
21
  describe '#transport_logger=' do
18
22
  let(:logger) { Logger.new('/dev/null') }
@@ -50,8 +54,85 @@ describe Chewy::Config do
50
54
  end
51
55
  end
52
56
 
57
+ describe '#search_class=' do
58
+ specify do
59
+ expect { subject.search_class = Chewy::Query }
60
+ .to change { subject.search_class }
61
+ .from(be < Chewy::Search::Request)
62
+ .to(be < Chewy::Query)
63
+ end
64
+
65
+ context do
66
+ before { hide_const('Kaminari') }
67
+
68
+ specify do
69
+ expect(subject.search_class.included_modules)
70
+ .to include(Chewy::Search::Pagination::WillPaginate)
71
+ end
72
+ end
73
+ end
74
+
75
+ describe '#search_class' do
76
+ context 'nothing is defined' do
77
+ before do
78
+ hide_const('Kaminari')
79
+ hide_const('WillPaginate')
80
+ end
81
+
82
+ specify do
83
+ expect(subject.search_class.included_modules)
84
+ .not_to include(Chewy::Search::Pagination::Kaminari)
85
+ end
86
+
87
+ specify do
88
+ expect(subject.search_class.included_modules)
89
+ .not_to include(Chewy::Search::Pagination::WillPaginate)
90
+ end
91
+ end
92
+
93
+ context 'kaminari' do
94
+ before { hide_const('WillPaginate') }
95
+
96
+ specify do
97
+ expect(subject.search_class.included_modules)
98
+ .to include(Chewy::Search::Pagination::Kaminari)
99
+ end
100
+
101
+ specify do
102
+ expect(subject.search_class.included_modules)
103
+ .not_to include(Chewy::Search::Pagination::WillPaginate)
104
+ end
105
+ end
106
+
107
+ context 'will_paginate' do
108
+ before { hide_const('Kaminari') }
109
+
110
+ specify do
111
+ expect(subject.search_class.included_modules)
112
+ .not_to include(Chewy::Search::Pagination::Kaminari)
113
+ end
114
+
115
+ specify do
116
+ expect(subject.search_class.included_modules)
117
+ .to include(Chewy::Search::Pagination::WillPaginate)
118
+ end
119
+ end
120
+
121
+ context 'both are defined' do
122
+ specify do
123
+ expect(subject.search_class.included_modules)
124
+ .to include(Chewy::Search::Pagination::Kaminari)
125
+ end
126
+
127
+ specify do
128
+ expect(subject.search_class.included_modules)
129
+ .not_to include(Chewy::Search::Pagination::WillPaginate)
130
+ end
131
+ end
132
+ end
133
+
53
134
  describe '#configuration' do
54
- before { subject.settings = { indices_path: 'app/custom_indices_path' } }
135
+ before { subject.settings = {indices_path: 'app/custom_indices_path'} }
55
136
 
56
137
  specify do
57
138
  expect(subject.configuration).to include(indices_path: 'app/custom_indices_path')
@@ -8,7 +8,7 @@ describe Chewy::Fields::Base do
8
8
  let(:field) { described_class.new(:name, value: ->(o) { o.value }) }
9
9
 
10
10
  specify { expect(field.compose(double(value: 'hello'))).to eq(name: 'hello') }
11
- specify { expect(field.compose(double(value: %w(hello world)))).to eq(name: %w(hello world)) }
11
+ specify { expect(field.compose(double(value: %w[hello world]))).to eq(name: %w[hello world]) }
12
12
 
13
13
  specify { expect(described_class.new(:name).compose(double(name: 'hello'))).to eq(name: 'hello') }
14
14
  specify { expect(described_class.new(:false_value).compose(false_value: false)).to eq(false_value: false) }
@@ -24,23 +24,24 @@ describe Chewy::Fields::Base do
24
24
 
25
25
  specify do
26
26
  expect(field.compose(double(value: double(subvalue1: 'hello', subvalue2: 'value', subname3: 'world'))))
27
- .to eq(name: { subname1: 'hello', subname2: 'value', subname3: 'world' })
27
+ .to eq(name: {subname1: 'hello', subname2: 'value', subname3: 'world'})
28
28
  end
29
29
  specify do
30
30
  expect(field.compose(double(value: [
31
31
  double(subvalue1: 'hello1', subvalue2: 'value1', subname3: 'world1'),
32
32
  double(subvalue1: 'hello2', subvalue2: 'value2', subname3: 'world2')
33
33
  ]))).to eq(name: [
34
- { subname1: 'hello1', subname2: 'value1', subname3: 'world1' },
35
- { subname1: 'hello2', subname2: 'value2', subname3: 'world2' }
34
+ {subname1: 'hello1', subname2: 'value1', subname3: 'world1'},
35
+ {subname1: 'hello2', subname2: 'value2', subname3: 'world2'}
36
36
  ])
37
37
  end
38
38
  end
39
39
 
40
40
  context 'parent objects' do
41
- let!(:country) { described_class.new(:name, value: ->(country) { country.cities }) }
42
- let!(:city) { described_class.new(:name, value: ->(city, country) { city.districts.map { |district| [district, country.name] } }) }
43
- let!(:district) { described_class.new(:name, value: ->(district, city, country) { [district, city.name, country.name] }) }
41
+ let!(:country) { described_class.new(:name, value: ->(country, crutches) { country.cities.map { |city| double(districts: city.districts, name: crutches.city_name) } }) }
42
+ let!(:city) { described_class.new(:name, value: ->(city, country, crutches) { city.districts.map { |district| [district, country.name, crutches.suffix] } }) }
43
+ let!(:district) { described_class.new(:name, value: ->(district, city, country, crutches) { [district, city.name, country.name, crutches] }) }
44
+ let(:crutches) { double(suffix: 'suffix', city_name: 'Bangkok') }
44
45
 
45
46
  before do
46
47
  country.children.push(city)
@@ -49,12 +50,12 @@ describe Chewy::Fields::Base do
49
50
 
50
51
  specify do
51
52
  expect(country.compose(double(name: 'Thailand', cities: [
52
- double(name: 'Bangkok', districts: %w(First Second))
53
- ]))).to eq(name: [
54
- { name: [
55
- { name: [%w(First Thailand), 'Bangkok', 'Thailand'] },
56
- { name: [%w(Second Thailand), 'Bangkok', 'Thailand'] }
57
- ] }
53
+ double(districts: %w[First Second])
54
+ ]), crutches)).to eq(name: [
55
+ {name: [
56
+ {name: [%w[First Thailand suffix], 'Bangkok', 'Thailand', crutches]},
57
+ {name: [%w[Second Thailand suffix], 'Bangkok', 'Thailand', crutches]}
58
+ ]}
58
59
  ])
59
60
  end
60
61
  end
@@ -71,14 +72,14 @@ describe Chewy::Fields::Base do
71
72
 
72
73
  context 'hash values' do
73
74
  let(:field) { described_class.new(:name, type: 'object') }
74
- let(:object) { double(name: { key1: 'value1', key2: 'value2' }) }
75
+ let(:object) { double(name: {key1: 'value1', key2: 'value2'}) }
75
76
 
76
77
  before do
77
78
  field.children.push(described_class.new(:key1, value: ->(h) { h[:key1] }))
78
79
  field.children.push(described_class.new(:key2, value: ->(h) { h[:key2] }))
79
80
  end
80
81
 
81
- specify { expect(field.compose(object)).to eq(name: { key1: 'value1', key2: 'value2' }) }
82
+ specify { expect(field.compose(object)).to eq(name: {key1: 'value1', key2: 'value2'}) }
82
83
  end
83
84
  end
84
85
 
@@ -92,11 +93,11 @@ describe Chewy::Fields::Base do
92
93
  end
93
94
 
94
95
  specify do
95
- expect(field.mappings_hash).to eq(name: { type: :object, properties: {
96
- name1: { type: 'string1', fields: {
97
- name3: { type: 'string3' }, name4: { type: 'string4' }
98
- } }, name2: { type: 'string2' }
99
- } })
96
+ expect(field.mappings_hash).to eq(name: {type: :object, properties: {
97
+ name1: {type: 'string1', fields: {
98
+ name3: {type: 'string3'}, name4: {type: 'string4'}
99
+ }}, name2: {type: 'string2'}
100
+ }})
100
101
  end
101
102
 
102
103
  context do
@@ -104,11 +105,11 @@ describe Chewy::Fields::Base do
104
105
  let(:fields1) { Array.new(2) { |i| described_class.new("name#{i + 1}") } }
105
106
 
106
107
  specify do
107
- expect(field.mappings_hash).to eq(name: { type: :string, fields: {
108
- name1: { type: 'object', properties: {
109
- name3: { type: 'string3' }, name4: { type: 'string4' }
110
- } }, name2: { type: 'string' }
111
- } })
108
+ expect(field.mappings_hash).to eq(name: {type: :string, fields: {
109
+ name1: {type: 'object', properties: {
110
+ name3: {type: 'string3'}, name4: {type: 'string4'}
111
+ }}, name2: {type: 'string'}
112
+ }})
112
113
  end
113
114
  end
114
115
  end
@@ -132,85 +133,115 @@ describe Chewy::Fields::Base do
132
133
 
133
134
  specify do
134
135
  expect(EventsIndex::Event.mappings_hash).to eq(event: {
135
- properties: {
136
- id: { type: 'string' },
137
- category: {
138
- type: 'object',
139
- properties: {
140
- id: { type: 'string' },
141
- licenses: {
142
- type: 'object',
143
- properties: {
144
- id: { type: 'string' },
145
- name: { type: 'string' }
146
- }
147
- }
148
- }
149
- }
150
- }
151
- })
136
+ properties: {
137
+ id: {type: 'string'},
138
+ category: {
139
+ type: 'object',
140
+ properties: {
141
+ id: {type: 'string'},
142
+ licenses: {
143
+ type: 'object',
144
+ properties: {
145
+ id: {type: 'string'},
146
+ name: {type: 'string'}
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+ })
153
+ end
154
+
155
+ context 'default field type' do
156
+ around do |example|
157
+ previous_type = Chewy.default_field_type
158
+ Chewy.default_field_type = 'text'
159
+ example.run
160
+ Chewy.default_field_type = previous_type
161
+ end
162
+
163
+ specify do
164
+ expect(EventsIndex::Event.mappings_hash).to eq(event: {
165
+ properties: {
166
+ id: {type: 'text'},
167
+ category: {
168
+ type: 'object',
169
+ properties: {
170
+ id: {type: 'text'},
171
+ licenses: {
172
+ type: 'object',
173
+ properties: {
174
+ id: {type: 'text'},
175
+ name: {type: 'text'}
176
+ }
177
+ }
178
+ }
179
+ }
180
+ }
181
+ })
182
+ end
152
183
  end
153
184
 
154
185
  specify do
155
186
  expect(EventsIndex::Event.root_object.compose(
156
- id: 1, category: { id: 2, licenses: { id: 3, name: 'Name' } }
157
- )).to eq('event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => { 'id' => 3, 'name' => 'Name' } } })
187
+ id: 1, category: {id: 2, licenses: {id: 3, name: 'Name'}}
188
+ )).to eq('id' => 1, 'category' => {'id' => 2, 'licenses' => {'id' => 3, 'name' => 'Name'}})
158
189
  end
159
190
 
160
191
  specify do
161
192
  expect(EventsIndex::Event.root_object.compose(id: 1, category: [
162
- { id: 2, 'licenses' => { id: 3, name: 'Name1' } },
163
- { id: 4, licenses: nil }
164
- ])).to eq('event' => { 'id' => 1, 'category' => [
165
- { 'id' => 2, 'licenses' => { 'id' => 3, 'name' => 'Name1' } },
166
- { 'id' => 4, 'licenses' => nil.as_json }
167
- ] })
193
+ {id: 2, 'licenses' => {id: 3, name: 'Name1'}},
194
+ {id: 4, licenses: nil}
195
+ ])).to eq('id' => 1, 'category' => [
196
+ {'id' => 2, 'licenses' => {'id' => 3, 'name' => 'Name1'}},
197
+ {'id' => 4, 'licenses' => nil.as_json}
198
+ ])
168
199
  end
169
200
 
170
201
  specify do
171
- expect(EventsIndex::Event.root_object.compose('id' => 1, category: { id: 2, licenses: [
172
- { id: 3, name: 'Name1' }, { id: 4, name: 'Name2' }
173
- ] })).to eq('event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => [
174
- { 'id' => 3, 'name' => 'Name1' }, { 'id' => 4, 'name' => 'Name2' }
175
- ] } })
202
+ expect(EventsIndex::Event.root_object.compose('id' => 1, category: {id: 2, licenses: [
203
+ {id: 3, name: 'Name1'}, {id: 4, name: 'Name2'}
204
+ ]})).to eq('id' => 1, 'category' => {'id' => 2, 'licenses' => [
205
+ {'id' => 3, 'name' => 'Name1'}, {'id' => 4, 'name' => 'Name2'}
206
+ ]})
176
207
  end
177
208
 
178
209
  specify do
179
210
  expect(EventsIndex::Event.root_object.compose(id: 1, category: [
180
- { id: 2, licenses: [
181
- { id: 3, 'name' => 'Name1' }, { id: 4, name: 'Name2' }
182
- ] },
183
- { id: 5, licenses: [] }
184
- ])).to eq('event' => { 'id' => 1, 'category' => [
185
- { 'id' => 2, 'licenses' => [
186
- { 'id' => 3, 'name' => 'Name1' }, { 'id' => 4, 'name' => 'Name2' }
187
- ] },
188
- { 'id' => 5, 'licenses' => [] }
189
- ] })
211
+ {id: 2, licenses: [
212
+ {id: 3, 'name' => 'Name1'}, {id: 4, name: 'Name2'}
213
+ ]},
214
+ {id: 5, licenses: []}
215
+ ])).to eq('id' => 1, 'category' => [
216
+ {'id' => 2, 'licenses' => [
217
+ {'id' => 3, 'name' => 'Name1'}, {'id' => 4, 'name' => 'Name2'}
218
+ ]},
219
+ {'id' => 5, 'licenses' => []}
220
+ ])
190
221
  end
191
222
 
192
223
  specify do
193
224
  expect(EventsIndex::Event.root_object.compose(
194
225
  double(id: 1, category: double(id: 2, licenses: double(id: 3, name: 'Name')))
195
- )).to eq('event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => { 'id' => 3, 'name' => 'Name' } } })
226
+ )).to eq('id' => 1, 'category' => {'id' => 2, 'licenses' => {'id' => 3, 'name' => 'Name'}})
196
227
  end
197
228
 
198
229
  specify do
199
230
  expect(EventsIndex::Event.root_object.compose(double(id: 1, category: [
200
231
  double(id: 2, licenses: double(id: 3, name: 'Name1')),
201
232
  double(id: 4, licenses: nil)
202
- ]))).to eq('event' => { 'id' => 1, 'category' => [
203
- { 'id' => 2, 'licenses' => { 'id' => 3, 'name' => 'Name1' } },
204
- { 'id' => 4, 'licenses' => nil.as_json }
205
- ] })
233
+ ]))).to eq('id' => 1, 'category' => [
234
+ {'id' => 2, 'licenses' => {'id' => 3, 'name' => 'Name1'}},
235
+ {'id' => 4, 'licenses' => nil.as_json}
236
+ ])
206
237
  end
207
238
 
208
239
  specify do
209
240
  expect(EventsIndex::Event.root_object.compose(double(id: 1, category: double(id: 2, licenses: [
210
241
  double(id: 3, name: 'Name1'), double(id: 4, name: 'Name2')
211
- ])))).to eq('event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => [
212
- { 'id' => 3, 'name' => 'Name1' }, { 'id' => 4, 'name' => 'Name2' }
213
- ] } })
242
+ ])))).to eq('id' => 1, 'category' => {'id' => 2, 'licenses' => [
243
+ {'id' => 3, 'name' => 'Name1'}, {'id' => 4, 'name' => 'Name2'}
244
+ ]})
214
245
  end
215
246
 
216
247
  specify do
@@ -219,12 +250,12 @@ describe Chewy::Fields::Base do
219
250
  double(id: 3, name: 'Name1'), double(id: 4, name: 'Name2')
220
251
  ]),
221
252
  double(id: 5, licenses: [])
222
- ]))).to eq('event' => { 'id' => 1, 'category' => [
223
- { 'id' => 2, 'licenses' => [
224
- { 'id' => 3, 'name' => 'Name1' }, { 'id' => 4, 'name' => 'Name2' }
225
- ] },
226
- { 'id' => 5, 'licenses' => [] }
227
- ] })
253
+ ]))).to eq('id' => 1, 'category' => [
254
+ {'id' => 2, 'licenses' => [
255
+ {'id' => 3, 'name' => 'Name1'}, {'id' => 4, 'name' => 'Name2'}
256
+ ]},
257
+ {'id' => 5, 'licenses' => []}
258
+ ])
228
259
  end
229
260
  end
230
261
 
@@ -247,7 +278,7 @@ describe Chewy::Fields::Base do
247
278
  specify do
248
279
  expect(EventsIndex::Event.root_object.compose(
249
280
  double(id: 1, categories: double(id: 2, license: double(id: 3, name: 'Name')))
250
- )).to eq('event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => { 'id' => 3, 'name' => 'Name' } } })
281
+ )).to eq('id' => 1, 'category' => {'id' => 2, 'licenses' => {'id' => 3, 'name' => 'Name'}})
251
282
  end
252
283
  end
253
284
 
@@ -266,43 +297,43 @@ describe Chewy::Fields::Base do
266
297
 
267
298
  specify do
268
299
  expect(EventsIndex::Event.mappings_hash).to eq(event: {
269
- properties: {
270
- id: { type: 'string' },
271
- name: {
272
- type: 'string',
273
- fields: {
274
- raw: { analyzer: 'my_own', type: 'string' }
275
- }
276
- },
277
- category: { type: 'object' }
278
- }
279
- })
300
+ properties: {
301
+ id: {type: 'string'},
302
+ name: {
303
+ type: 'string',
304
+ fields: {
305
+ raw: {analyzer: 'my_own', type: 'string'}
306
+ }
307
+ },
308
+ category: {type: 'object'}
309
+ }
310
+ })
280
311
  end
281
312
 
282
313
  specify do
283
314
  expect(EventsIndex::Event.root_object.compose(
284
- double(id: 1, name: 'Jonny', category: double(id: 2, as_json: { 'name' => 'Borogoves' }))
285
- )).to eq('event' => {
286
- 'id' => 1,
287
- 'name' => 'Jonny',
288
- 'category' => { 'name' => 'Borogoves' }
289
- })
315
+ double(id: 1, name: 'Jonny', category: double(id: 2, as_json: {'name' => 'Borogoves'}))
316
+ )).to eq(
317
+ 'id' => 1,
318
+ 'name' => 'Jonny',
319
+ 'category' => {'name' => 'Borogoves'}
320
+ )
290
321
  end
291
322
 
292
323
  specify do
293
324
  expect(EventsIndex::Event.root_object.compose(
294
325
  double(id: 1, name: 'Jonny', category: [
295
- double(id: 2, as_json: { 'name' => 'Borogoves1' }),
296
- double(id: 3, as_json: { 'name' => 'Borogoves2' })
326
+ double(id: 2, as_json: {'name' => 'Borogoves1'}),
327
+ double(id: 3, as_json: {'name' => 'Borogoves2'})
297
328
  ])
298
- )).to eq('event' => {
299
- 'id' => 1,
300
- 'name' => 'Jonny',
301
- 'category' => [
302
- { 'name' => 'Borogoves1' },
303
- { 'name' => 'Borogoves2' }
304
- ]
305
- })
329
+ )).to eq(
330
+ 'id' => 1,
331
+ 'name' => 'Jonny',
332
+ 'category' => [
333
+ {'name' => 'Borogoves1'},
334
+ {'name' => 'Borogoves2'}
335
+ ]
336
+ )
306
337
  end
307
338
  end
308
339
 
@@ -320,7 +351,11 @@ describe Chewy::Fields::Base do
320
351
  Country.has_many :cities, order: :id
321
352
  end
322
353
  when :mongoid
323
- City.belongs_to :country
354
+ if Mongoid::VERSION.start_with?('6')
355
+ City.belongs_to :country, optional: true
356
+ else
357
+ City.belongs_to :country
358
+ end
324
359
  Country.has_many :cities, order: :id.asc
325
360
  when :sequel
326
361
  City.many_to_one :country
@@ -351,9 +386,9 @@ describe Chewy::Fields::Base do
351
386
  end
352
387
 
353
388
  specify do
354
- expect(CountriesIndex::Country.root_object.compose(country_with_cities)).to eq('country' => { 'id' => 1, 'cities' => [
355
- { 'id' => 1, 'name' => 'City1' }, { 'id' => 2, 'name' => 'City2' }
356
- ] })
389
+ expect(CountriesIndex::Country.root_object.compose(country_with_cities)).to eq('id' => 1, 'cities' => [
390
+ {'id' => 1, 'name' => 'City1'}, {'id' => 2, 'name' => 'City2'}
391
+ ])
357
392
  end
358
393
 
359
394
  context 'nested object' do
@@ -372,7 +407,7 @@ describe Chewy::Fields::Base do
372
407
  specify do
373
408
  expect(CitiesIndex::City.root_object.compose(
374
409
  City.create!(id: 1, country: Country.create!(id: 1, name: 'Country'))
375
- )).to eq('city' => { 'id' => 1, 'country' => { 'id' => 1, 'name' => 'Country' } })
410
+ )).to eq('id' => 1, 'country' => {'id' => 1, 'name' => 'Country'})
376
411
  end
377
412
  end
378
413
  end