chewy 0.8.4 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (303) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +56 -0
  4. data/.rubocop_todo.yml +44 -0
  5. data/.travis.yml +36 -67
  6. data/.yardopts +5 -0
  7. data/Appraisals +63 -58
  8. data/CHANGELOG.md +168 -11
  9. data/Gemfile +16 -9
  10. data/Guardfile +5 -5
  11. data/LEGACY_DSL.md +497 -0
  12. data/README.md +403 -470
  13. data/Rakefile +11 -1
  14. data/chewy.gemspec +12 -15
  15. data/gemfiles/rails.4.0.activerecord.gemfile +9 -9
  16. data/gemfiles/rails.4.1.activerecord.gemfile +9 -9
  17. data/gemfiles/rails.4.2.activerecord.gemfile +8 -8
  18. data/gemfiles/rails.4.2.mongoid.5.2.gemfile +16 -0
  19. data/gemfiles/rails.5.0.activerecord.gemfile +16 -0
  20. data/gemfiles/rails.5.0.mongoid.6.1.gemfile +16 -0
  21. data/gemfiles/rails.5.1.activerecord.gemfile +16 -0
  22. data/gemfiles/rails.5.1.mongoid.6.3.gemfile +16 -0
  23. data/gemfiles/rails.5.2.activerecord.gemfile +16 -0
  24. data/gemfiles/sequel.4.45.gemfile +11 -0
  25. data/lib/chewy/backports/deep_dup.rb +1 -1
  26. data/lib/chewy/backports/duplicable.rb +1 -0
  27. data/lib/chewy/config.rb +53 -21
  28. data/lib/chewy/errors.rb +6 -6
  29. data/lib/chewy/fields/base.rb +59 -29
  30. data/lib/chewy/fields/root.rb +49 -14
  31. data/lib/chewy/index/actions.rb +95 -36
  32. data/lib/chewy/index/aliases.rb +2 -1
  33. data/lib/chewy/index/settings.rb +10 -5
  34. data/lib/chewy/index/specification.rb +60 -0
  35. data/lib/chewy/index.rb +239 -138
  36. data/lib/chewy/journal.rb +55 -0
  37. data/lib/chewy/log_subscriber.rb +8 -8
  38. data/lib/chewy/minitest/helpers.rb +77 -0
  39. data/lib/chewy/minitest/search_index_receiver.rb +80 -0
  40. data/lib/chewy/minitest.rb +1 -0
  41. data/lib/chewy/query/compose.rb +18 -19
  42. data/lib/chewy/query/criteria.rb +34 -24
  43. data/lib/chewy/query/filters.rb +28 -11
  44. data/lib/chewy/query/loading.rb +3 -4
  45. data/lib/chewy/query/nodes/and.rb +1 -1
  46. data/lib/chewy/query/nodes/base.rb +1 -1
  47. data/lib/chewy/query/nodes/bool.rb +6 -4
  48. data/lib/chewy/query/nodes/equal.rb +4 -4
  49. data/lib/chewy/query/nodes/exists.rb +1 -1
  50. data/lib/chewy/query/nodes/expr.rb +2 -2
  51. data/lib/chewy/query/nodes/field.rb +35 -31
  52. data/lib/chewy/query/nodes/has_child.rb +1 -0
  53. data/lib/chewy/query/nodes/has_parent.rb +1 -0
  54. data/lib/chewy/query/nodes/has_relation.rb +10 -12
  55. data/lib/chewy/query/nodes/missing.rb +1 -1
  56. data/lib/chewy/query/nodes/not.rb +1 -1
  57. data/lib/chewy/query/nodes/or.rb +1 -1
  58. data/lib/chewy/query/nodes/prefix.rb +3 -2
  59. data/lib/chewy/query/nodes/query.rb +1 -1
  60. data/lib/chewy/query/nodes/range.rb +9 -9
  61. data/lib/chewy/query/nodes/raw.rb +1 -1
  62. data/lib/chewy/query/nodes/regexp.rb +13 -9
  63. data/lib/chewy/query/nodes/script.rb +4 -4
  64. data/lib/chewy/query/pagination.rb +10 -1
  65. data/lib/chewy/query.rb +286 -170
  66. data/lib/chewy/railtie.rb +7 -6
  67. data/lib/chewy/rake_helper.rb +275 -37
  68. data/lib/chewy/repository.rb +2 -2
  69. data/lib/chewy/rspec/update_index.rb +70 -65
  70. data/lib/chewy/rspec.rb +1 -1
  71. data/lib/chewy/runtime/version.rb +4 -4
  72. data/lib/chewy/search/loader.rb +83 -0
  73. data/lib/chewy/{query → search}/pagination/kaminari.rb +13 -5
  74. data/lib/chewy/search/pagination/will_paginate.rb +43 -0
  75. data/lib/chewy/search/parameters/aggs.rb +16 -0
  76. data/lib/chewy/search/parameters/allow_partial_search_results.rb +27 -0
  77. data/lib/chewy/search/parameters/concerns/bool_storage.rb +24 -0
  78. data/lib/chewy/search/parameters/concerns/hash_storage.rb +23 -0
  79. data/lib/chewy/search/parameters/concerns/integer_storage.rb +14 -0
  80. data/lib/chewy/search/parameters/concerns/query_storage.rb +238 -0
  81. data/lib/chewy/search/parameters/concerns/string_array_storage.rb +23 -0
  82. data/lib/chewy/search/parameters/concerns/string_storage.rb +14 -0
  83. data/lib/chewy/search/parameters/docvalue_fields.rb +12 -0
  84. data/lib/chewy/search/parameters/explain.rb +16 -0
  85. data/lib/chewy/search/parameters/filter.rb +47 -0
  86. data/lib/chewy/search/parameters/highlight.rb +16 -0
  87. data/lib/chewy/search/parameters/indices.rb +123 -0
  88. data/lib/chewy/search/parameters/indices_boost.rb +52 -0
  89. data/lib/chewy/search/parameters/limit.rb +17 -0
  90. data/lib/chewy/search/parameters/load.rb +32 -0
  91. data/lib/chewy/search/parameters/min_score.rb +16 -0
  92. data/lib/chewy/search/parameters/none.rb +27 -0
  93. data/lib/chewy/search/parameters/offset.rb +17 -0
  94. data/lib/chewy/search/parameters/order.rb +64 -0
  95. data/lib/chewy/search/parameters/post_filter.rb +19 -0
  96. data/lib/chewy/search/parameters/preference.rb +16 -0
  97. data/lib/chewy/search/parameters/profile.rb +16 -0
  98. data/lib/chewy/search/parameters/query.rb +19 -0
  99. data/lib/chewy/search/parameters/request_cache.rb +27 -0
  100. data/lib/chewy/search/parameters/rescore.rb +29 -0
  101. data/lib/chewy/search/parameters/script_fields.rb +16 -0
  102. data/lib/chewy/search/parameters/search_after.rb +20 -0
  103. data/lib/chewy/search/parameters/search_type.rb +16 -0
  104. data/lib/chewy/search/parameters/source.rb +73 -0
  105. data/lib/chewy/search/parameters/storage.rb +95 -0
  106. data/lib/chewy/search/parameters/stored_fields.rb +63 -0
  107. data/lib/chewy/search/parameters/suggest.rb +16 -0
  108. data/lib/chewy/search/parameters/terminate_after.rb +16 -0
  109. data/lib/chewy/search/parameters/timeout.rb +16 -0
  110. data/lib/chewy/search/parameters/track_scores.rb +16 -0
  111. data/lib/chewy/search/parameters/types.rb +20 -0
  112. data/lib/chewy/search/parameters/version.rb +16 -0
  113. data/lib/chewy/search/parameters.rb +167 -0
  114. data/lib/chewy/search/query_proxy.rb +257 -0
  115. data/lib/chewy/search/request.rb +1045 -0
  116. data/lib/chewy/search/response.rb +119 -0
  117. data/lib/chewy/search/scoping.rb +50 -0
  118. data/lib/chewy/search/scrolling.rb +134 -0
  119. data/lib/chewy/search.rb +81 -26
  120. data/lib/chewy/stash.rb +79 -0
  121. data/lib/chewy/strategy/active_job.rb +1 -0
  122. data/lib/chewy/strategy/atomic.rb +2 -4
  123. data/lib/chewy/strategy/base.rb +4 -4
  124. data/lib/chewy/strategy/bypass.rb +1 -2
  125. data/lib/chewy/strategy/resque.rb +1 -0
  126. data/lib/chewy/strategy/shoryuken.rb +40 -0
  127. data/lib/chewy/strategy/sidekiq.rb +13 -1
  128. data/lib/chewy/strategy/urgent.rb +1 -1
  129. data/lib/chewy/strategy.rb +19 -10
  130. data/lib/chewy/type/actions.rb +26 -2
  131. data/lib/chewy/type/adapter/active_record.rb +50 -24
  132. data/lib/chewy/type/adapter/base.rb +29 -9
  133. data/lib/chewy/type/adapter/mongoid.rb +19 -10
  134. data/lib/chewy/type/adapter/object.rb +195 -31
  135. data/lib/chewy/type/adapter/orm.rb +69 -33
  136. data/lib/chewy/type/adapter/sequel.rb +37 -19
  137. data/lib/chewy/type/crutch.rb +5 -4
  138. data/lib/chewy/type/import/bulk_builder.rb +122 -0
  139. data/lib/chewy/type/import/bulk_request.rb +78 -0
  140. data/lib/chewy/type/import/journal_builder.rb +45 -0
  141. data/lib/chewy/type/import/routine.rb +138 -0
  142. data/lib/chewy/type/import.rb +150 -176
  143. data/lib/chewy/type/mapping.rb +58 -42
  144. data/lib/chewy/type/observe.rb +21 -15
  145. data/lib/chewy/type/syncer.rb +222 -0
  146. data/lib/chewy/type/witchcraft.rb +89 -34
  147. data/lib/chewy/type/wrapper.rb +48 -16
  148. data/lib/chewy/type.rb +77 -49
  149. data/lib/chewy/version.rb +1 -1
  150. data/lib/chewy.rb +95 -52
  151. data/lib/generators/chewy/install_generator.rb +3 -3
  152. data/lib/sequel/plugins/chewy_observe.rb +4 -19
  153. data/lib/tasks/chewy.rake +91 -28
  154. data/spec/chewy/config_spec.rb +130 -12
  155. data/spec/chewy/fields/base_spec.rb +194 -172
  156. data/spec/chewy/fields/root_spec.rb +123 -17
  157. data/spec/chewy/fields/time_fields_spec.rb +10 -9
  158. data/spec/chewy/index/actions_spec.rb +228 -43
  159. data/spec/chewy/index/aliases_spec.rb +2 -2
  160. data/spec/chewy/index/settings_spec.rb +100 -49
  161. data/spec/chewy/index/specification_spec.rb +169 -0
  162. data/spec/chewy/index_spec.rb +159 -63
  163. data/spec/chewy/journal_spec.rb +268 -0
  164. data/spec/chewy/minitest/helpers_spec.rb +90 -0
  165. data/spec/chewy/minitest/search_index_receiver_spec.rb +120 -0
  166. data/spec/chewy/query/criteria_spec.rb +503 -236
  167. data/spec/chewy/query/filters_spec.rb +96 -68
  168. data/spec/chewy/query/loading_spec.rb +80 -42
  169. data/spec/chewy/query/nodes/and_spec.rb +3 -7
  170. data/spec/chewy/query/nodes/bool_spec.rb +5 -13
  171. data/spec/chewy/query/nodes/equal_spec.rb +20 -20
  172. data/spec/chewy/query/nodes/exists_spec.rb +7 -7
  173. data/spec/chewy/query/nodes/has_child_spec.rb +42 -23
  174. data/spec/chewy/query/nodes/has_parent_spec.rb +42 -23
  175. data/spec/chewy/query/nodes/match_all_spec.rb +2 -2
  176. data/spec/chewy/query/nodes/missing_spec.rb +6 -5
  177. data/spec/chewy/query/nodes/not_spec.rb +5 -7
  178. data/spec/chewy/query/nodes/or_spec.rb +3 -7
  179. data/spec/chewy/query/nodes/prefix_spec.rb +6 -6
  180. data/spec/chewy/query/nodes/query_spec.rb +3 -3
  181. data/spec/chewy/query/nodes/range_spec.rb +19 -19
  182. data/spec/chewy/query/nodes/raw_spec.rb +2 -2
  183. data/spec/chewy/query/nodes/regexp_spec.rb +31 -19
  184. data/spec/chewy/query/nodes/script_spec.rb +5 -5
  185. data/spec/chewy/query/pagination/kaminari_spec.rb +3 -55
  186. data/spec/chewy/query/pagination/will_paginate_spec.rb +5 -0
  187. data/spec/chewy/query/pagination_spec.rb +25 -22
  188. data/spec/chewy/query_spec.rb +510 -505
  189. data/spec/chewy/rake_helper_spec.rb +381 -0
  190. data/spec/chewy/repository_spec.rb +8 -8
  191. data/spec/chewy/rspec/update_index_spec.rb +215 -113
  192. data/spec/chewy/runtime_spec.rb +2 -2
  193. data/spec/chewy/search/loader_spec.rb +117 -0
  194. data/spec/chewy/search/pagination/kaminari_examples.rb +71 -0
  195. data/spec/chewy/search/pagination/kaminari_spec.rb +21 -0
  196. data/spec/chewy/search/pagination/will_paginate_examples.rb +63 -0
  197. data/spec/chewy/search/pagination/will_paginate_spec.rb +23 -0
  198. data/spec/chewy/search/parameters/aggs_spec.rb +5 -0
  199. data/spec/chewy/search/parameters/bool_storage_examples.rb +53 -0
  200. data/spec/chewy/search/parameters/docvalue_fields_spec.rb +5 -0
  201. data/spec/chewy/search/parameters/explain_spec.rb +5 -0
  202. data/spec/chewy/search/parameters/filter_spec.rb +5 -0
  203. data/spec/chewy/search/parameters/hash_storage_examples.rb +59 -0
  204. data/spec/chewy/search/parameters/highlight_spec.rb +5 -0
  205. data/spec/chewy/search/parameters/indices_spec.rb +191 -0
  206. data/spec/chewy/search/parameters/integer_storage_examples.rb +32 -0
  207. data/spec/chewy/search/parameters/limit_spec.rb +5 -0
  208. data/spec/chewy/search/parameters/load_spec.rb +60 -0
  209. data/spec/chewy/search/parameters/min_score_spec.rb +32 -0
  210. data/spec/chewy/search/parameters/none_spec.rb +5 -0
  211. data/spec/chewy/search/parameters/offset_spec.rb +5 -0
  212. data/spec/chewy/search/parameters/order_spec.rb +65 -0
  213. data/spec/chewy/search/parameters/post_filter_spec.rb +5 -0
  214. data/spec/chewy/search/parameters/preference_spec.rb +5 -0
  215. data/spec/chewy/search/parameters/profile_spec.rb +5 -0
  216. data/spec/chewy/search/parameters/query_spec.rb +5 -0
  217. data/spec/chewy/search/parameters/query_storage_examples.rb +388 -0
  218. data/spec/chewy/search/parameters/request_cache_spec.rb +67 -0
  219. data/spec/chewy/search/parameters/rescore_spec.rb +62 -0
  220. data/spec/chewy/search/parameters/script_fields_spec.rb +5 -0
  221. data/spec/chewy/search/parameters/search_after_spec.rb +32 -0
  222. data/spec/chewy/search/parameters/search_type_spec.rb +5 -0
  223. data/spec/chewy/search/parameters/source_spec.rb +156 -0
  224. data/spec/chewy/search/parameters/storage_spec.rb +60 -0
  225. data/spec/chewy/search/parameters/stored_fields_spec.rb +126 -0
  226. data/spec/chewy/search/parameters/string_array_storage_examples.rb +63 -0
  227. data/spec/chewy/search/parameters/string_storage_examples.rb +32 -0
  228. data/spec/chewy/search/parameters/suggest_spec.rb +5 -0
  229. data/spec/chewy/search/parameters/terminate_after_spec.rb +5 -0
  230. data/spec/chewy/search/parameters/timeout_spec.rb +5 -0
  231. data/spec/chewy/search/parameters/track_scores_spec.rb +5 -0
  232. data/spec/chewy/search/parameters/types_spec.rb +5 -0
  233. data/spec/chewy/search/parameters/version_spec.rb +5 -0
  234. data/spec/chewy/search/parameters_spec.rb +145 -0
  235. data/spec/chewy/search/query_proxy_spec.rb +68 -0
  236. data/spec/chewy/search/request_spec.rb +685 -0
  237. data/spec/chewy/search/response_spec.rb +192 -0
  238. data/spec/chewy/search/scrolling_spec.rb +169 -0
  239. data/spec/chewy/search_spec.rb +37 -20
  240. data/spec/chewy/stash_spec.rb +95 -0
  241. data/spec/chewy/strategy/active_job_spec.rb +8 -2
  242. data/spec/chewy/strategy/atomic_spec.rb +4 -1
  243. data/spec/chewy/strategy/resque_spec.rb +8 -2
  244. data/spec/chewy/strategy/shoryuken_spec.rb +66 -0
  245. data/spec/chewy/strategy/sidekiq_spec.rb +10 -2
  246. data/spec/chewy/strategy_spec.rb +6 -6
  247. data/spec/chewy/type/actions_spec.rb +29 -10
  248. data/spec/chewy/type/adapter/active_record_spec.rb +357 -139
  249. data/spec/chewy/type/adapter/mongoid_spec.rb +220 -101
  250. data/spec/chewy/type/adapter/object_spec.rb +129 -40
  251. data/spec/chewy/type/adapter/sequel_spec.rb +304 -152
  252. data/spec/chewy/type/import/bulk_builder_spec.rb +279 -0
  253. data/spec/chewy/type/import/bulk_request_spec.rb +102 -0
  254. data/spec/chewy/type/import/journal_builder_spec.rb +95 -0
  255. data/spec/chewy/type/import/routine_spec.rb +110 -0
  256. data/spec/chewy/type/import_spec.rb +360 -244
  257. data/spec/chewy/type/mapping_spec.rb +96 -29
  258. data/spec/chewy/type/observe_spec.rb +25 -15
  259. data/spec/chewy/type/syncer_spec.rb +123 -0
  260. data/spec/chewy/type/witchcraft_spec.rb +122 -44
  261. data/spec/chewy/type/wrapper_spec.rb +63 -23
  262. data/spec/chewy/type_spec.rb +32 -10
  263. data/spec/chewy_spec.rb +82 -12
  264. data/spec/spec_helper.rb +16 -2
  265. data/spec/support/active_record.rb +6 -2
  266. data/spec/support/class_helpers.rb +4 -19
  267. data/spec/support/mongoid.rb +17 -5
  268. data/spec/support/sequel.rb +6 -1
  269. metadata +250 -57
  270. data/gemfiles/rails.3.2.activerecord.gemfile +0 -15
  271. data/gemfiles/rails.3.2.activerecord.kaminari.gemfile +0 -14
  272. data/gemfiles/rails.3.2.activerecord.will_paginate.gemfile +0 -14
  273. data/gemfiles/rails.4.0.activerecord.kaminari.gemfile +0 -14
  274. data/gemfiles/rails.4.0.activerecord.will_paginate.gemfile +0 -14
  275. data/gemfiles/rails.4.0.mongoid.4.0.0.gemfile +0 -15
  276. data/gemfiles/rails.4.0.mongoid.4.0.0.kaminari.gemfile +0 -14
  277. data/gemfiles/rails.4.0.mongoid.4.0.0.will_paginate.gemfile +0 -14
  278. data/gemfiles/rails.4.0.mongoid.5.1.0.gemfile +0 -15
  279. data/gemfiles/rails.4.0.mongoid.5.1.0.kaminari.gemfile +0 -14
  280. data/gemfiles/rails.4.0.mongoid.5.1.0.will_paginate.gemfile +0 -14
  281. data/gemfiles/rails.4.1.activerecord.kaminari.gemfile +0 -14
  282. data/gemfiles/rails.4.1.activerecord.will_paginate.gemfile +0 -14
  283. data/gemfiles/rails.4.1.mongoid.4.0.0.gemfile +0 -15
  284. data/gemfiles/rails.4.1.mongoid.4.0.0.kaminari.gemfile +0 -14
  285. data/gemfiles/rails.4.1.mongoid.4.0.0.will_paginate.gemfile +0 -14
  286. data/gemfiles/rails.4.1.mongoid.5.1.0.gemfile +0 -15
  287. data/gemfiles/rails.4.1.mongoid.5.1.0.kaminari.gemfile +0 -14
  288. data/gemfiles/rails.4.1.mongoid.5.1.0.will_paginate.gemfile +0 -14
  289. data/gemfiles/rails.4.2.activerecord.kaminari.gemfile +0 -15
  290. data/gemfiles/rails.4.2.activerecord.will_paginate.gemfile +0 -15
  291. data/gemfiles/rails.4.2.mongoid.4.0.0.gemfile +0 -15
  292. data/gemfiles/rails.4.2.mongoid.4.0.0.kaminari.gemfile +0 -14
  293. data/gemfiles/rails.4.2.mongoid.4.0.0.will_paginate.gemfile +0 -14
  294. data/gemfiles/rails.4.2.mongoid.5.1.0.gemfile +0 -15
  295. data/gemfiles/rails.4.2.mongoid.5.1.0.kaminari.gemfile +0 -14
  296. data/gemfiles/rails.4.2.mongoid.5.1.0.will_paginate.gemfile +0 -14
  297. data/gemfiles/rails.5.0.0.beta3.activerecord.gemfile +0 -16
  298. data/gemfiles/rails.5.0.0.beta3.activerecord.kaminari.gemfile +0 -16
  299. data/gemfiles/rails.5.0.0.beta3.activerecord.will_paginate.gemfile +0 -15
  300. data/gemfiles/sequel.4.31.gemfile +0 -13
  301. data/lib/chewy/query/pagination/will_paginate.rb +0 -27
  302. data/lib/chewy/query/scoping.rb +0 -20
  303. data/spec/chewy/query/pagination/will_paginage_spec.rb +0 -60
@@ -1,46 +1,45 @@
1
1
  module Chewy
2
2
  class Query
3
3
  module Compose
4
-
5
4
  protected
6
5
 
7
- def _filtered_query query, filter, options = {}
8
- query = { match_all: {} } if !query.present? && filter.present?
6
+ def _filtered_query(query, filter, options = {})
7
+ query = {match_all: {}} if !query.present? && filter.present?
9
8
 
10
9
  if filter.present?
11
10
  filtered = if query.present?
12
- { query: { filtered: {
11
+ {query: {filtered: {
13
12
  query: query,
14
13
  filter: filter
15
- } } }
14
+ }}}
16
15
  else
17
- { query: { filtered: {
16
+ {query: {filtered: {
18
17
  filter: filter
19
- } } }
18
+ }}}
20
19
  end
21
- filtered[:query][:filtered].merge!(strategy: options[:strategy].to_s) if options[:strategy].present?
20
+ filtered[:query][:filtered][:strategy] = options[:strategy].to_s if options[:strategy].present?
22
21
  filtered
23
22
  elsif query.present?
24
- { query: query }
23
+ {query: query}
25
24
  else
26
- { }
25
+ {}
27
26
  end
28
27
  end
29
28
 
30
- def _queries_join queries, logic
29
+ def _queries_join(queries, logic)
31
30
  queries = queries.compact
32
31
 
33
32
  if queries.many? || (queries.present? && logic == :must_not)
34
33
  case logic
35
34
  when :dis_max
36
- { dis_max: { queries: queries } }
35
+ {dis_max: {queries: queries}}
37
36
  when :must, :should, :must_not
38
- { bool: { logic => queries } }
37
+ {bool: {logic => queries}}
39
38
  else
40
39
  if logic.is_a?(Float)
41
- { dis_max: { queries: queries, tie_breaker: logic } }
40
+ {dis_max: {queries: queries, tie_breaker: logic}}
42
41
  else
43
- { bool: { should: queries, minimum_should_match: logic } }
42
+ {bool: {should: queries, minimum_should_match: logic}}
44
43
  end
45
44
  end
46
45
  else
@@ -48,17 +47,17 @@ module Chewy
48
47
  end
49
48
  end
50
49
 
51
- def _filters_join filters, logic
50
+ def _filters_join(filters, logic)
52
51
  filters = filters.compact
53
52
 
54
53
  if filters.many? || (filters.present? && logic == :must_not)
55
54
  case logic
56
55
  when :and, :or
57
- { logic => filters }
56
+ {logic => filters}
58
57
  when :must, :should, :must_not
59
- { bool: { logic => filters } }
58
+ {bool: {logic => filters}}
60
59
  else
61
- { bool: { should: filters, minimum_should_match: logic } }
60
+ {bool: {should: filters, minimum_should_match: logic}}
62
61
  end
63
62
  else
64
63
  filters.first
@@ -4,11 +4,11 @@ module Chewy
4
4
  class Query
5
5
  class Criteria
6
6
  include Compose
7
- ARRAY_STORAGES = [:queries, :filters, :post_filters, :sort, :fields, :types, :scores]
8
- HASH_STORAGES = [:options, :request_options, :facets, :aggregations, :suggest, :script_fields]
7
+ ARRAY_STORAGES = %i[queries filters post_filters sort fields types scores].freeze
8
+ HASH_STORAGES = %i[options search_options request_options facets aggregations suggest script_fields].freeze
9
9
  STORAGES = ARRAY_STORAGES + HASH_STORAGES
10
10
 
11
- def initialize options = {}
11
+ def initialize(options = {})
12
12
  @options = options.merge(
13
13
  query_mode: Chewy.query_mode,
14
14
  filter_mode: Chewy.filter_mode,
@@ -16,11 +16,11 @@ module Chewy
16
16
  )
17
17
  end
18
18
 
19
- def == other
19
+ def ==(other)
20
20
  other.is_a?(self.class) && storages == other.storages
21
21
  end
22
22
 
23
- { ARRAY_STORAGES => '[]', HASH_STORAGES => '{}' }.each do |storages, default|
23
+ {ARRAY_STORAGES => '[]', HASH_STORAGES => '{}'}.each do |storages, default|
24
24
  storages.each do |storage|
25
25
  class_eval <<-METHODS, __FILE__, __LINE__ + 1
26
26
  def #{storage}
@@ -32,7 +32,7 @@ module Chewy
32
32
 
33
33
  STORAGES.each do |storage|
34
34
  define_method "#{storage}?" do
35
- send(storage).present?
35
+ send(storage).any?
36
36
  end
37
37
  end
38
38
 
@@ -48,6 +48,10 @@ module Chewy
48
48
  request_options.merge!(modifier)
49
49
  end
50
50
 
51
+ def update_search_options(modifier)
52
+ search_options.merge!(modifier)
53
+ end
54
+
51
55
  def update_facets(modifier)
52
56
  facets.merge!(modifier)
53
57
  end
@@ -68,7 +72,7 @@ module Chewy
68
72
  script_fields.merge!(modifier)
69
73
  end
70
74
 
71
- [:filters, :queries, :post_filters].each do |storage|
75
+ %i[filters queries post_filters].each do |storage|
72
76
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
73
77
  def update_#{storage}(modifier)
74
78
  @#{storage} = #{storage} + Array.wrap(modifier).reject(&:blank?)
@@ -84,7 +88,7 @@ module Chewy
84
88
  @sort = sort + modifier
85
89
  end
86
90
 
87
- %w(fields types).each do |storage|
91
+ %w[fields types].each do |storage|
88
92
  define_method "update_#{storage}" do |modifier, options = {}|
89
93
  variable = "@#{storage}"
90
94
  instance_variable_set(variable, nil) if options[:purge]
@@ -93,14 +97,14 @@ module Chewy
93
97
  end
94
98
  end
95
99
 
96
- def merge! other
100
+ def merge!(other)
97
101
  STORAGES.each do |storage|
98
102
  send("update_#{storage}", other.send(storage))
99
103
  end
100
104
  self
101
105
  end
102
106
 
103
- def merge other
107
+ def merge(other)
104
108
  clone.merge!(other)
105
109
  end
106
110
 
@@ -108,19 +112,19 @@ module Chewy
108
112
  body = _filtered_query(_request_query, _request_filter, options.slice(:strategy))
109
113
 
110
114
  if options[:simple]
111
- { body: body.presence || { query: { match_all: {} } } }
115
+ {body: body.presence || {query: {match_all: {}}}}
112
116
  else
113
- body.merge!(post_filter: _request_post_filter) if post_filters?
114
- body.merge!(facets: facets) if facets?
115
- body.merge!(aggregations: aggregations) if aggregations?
116
- body.merge!(suggest: suggest) if suggest?
117
- body.merge!(sort: sort) if sort?
118
- body.merge!(_source: fields) if fields?
119
- body.merge!(script_fields: script_fields) if script_fields?
117
+ body[:post_filter] = _request_post_filter if post_filters?
118
+ body[:facets] = facets if facets?
119
+ body[:aggregations] = aggregations if aggregations?
120
+ body[:suggest] = suggest if suggest?
121
+ body[:sort] = sort if sort?
122
+ body[:_source] = fields if fields?
123
+ body[:script_fields] = script_fields if script_fields?
120
124
 
121
125
  body = _boost_query(body)
122
126
 
123
- { body: body.merge!(request_options) }
127
+ {body: body.merge!(_request_options)}.merge!(search_options)
124
128
  end
125
129
  end
126
130
 
@@ -130,9 +134,9 @@ module Chewy
130
134
  STORAGES.map { |storage| send(storage) }
131
135
  end
132
136
 
133
- def initialize_clone(other)
137
+ def initialize_clone(origin)
134
138
  STORAGES.each do |storage|
135
- value = other.send(storage)
139
+ value = origin.send(storage)
136
140
  instance_variable_set("@#{storage}", value.deep_dup)
137
141
  end
138
142
  end
@@ -142,7 +146,7 @@ module Chewy
142
146
  query = body.delete :query
143
147
  filter = body.delete :filter
144
148
  if query && filter
145
- query = { filtered: { query: query, filter: filter } }
149
+ query = {filtered: {query: query, filter: filter}}
146
150
  filter = nil
147
151
  end
148
152
  score = {}
@@ -151,7 +155,13 @@ module Chewy
151
155
  score[:score_mode] = options[:score_mode] if options[:score_mode]
152
156
  score[:query] = query if query
153
157
  score[:filter] = filter if filter
154
- body.tap { |b| b[:query] = { function_score: score } }
158
+ body.tap { |b| b[:query] = {function_score: score} }
159
+ end
160
+
161
+ def _request_options
162
+ Hash[request_options.map do |key, value|
163
+ [key, value.is_a?(Proc) ? value.call : value]
164
+ end]
155
165
  end
156
166
 
157
167
  def _request_query
@@ -170,7 +180,7 @@ module Chewy
170
180
  end
171
181
 
172
182
  def _request_types
173
- _filters_join(types.map { |type| { type: { value: type } } }, :or)
183
+ _filters_join(types.map { |type| {type: {value: type}} }, :or)
174
184
  end
175
185
 
176
186
  def _request_post_filter
@@ -24,25 +24,27 @@ module Chewy
24
24
  # You can use logic operations <tt>&</tt> and <tt>|</tt> to concat
25
25
  # expressions.
26
26
  #
27
+ # @example
27
28
  # UsersIndex.filter{ (article.title =~ /Honey/) & (age < 42) & !rate }
28
29
  #
29
30
  #
30
31
  class Filters
31
- def initialize outer = nil, &block
32
+ def initialize(outer = nil, &block)
32
33
  @block = block
33
- @outer = outer || eval('self', block.binding)
34
+ @outer = outer || eval('self', block.binding, __FILE__, __LINE__)
34
35
  end
35
36
 
36
37
  # Outer scope call
37
38
  # Block evaluates in the external context
38
39
  #
40
+ # @example
39
41
  # def name
40
42
  # 'Friend'
41
43
  # end
42
44
  #
43
45
  # UsersIndex.filter{ name == o{ name } } # => {filter: {term: {name: 'Friend'}}}
44
46
  #
45
- def o &block
47
+ def o(&block)
46
48
  @outer.instance_exec(&block)
47
49
  end
48
50
 
@@ -50,19 +52,21 @@ module Chewy
50
52
  # Used if method_missing is not working by some reason.
51
53
  # Additional expression options might be passed as second argument hash.
52
54
  #
55
+ # @example
53
56
  # UsersIndex.filter{ f(:name) == 'Name' } == UsersIndex.filter{ name == 'Name' } # => true
54
57
  # UsersIndex.filter{ f(:name, execution: :bool) == ['Name1', 'Name2'] } ==
55
58
  # UsersIndex.filter{ name(execution: :bool) == ['Name1', 'Name2'] } # => true
56
59
  #
57
60
  # Supports block for getting field name from the outer scope
58
61
  #
62
+ # @example
59
63
  # def field
60
64
  # :name
61
65
  # end
62
66
  #
63
67
  # UsersIndex.filter{ f{ field } == 'Name' } == UsersIndex.filter{ name == 'Name' } # => true
64
68
  #
65
- def f name = nil, *args, &block
69
+ def f(name = nil, *args, &block)
66
70
  name = block ? o(&block) : name
67
71
  Nodes::Field.new name, *args
68
72
  end
@@ -70,11 +74,13 @@ module Chewy
70
74
  # Returns script filter
71
75
  # Just script filter. Supports additional params.
72
76
  #
77
+ # @example
73
78
  # UsersIndex.filter{ s('doc["num1"].value > 1') }
74
79
  # UsersIndex.filter{ s('doc["num1"].value > param1', param1: 42) }
75
80
  #
76
81
  # Supports block for getting script from the outer scope
77
82
  #
83
+ # @example
78
84
  # def script
79
85
  # 'doc["num1"].value > param1 || 1'
80
86
  # end
@@ -82,7 +88,7 @@ module Chewy
82
88
  # UsersIndex.filter{ s{ script } } == UsersIndex.filter{ s('doc["num1"].value > 1') } # => true
83
89
  # UsersIndex.filter{ s(param1: 42) { script } } == UsersIndex.filter{ s('doc["num1"].value > 1', param1: 42) } # => true
84
90
  #
85
- def s *args, &block
91
+ def s(*args, &block)
86
92
  params = args.extract_options!
87
93
  script = block ? o(&block) : args.first
88
94
  Nodes::Script.new script, params
@@ -90,28 +96,32 @@ module Chewy
90
96
 
91
97
  # Returns query filter
92
98
  #
99
+ # @example
93
100
  # UsersIndex.filter{ q(query_string: {query: 'name: hello'}) }
94
101
  #
95
102
  # Supports block for getting query from the outer scope
96
103
  #
104
+ # @example
97
105
  # def query
98
106
  # {query_string: {query: 'name: hello'}}
99
107
  # end
100
108
  #
101
109
  # UsersIndex.filter{ q{ query } } == UsersIndex.filter{ q(query_string: {query: 'name: hello'}) } # => true
102
110
  #
103
- def q query = nil, &block
111
+ def q(query = nil, &block)
104
112
  Nodes::Query.new block ? o(&block) : query
105
113
  end
106
114
 
107
115
  # Returns raw expression
108
116
  # Same as filter with arguments instead of block, but can participate in expressions
109
117
  #
118
+ # @example
110
119
  # UsersIndex.filter{ r(term: {name: 'Name'}) }
111
120
  # UsersIndex.filter{ r(term: {name: 'Name'}) & (age < 42) }
112
121
  #
113
122
  # Supports block for getting raw filter from the outer scope
114
123
  #
124
+ # @example
115
125
  # def filter
116
126
  # {term: {name: 'Name'}}
117
127
  # end
@@ -119,19 +129,20 @@ module Chewy
119
129
  # UsersIndex.filter{ r{ filter } } == UsersIndex.filter{ r(term: {name: 'Name'}) } # => true
120
130
  # UsersIndex.filter{ r{ filter } } == UsersIndex.filter(term: {name: 'Name'}) # => true
121
131
  #
122
- def r raw = nil, &block
132
+ def r(raw = nil, &block)
123
133
  Nodes::Raw.new block ? o(&block) : raw
124
134
  end
125
135
 
126
136
  # Bool filter chainable methods
127
137
  # Used to create bool query. Nodes are passed as arguments.
128
138
  #
139
+ # @example
129
140
  # UsersIndex.filter{ must(age < 42, name == 'Name') }
130
141
  # UsersIndex.filter{ should(age < 42, name == 'Name') }
131
142
  # UsersIndex.filter{ must(age < 42).should(name == 'Name1', name == 'Name2') }
132
143
  # UsersIndex.filter{ should_not(age >= 42).must(name == 'Name1') }
133
144
  #
134
- %w(must must_not should).each do |method|
145
+ %w[must must_not should].each do |method|
135
146
  define_method method do |*exprs|
136
147
  Nodes::Bool.new.send(method, *exprs)
137
148
  end
@@ -141,12 +152,14 @@ module Chewy
141
152
  # Chainable interface acts the same as main query interface. You can pass plain
142
153
  # filters or plain queries or filter with DSL block.
143
154
  #
155
+ # @example
144
156
  # UsersIndex.filter{ has_child('user').filter(term: {role: 'Admin'}) }
145
157
  # UsersIndex.filter{ has_child('user').filter{ role == 'Admin' } }
146
158
  # UsersIndex.filter{ has_child('user').query(match: {name: 'borogoves'}) }
147
159
  #
148
160
  # Filters and queries might be combined and filter_mode and query_mode are configurable:
149
161
  #
162
+ # @example
150
163
  # UsersIndex.filter do
151
164
  # has_child('user')
152
165
  # .filter{ name: 'Peter' }
@@ -155,7 +168,7 @@ module Chewy
155
168
  # .filter_mode(:or)
156
169
  # end
157
170
  #
158
- def has_child type
171
+ def has_child(type) # rubocop:disable Naming/PredicateName
159
172
  Nodes::HasChild.new(type, @outer)
160
173
  end
161
174
 
@@ -163,12 +176,14 @@ module Chewy
163
176
  # Chainable interface acts the same as main query interface. You can pass plain
164
177
  # filters or plain queries or filter with DSL block.
165
178
  #
179
+ # @example
166
180
  # UsersIndex.filter{ has_parent('user').filter(term: {role: 'Admin'}) }
167
181
  # UsersIndex.filter{ has_parent('user').filter{ role == 'Admin' } }
168
182
  # UsersIndex.filter{ has_parent('user').query(match: {name: 'borogoves'}) }
169
183
  #
170
184
  # Filters and queries might be combined and filter_mode and query_mode are configurable:
171
185
  #
186
+ # @example
172
187
  # UsersIndex.filter do
173
188
  # has_parent('user')
174
189
  # .filter{ name: 'Peter' }
@@ -177,7 +192,7 @@ module Chewy
177
192
  # .filter_mode(:or)
178
193
  # end
179
194
  #
180
- def has_parent type
195
+ def has_parent(type) # rubocop:disable Naming/PredicateName
181
196
  Nodes::HasParent.new(type, @outer)
182
197
  end
183
198
 
@@ -190,6 +205,7 @@ module Chewy
190
205
  # Creates field or exists node
191
206
  # Additional options for further expression might be passed as hash
192
207
  #
208
+ # @example
193
209
  # UsersIndex.filter{ name == 'Name' } == UsersIndex.filter(term: {name: 'Name'}) # => true
194
210
  # UsersIndex.filter{ name? } == UsersIndex.filter(exists: {term: 'name'}) # => true
195
211
  # UsersIndex.filter{ name(execution: :bool) == ['Name1', 'Name2'] } ==
@@ -197,10 +213,11 @@ module Chewy
197
213
  #
198
214
  # Also field names might be chained to use dot-notation for ES field names
199
215
  #
216
+ # @example
200
217
  # UsersIndex.filter{ article.title =~ 'Hello' }
201
218
  # UsersIndex.filter{ article.tags? }
202
219
  #
203
- def method_missing method, *args, &block
220
+ def method_missing(method, *args) # rubocop:disable Style/MethodMissing
204
221
  method = method.to_s
205
222
  if method =~ /\?\Z/
206
223
  Nodes::Exists.new method.gsub(/\?\Z/, '')
@@ -94,10 +94,9 @@ module Chewy
94
94
  loaded_objects = Hash[_results.group_by(&:class).map do |type, objects|
95
95
  next if except.include?(type.type_name)
96
96
  next if only.present? && !only.include?(type.type_name)
97
-
98
- loaded = type.adapter.load(objects, options.merge(_type: type))
99
- [type, loaded.index_by.with_index do |loaded, i|
100
- objects[i]._object = loaded
97
+ loaded = type.adapter.load(objects.map(&:id), options.merge(_type: type)) || objects
98
+ [type, loaded.index_by.with_index do |loaded_object, i|
99
+ objects[i]._object = loaded_object
101
100
  objects[i]
102
101
  end]
103
102
  end.compact]
@@ -2,7 +2,7 @@ module Chewy
2
2
  class Query
3
3
  module Nodes
4
4
  class And < Expr
5
- def initialize *nodes
5
+ def initialize(*nodes)
6
6
  @options = nodes.extract_options!
7
7
  @nodes = nodes.flatten.map { |node| node.is_a?(self.class) ? node.__nodes__ : node }.flatten
8
8
  end
@@ -6,7 +6,7 @@ module Chewy
6
6
  raise NotImplementedError
7
7
  end
8
8
 
9
- def eql? other
9
+ def eql?(other)
10
10
  other.is_a?(self.class) && instance_variables.all? do |ivar|
11
11
  instance_variable_get(ivar).eql? other.instance_variable_get(ivar)
12
12
  end
@@ -2,16 +2,18 @@ module Chewy
2
2
  class Query
3
3
  module Nodes
4
4
  class Bool < Expr
5
- METHODS = %w(must must_not should)
5
+ METHODS = %w[must must_not should].freeze
6
6
 
7
- def initialize options = {}
7
+ def initialize(options = {})
8
8
  @options = options
9
- @must, @must_not, @should = [], [], []
9
+ @must = []
10
+ @must_not = []
11
+ @should = []
10
12
  end
11
13
 
12
14
  METHODS.each do |method|
13
15
  define_method method do |*exprs|
14
- instance_variable_get("@#{method}").push(*exprs)
16
+ instance_variable_get("@#{method}").concat(exprs)
15
17
  self
16
18
  end
17
19
  end
@@ -10,10 +10,10 @@ module Chewy
10
10
  :b => :bool,
11
11
  :bool => :bool,
12
12
  :f => :fielddata,
13
- :fielddata => :fielddata,
14
- }
13
+ :fielddata => :fielddata
14
+ }.freeze
15
15
 
16
- def initialize name, value, *args
16
+ def initialize(name, value, *args)
17
17
  @name = name.to_s
18
18
  @value = value
19
19
  @options = args.extract_options!
@@ -25,7 +25,7 @@ module Chewy
25
25
  filter = (@value.is_a?(Array) ? :terms : :term)
26
26
  body = {@name => @value}
27
27
  body.merge!(@options.slice(:execution)) if filter == :terms
28
- body.merge!(_cache: !!@options[:cache]) if @options.key?(:cache)
28
+ body[:_cache] = !!@options[:cache] if @options.key?(:cache)
29
29
  {filter => body}
30
30
  end
31
31
  end
@@ -2,7 +2,7 @@ module Chewy
2
2
  class Query
3
3
  module Nodes
4
4
  class Exists < Expr
5
- def initialize name, options = {}
5
+ def initialize(name, options = {})
6
6
  @name = name.to_s
7
7
  @options = options
8
8
  end
@@ -2,11 +2,11 @@ module Chewy
2
2
  class Query
3
3
  module Nodes
4
4
  class Expr < Base
5
- def & other
5
+ def &(other)
6
6
  Nodes::And.new self, other
7
7
  end
8
8
 
9
- def | other
9
+ def |(other)
10
10
  Nodes::Or.new self, other
11
11
  end
12
12
 
@@ -2,7 +2,7 @@ module Chewy
2
2
  class Query
3
3
  module Nodes
4
4
  class Field < Base
5
- def initialize name, *args
5
+ def initialize(name, *args)
6
6
  @name = name.to_s
7
7
  @args = args
8
8
  end
@@ -16,70 +16,74 @@ module Chewy
16
16
  self
17
17
  end
18
18
 
19
- def > value
20
- Nodes::Range.new @name, *__options_merge__(gt: value)
19
+ def >(other)
20
+ Nodes::Range.new @name, *__options_merge__(gt: other)
21
21
  end
22
22
 
23
- def < value
24
- Nodes::Range.new @name, *__options_merge__(lt: value)
23
+ def <(other)
24
+ Nodes::Range.new @name, *__options_merge__(lt: other)
25
25
  end
26
26
 
27
- def >= value
28
- Nodes::Range.new @name, *__options_merge__(gt: value, left_closed: true)
27
+ def >=(other)
28
+ Nodes::Range.new @name, *__options_merge__(gt: other, left_closed: true)
29
29
  end
30
30
 
31
- def <= value
32
- Nodes::Range.new @name, *__options_merge__(lt: value, right_closed: true)
31
+ def <=(other)
32
+ Nodes::Range.new @name, *__options_merge__(lt: other, right_closed: true)
33
33
  end
34
34
 
35
- def == value
36
- case value
35
+ def ==(other)
36
+ case other
37
37
  when nil
38
- Nodes::Missing.new @name, existence: false, null_value: true
38
+ nil?
39
39
  when ::Regexp
40
- Nodes::Regexp.new @name, value, *@args
40
+ Nodes::Regexp.new @name, other, *@args
41
41
  when ::Range
42
- Nodes::Range.new @name, *__options_merge__(gt: value.first, lt: value.last)
42
+ Nodes::Range.new @name, *__options_merge__(gt: other.first, lt: other.last)
43
43
  else
44
- if value.is_a?(Array) && value.first.is_a?(::Range)
44
+ if other.is_a?(Array) && other.first.is_a?(::Range)
45
45
  Nodes::Range.new @name, *__options_merge__(
46
- gt: value.first.first, lt: value.first.last,
46
+ gt: other.first.first, lt: other.first.last,
47
47
  left_closed: true, right_closed: true
48
48
  )
49
49
  else
50
- Nodes::Equal.new @name, value, *@args
50
+ Nodes::Equal.new @name, other, *@args
51
51
  end
52
52
  end
53
53
  end
54
54
 
55
- def != value
56
- case value
55
+ def !=(other)
56
+ case other
57
57
  when nil
58
58
  Nodes::Exists.new @name
59
59
  else
60
- Nodes::Not.new self == value
60
+ Nodes::Not.new self == other
61
61
  end
62
62
  end
63
63
 
64
- def =~ value
65
- case value
64
+ def =~(other)
65
+ case other
66
66
  when ::Regexp
67
- Nodes::Regexp.new @name, value, *@args
67
+ Nodes::Regexp.new @name, other, *@args
68
68
  else
69
- Nodes::Prefix.new @name, value, @args.extract_options!
69
+ Nodes::Prefix.new @name, other, @args.extract_options!
70
70
  end
71
71
  end
72
72
 
73
- def !~ value
74
- Not.new(self =~ value)
73
+ def !~(other)
74
+ Not.new(self =~ other)
75
75
  end
76
76
 
77
- def method_missing method, *args, &block
77
+ def nil?
78
+ Nodes::Missing.new @name, existence: false, null_value: true
79
+ end
80
+
81
+ def method_missing(method, *args) # rubocop:disable Style/MethodMissing
78
82
  method = method.to_s
79
83
  if method =~ /\?\Z/
80
- Nodes::Exists.new [@name, method.gsub(/\?\Z/, '')].join(?.)
84
+ Nodes::Exists.new [@name, method.gsub(/\?\Z/, '')].join('.')
81
85
  else
82
- self.class.new [@name, method].join(?.), *args
86
+ self.class.new [@name, method].join('.'), *args
83
87
  end
84
88
  end
85
89
 
@@ -89,13 +93,13 @@ module Chewy
89
93
 
90
94
  private
91
95
 
92
- def __options_merge__! additional = {}
96
+ def __options_merge__!(additional = {})
93
97
  options = @args.extract_options!
94
98
  options = options.merge(additional)
95
99
  @args.push(options)
96
100
  end
97
101
 
98
- def __options_merge__ additional = {}
102
+ def __options_merge__(additional = {})
99
103
  options = @args.extract_options!
100
104
  options = options.merge(additional)
101
105
  @args + [options]