chewy 0.8.4 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.rubocop.yml +56 -0
- data/.rubocop_todo.yml +44 -0
- data/.travis.yml +36 -67
- data/.yardopts +5 -0
- data/Appraisals +63 -58
- data/CHANGELOG.md +168 -11
- data/Gemfile +16 -9
- data/Guardfile +5 -5
- data/LEGACY_DSL.md +497 -0
- data/README.md +403 -470
- data/Rakefile +11 -1
- data/chewy.gemspec +12 -15
- data/gemfiles/rails.4.0.activerecord.gemfile +9 -9
- data/gemfiles/rails.4.1.activerecord.gemfile +9 -9
- data/gemfiles/rails.4.2.activerecord.gemfile +8 -8
- data/gemfiles/rails.4.2.mongoid.5.2.gemfile +16 -0
- data/gemfiles/rails.5.0.activerecord.gemfile +16 -0
- data/gemfiles/rails.5.0.mongoid.6.1.gemfile +16 -0
- data/gemfiles/rails.5.1.activerecord.gemfile +16 -0
- data/gemfiles/rails.5.1.mongoid.6.3.gemfile +16 -0
- data/gemfiles/rails.5.2.activerecord.gemfile +16 -0
- data/gemfiles/sequel.4.45.gemfile +11 -0
- data/lib/chewy/backports/deep_dup.rb +1 -1
- data/lib/chewy/backports/duplicable.rb +1 -0
- data/lib/chewy/config.rb +53 -21
- data/lib/chewy/errors.rb +6 -6
- data/lib/chewy/fields/base.rb +59 -29
- data/lib/chewy/fields/root.rb +49 -14
- data/lib/chewy/index/actions.rb +95 -36
- data/lib/chewy/index/aliases.rb +2 -1
- data/lib/chewy/index/settings.rb +10 -5
- data/lib/chewy/index/specification.rb +60 -0
- data/lib/chewy/index.rb +239 -138
- data/lib/chewy/journal.rb +55 -0
- data/lib/chewy/log_subscriber.rb +8 -8
- data/lib/chewy/minitest/helpers.rb +77 -0
- data/lib/chewy/minitest/search_index_receiver.rb +80 -0
- data/lib/chewy/minitest.rb +1 -0
- data/lib/chewy/query/compose.rb +18 -19
- data/lib/chewy/query/criteria.rb +34 -24
- data/lib/chewy/query/filters.rb +28 -11
- data/lib/chewy/query/loading.rb +3 -4
- data/lib/chewy/query/nodes/and.rb +1 -1
- data/lib/chewy/query/nodes/base.rb +1 -1
- data/lib/chewy/query/nodes/bool.rb +6 -4
- data/lib/chewy/query/nodes/equal.rb +4 -4
- data/lib/chewy/query/nodes/exists.rb +1 -1
- data/lib/chewy/query/nodes/expr.rb +2 -2
- data/lib/chewy/query/nodes/field.rb +35 -31
- data/lib/chewy/query/nodes/has_child.rb +1 -0
- data/lib/chewy/query/nodes/has_parent.rb +1 -0
- data/lib/chewy/query/nodes/has_relation.rb +10 -12
- data/lib/chewy/query/nodes/missing.rb +1 -1
- data/lib/chewy/query/nodes/not.rb +1 -1
- data/lib/chewy/query/nodes/or.rb +1 -1
- data/lib/chewy/query/nodes/prefix.rb +3 -2
- data/lib/chewy/query/nodes/query.rb +1 -1
- data/lib/chewy/query/nodes/range.rb +9 -9
- data/lib/chewy/query/nodes/raw.rb +1 -1
- data/lib/chewy/query/nodes/regexp.rb +13 -9
- data/lib/chewy/query/nodes/script.rb +4 -4
- data/lib/chewy/query/pagination.rb +10 -1
- data/lib/chewy/query.rb +286 -170
- data/lib/chewy/railtie.rb +7 -6
- data/lib/chewy/rake_helper.rb +275 -37
- data/lib/chewy/repository.rb +2 -2
- data/lib/chewy/rspec/update_index.rb +70 -65
- data/lib/chewy/rspec.rb +1 -1
- data/lib/chewy/runtime/version.rb +4 -4
- data/lib/chewy/search/loader.rb +83 -0
- data/lib/chewy/{query → search}/pagination/kaminari.rb +13 -5
- data/lib/chewy/search/pagination/will_paginate.rb +43 -0
- data/lib/chewy/search/parameters/aggs.rb +16 -0
- data/lib/chewy/search/parameters/allow_partial_search_results.rb +27 -0
- data/lib/chewy/search/parameters/concerns/bool_storage.rb +24 -0
- data/lib/chewy/search/parameters/concerns/hash_storage.rb +23 -0
- data/lib/chewy/search/parameters/concerns/integer_storage.rb +14 -0
- data/lib/chewy/search/parameters/concerns/query_storage.rb +238 -0
- data/lib/chewy/search/parameters/concerns/string_array_storage.rb +23 -0
- data/lib/chewy/search/parameters/concerns/string_storage.rb +14 -0
- data/lib/chewy/search/parameters/docvalue_fields.rb +12 -0
- data/lib/chewy/search/parameters/explain.rb +16 -0
- data/lib/chewy/search/parameters/filter.rb +47 -0
- data/lib/chewy/search/parameters/highlight.rb +16 -0
- data/lib/chewy/search/parameters/indices.rb +123 -0
- data/lib/chewy/search/parameters/indices_boost.rb +52 -0
- data/lib/chewy/search/parameters/limit.rb +17 -0
- data/lib/chewy/search/parameters/load.rb +32 -0
- data/lib/chewy/search/parameters/min_score.rb +16 -0
- data/lib/chewy/search/parameters/none.rb +27 -0
- data/lib/chewy/search/parameters/offset.rb +17 -0
- data/lib/chewy/search/parameters/order.rb +64 -0
- data/lib/chewy/search/parameters/post_filter.rb +19 -0
- data/lib/chewy/search/parameters/preference.rb +16 -0
- data/lib/chewy/search/parameters/profile.rb +16 -0
- data/lib/chewy/search/parameters/query.rb +19 -0
- data/lib/chewy/search/parameters/request_cache.rb +27 -0
- data/lib/chewy/search/parameters/rescore.rb +29 -0
- data/lib/chewy/search/parameters/script_fields.rb +16 -0
- data/lib/chewy/search/parameters/search_after.rb +20 -0
- data/lib/chewy/search/parameters/search_type.rb +16 -0
- data/lib/chewy/search/parameters/source.rb +73 -0
- data/lib/chewy/search/parameters/storage.rb +95 -0
- data/lib/chewy/search/parameters/stored_fields.rb +63 -0
- data/lib/chewy/search/parameters/suggest.rb +16 -0
- data/lib/chewy/search/parameters/terminate_after.rb +16 -0
- data/lib/chewy/search/parameters/timeout.rb +16 -0
- data/lib/chewy/search/parameters/track_scores.rb +16 -0
- data/lib/chewy/search/parameters/types.rb +20 -0
- data/lib/chewy/search/parameters/version.rb +16 -0
- data/lib/chewy/search/parameters.rb +167 -0
- data/lib/chewy/search/query_proxy.rb +257 -0
- data/lib/chewy/search/request.rb +1045 -0
- data/lib/chewy/search/response.rb +119 -0
- data/lib/chewy/search/scoping.rb +50 -0
- data/lib/chewy/search/scrolling.rb +134 -0
- data/lib/chewy/search.rb +81 -26
- data/lib/chewy/stash.rb +79 -0
- data/lib/chewy/strategy/active_job.rb +1 -0
- data/lib/chewy/strategy/atomic.rb +2 -4
- data/lib/chewy/strategy/base.rb +4 -4
- data/lib/chewy/strategy/bypass.rb +1 -2
- data/lib/chewy/strategy/resque.rb +1 -0
- data/lib/chewy/strategy/shoryuken.rb +40 -0
- data/lib/chewy/strategy/sidekiq.rb +13 -1
- data/lib/chewy/strategy/urgent.rb +1 -1
- data/lib/chewy/strategy.rb +19 -10
- data/lib/chewy/type/actions.rb +26 -2
- data/lib/chewy/type/adapter/active_record.rb +50 -24
- data/lib/chewy/type/adapter/base.rb +29 -9
- data/lib/chewy/type/adapter/mongoid.rb +19 -10
- data/lib/chewy/type/adapter/object.rb +195 -31
- data/lib/chewy/type/adapter/orm.rb +69 -33
- data/lib/chewy/type/adapter/sequel.rb +37 -19
- data/lib/chewy/type/crutch.rb +5 -4
- data/lib/chewy/type/import/bulk_builder.rb +122 -0
- data/lib/chewy/type/import/bulk_request.rb +78 -0
- data/lib/chewy/type/import/journal_builder.rb +45 -0
- data/lib/chewy/type/import/routine.rb +138 -0
- data/lib/chewy/type/import.rb +150 -176
- data/lib/chewy/type/mapping.rb +58 -42
- data/lib/chewy/type/observe.rb +21 -15
- data/lib/chewy/type/syncer.rb +222 -0
- data/lib/chewy/type/witchcraft.rb +89 -34
- data/lib/chewy/type/wrapper.rb +48 -16
- data/lib/chewy/type.rb +77 -49
- data/lib/chewy/version.rb +1 -1
- data/lib/chewy.rb +95 -52
- data/lib/generators/chewy/install_generator.rb +3 -3
- data/lib/sequel/plugins/chewy_observe.rb +4 -19
- data/lib/tasks/chewy.rake +91 -28
- data/spec/chewy/config_spec.rb +130 -12
- data/spec/chewy/fields/base_spec.rb +194 -172
- data/spec/chewy/fields/root_spec.rb +123 -17
- data/spec/chewy/fields/time_fields_spec.rb +10 -9
- data/spec/chewy/index/actions_spec.rb +228 -43
- data/spec/chewy/index/aliases_spec.rb +2 -2
- data/spec/chewy/index/settings_spec.rb +100 -49
- data/spec/chewy/index/specification_spec.rb +169 -0
- data/spec/chewy/index_spec.rb +159 -63
- data/spec/chewy/journal_spec.rb +268 -0
- data/spec/chewy/minitest/helpers_spec.rb +90 -0
- data/spec/chewy/minitest/search_index_receiver_spec.rb +120 -0
- data/spec/chewy/query/criteria_spec.rb +503 -236
- data/spec/chewy/query/filters_spec.rb +96 -68
- data/spec/chewy/query/loading_spec.rb +80 -42
- data/spec/chewy/query/nodes/and_spec.rb +3 -7
- data/spec/chewy/query/nodes/bool_spec.rb +5 -13
- data/spec/chewy/query/nodes/equal_spec.rb +20 -20
- data/spec/chewy/query/nodes/exists_spec.rb +7 -7
- data/spec/chewy/query/nodes/has_child_spec.rb +42 -23
- data/spec/chewy/query/nodes/has_parent_spec.rb +42 -23
- data/spec/chewy/query/nodes/match_all_spec.rb +2 -2
- data/spec/chewy/query/nodes/missing_spec.rb +6 -5
- data/spec/chewy/query/nodes/not_spec.rb +5 -7
- data/spec/chewy/query/nodes/or_spec.rb +3 -7
- data/spec/chewy/query/nodes/prefix_spec.rb +6 -6
- data/spec/chewy/query/nodes/query_spec.rb +3 -3
- data/spec/chewy/query/nodes/range_spec.rb +19 -19
- data/spec/chewy/query/nodes/raw_spec.rb +2 -2
- data/spec/chewy/query/nodes/regexp_spec.rb +31 -19
- data/spec/chewy/query/nodes/script_spec.rb +5 -5
- data/spec/chewy/query/pagination/kaminari_spec.rb +3 -55
- data/spec/chewy/query/pagination/will_paginate_spec.rb +5 -0
- data/spec/chewy/query/pagination_spec.rb +25 -22
- data/spec/chewy/query_spec.rb +510 -505
- data/spec/chewy/rake_helper_spec.rb +381 -0
- data/spec/chewy/repository_spec.rb +8 -8
- data/spec/chewy/rspec/update_index_spec.rb +215 -113
- data/spec/chewy/runtime_spec.rb +2 -2
- data/spec/chewy/search/loader_spec.rb +117 -0
- data/spec/chewy/search/pagination/kaminari_examples.rb +71 -0
- data/spec/chewy/search/pagination/kaminari_spec.rb +21 -0
- data/spec/chewy/search/pagination/will_paginate_examples.rb +63 -0
- data/spec/chewy/search/pagination/will_paginate_spec.rb +23 -0
- data/spec/chewy/search/parameters/aggs_spec.rb +5 -0
- data/spec/chewy/search/parameters/bool_storage_examples.rb +53 -0
- data/spec/chewy/search/parameters/docvalue_fields_spec.rb +5 -0
- data/spec/chewy/search/parameters/explain_spec.rb +5 -0
- data/spec/chewy/search/parameters/filter_spec.rb +5 -0
- data/spec/chewy/search/parameters/hash_storage_examples.rb +59 -0
- data/spec/chewy/search/parameters/highlight_spec.rb +5 -0
- data/spec/chewy/search/parameters/indices_spec.rb +191 -0
- data/spec/chewy/search/parameters/integer_storage_examples.rb +32 -0
- data/spec/chewy/search/parameters/limit_spec.rb +5 -0
- data/spec/chewy/search/parameters/load_spec.rb +60 -0
- data/spec/chewy/search/parameters/min_score_spec.rb +32 -0
- data/spec/chewy/search/parameters/none_spec.rb +5 -0
- data/spec/chewy/search/parameters/offset_spec.rb +5 -0
- data/spec/chewy/search/parameters/order_spec.rb +65 -0
- data/spec/chewy/search/parameters/post_filter_spec.rb +5 -0
- data/spec/chewy/search/parameters/preference_spec.rb +5 -0
- data/spec/chewy/search/parameters/profile_spec.rb +5 -0
- data/spec/chewy/search/parameters/query_spec.rb +5 -0
- data/spec/chewy/search/parameters/query_storage_examples.rb +388 -0
- data/spec/chewy/search/parameters/request_cache_spec.rb +67 -0
- data/spec/chewy/search/parameters/rescore_spec.rb +62 -0
- data/spec/chewy/search/parameters/script_fields_spec.rb +5 -0
- data/spec/chewy/search/parameters/search_after_spec.rb +32 -0
- data/spec/chewy/search/parameters/search_type_spec.rb +5 -0
- data/spec/chewy/search/parameters/source_spec.rb +156 -0
- data/spec/chewy/search/parameters/storage_spec.rb +60 -0
- data/spec/chewy/search/parameters/stored_fields_spec.rb +126 -0
- data/spec/chewy/search/parameters/string_array_storage_examples.rb +63 -0
- data/spec/chewy/search/parameters/string_storage_examples.rb +32 -0
- data/spec/chewy/search/parameters/suggest_spec.rb +5 -0
- data/spec/chewy/search/parameters/terminate_after_spec.rb +5 -0
- data/spec/chewy/search/parameters/timeout_spec.rb +5 -0
- data/spec/chewy/search/parameters/track_scores_spec.rb +5 -0
- data/spec/chewy/search/parameters/types_spec.rb +5 -0
- data/spec/chewy/search/parameters/version_spec.rb +5 -0
- data/spec/chewy/search/parameters_spec.rb +145 -0
- data/spec/chewy/search/query_proxy_spec.rb +68 -0
- data/spec/chewy/search/request_spec.rb +685 -0
- data/spec/chewy/search/response_spec.rb +192 -0
- data/spec/chewy/search/scrolling_spec.rb +169 -0
- data/spec/chewy/search_spec.rb +37 -20
- data/spec/chewy/stash_spec.rb +95 -0
- data/spec/chewy/strategy/active_job_spec.rb +8 -2
- data/spec/chewy/strategy/atomic_spec.rb +4 -1
- data/spec/chewy/strategy/resque_spec.rb +8 -2
- data/spec/chewy/strategy/shoryuken_spec.rb +66 -0
- data/spec/chewy/strategy/sidekiq_spec.rb +10 -2
- data/spec/chewy/strategy_spec.rb +6 -6
- data/spec/chewy/type/actions_spec.rb +29 -10
- data/spec/chewy/type/adapter/active_record_spec.rb +357 -139
- data/spec/chewy/type/adapter/mongoid_spec.rb +220 -101
- data/spec/chewy/type/adapter/object_spec.rb +129 -40
- data/spec/chewy/type/adapter/sequel_spec.rb +304 -152
- data/spec/chewy/type/import/bulk_builder_spec.rb +279 -0
- data/spec/chewy/type/import/bulk_request_spec.rb +102 -0
- data/spec/chewy/type/import/journal_builder_spec.rb +95 -0
- data/spec/chewy/type/import/routine_spec.rb +110 -0
- data/spec/chewy/type/import_spec.rb +360 -244
- data/spec/chewy/type/mapping_spec.rb +96 -29
- data/spec/chewy/type/observe_spec.rb +25 -15
- data/spec/chewy/type/syncer_spec.rb +123 -0
- data/spec/chewy/type/witchcraft_spec.rb +122 -44
- data/spec/chewy/type/wrapper_spec.rb +63 -23
- data/spec/chewy/type_spec.rb +32 -10
- data/spec/chewy_spec.rb +82 -12
- data/spec/spec_helper.rb +16 -2
- data/spec/support/active_record.rb +6 -2
- data/spec/support/class_helpers.rb +4 -19
- data/spec/support/mongoid.rb +17 -5
- data/spec/support/sequel.rb +6 -1
- metadata +250 -57
- data/gemfiles/rails.3.2.activerecord.gemfile +0 -15
- data/gemfiles/rails.3.2.activerecord.kaminari.gemfile +0 -14
- data/gemfiles/rails.3.2.activerecord.will_paginate.gemfile +0 -14
- data/gemfiles/rails.4.0.activerecord.kaminari.gemfile +0 -14
- data/gemfiles/rails.4.0.activerecord.will_paginate.gemfile +0 -14
- data/gemfiles/rails.4.0.mongoid.4.0.0.gemfile +0 -15
- data/gemfiles/rails.4.0.mongoid.4.0.0.kaminari.gemfile +0 -14
- data/gemfiles/rails.4.0.mongoid.4.0.0.will_paginate.gemfile +0 -14
- data/gemfiles/rails.4.0.mongoid.5.1.0.gemfile +0 -15
- data/gemfiles/rails.4.0.mongoid.5.1.0.kaminari.gemfile +0 -14
- data/gemfiles/rails.4.0.mongoid.5.1.0.will_paginate.gemfile +0 -14
- data/gemfiles/rails.4.1.activerecord.kaminari.gemfile +0 -14
- data/gemfiles/rails.4.1.activerecord.will_paginate.gemfile +0 -14
- data/gemfiles/rails.4.1.mongoid.4.0.0.gemfile +0 -15
- data/gemfiles/rails.4.1.mongoid.4.0.0.kaminari.gemfile +0 -14
- data/gemfiles/rails.4.1.mongoid.4.0.0.will_paginate.gemfile +0 -14
- data/gemfiles/rails.4.1.mongoid.5.1.0.gemfile +0 -15
- data/gemfiles/rails.4.1.mongoid.5.1.0.kaminari.gemfile +0 -14
- data/gemfiles/rails.4.1.mongoid.5.1.0.will_paginate.gemfile +0 -14
- data/gemfiles/rails.4.2.activerecord.kaminari.gemfile +0 -15
- data/gemfiles/rails.4.2.activerecord.will_paginate.gemfile +0 -15
- data/gemfiles/rails.4.2.mongoid.4.0.0.gemfile +0 -15
- data/gemfiles/rails.4.2.mongoid.4.0.0.kaminari.gemfile +0 -14
- data/gemfiles/rails.4.2.mongoid.4.0.0.will_paginate.gemfile +0 -14
- data/gemfiles/rails.4.2.mongoid.5.1.0.gemfile +0 -15
- data/gemfiles/rails.4.2.mongoid.5.1.0.kaminari.gemfile +0 -14
- data/gemfiles/rails.4.2.mongoid.5.1.0.will_paginate.gemfile +0 -14
- data/gemfiles/rails.5.0.0.beta3.activerecord.gemfile +0 -16
- data/gemfiles/rails.5.0.0.beta3.activerecord.kaminari.gemfile +0 -16
- data/gemfiles/rails.5.0.0.beta3.activerecord.will_paginate.gemfile +0 -15
- data/gemfiles/sequel.4.31.gemfile +0 -13
- data/lib/chewy/query/pagination/will_paginate.rb +0 -27
- data/lib/chewy/query/scoping.rb +0 -20
- data/spec/chewy/query/pagination/will_paginage_spec.rb +0 -60
data/lib/chewy/query/compose.rb
CHANGED
@@ -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
|
8
|
-
query = {
|
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
|
-
{
|
11
|
+
{query: {filtered: {
|
13
12
|
query: query,
|
14
13
|
filter: filter
|
15
|
-
}
|
14
|
+
}}}
|
16
15
|
else
|
17
|
-
{
|
16
|
+
{query: {filtered: {
|
18
17
|
filter: filter
|
19
|
-
}
|
18
|
+
}}}
|
20
19
|
end
|
21
|
-
filtered[:query][:filtered]
|
20
|
+
filtered[:query][:filtered][:strategy] = options[:strategy].to_s if options[:strategy].present?
|
22
21
|
filtered
|
23
22
|
elsif query.present?
|
24
|
-
{
|
23
|
+
{query: query}
|
25
24
|
else
|
26
|
-
{
|
25
|
+
{}
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
30
|
-
def _queries_join
|
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
|
-
{
|
35
|
+
{dis_max: {queries: queries}}
|
37
36
|
when :must, :should, :must_not
|
38
|
-
{
|
37
|
+
{bool: {logic => queries}}
|
39
38
|
else
|
40
39
|
if logic.is_a?(Float)
|
41
|
-
{
|
40
|
+
{dis_max: {queries: queries, tie_breaker: logic}}
|
42
41
|
else
|
43
|
-
{
|
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
|
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
|
-
{
|
56
|
+
{logic => filters}
|
58
57
|
when :must, :should, :must_not
|
59
|
-
{
|
58
|
+
{bool: {logic => filters}}
|
60
59
|
else
|
61
|
-
{
|
60
|
+
{bool: {should: filters, minimum_should_match: logic}}
|
62
61
|
end
|
63
62
|
else
|
64
63
|
filters.first
|
data/lib/chewy/query/criteria.rb
CHANGED
@@ -4,11 +4,11 @@ module Chewy
|
|
4
4
|
class Query
|
5
5
|
class Criteria
|
6
6
|
include Compose
|
7
|
-
ARRAY_STORAGES = [
|
8
|
-
HASH_STORAGES = [
|
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
|
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 ==
|
19
|
+
def ==(other)
|
20
20
|
other.is_a?(self.class) && storages == other.storages
|
21
21
|
end
|
22
22
|
|
23
|
-
{
|
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).
|
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
|
-
[
|
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
|
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!
|
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
|
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
|
-
{
|
115
|
+
{body: body.presence || {query: {match_all: {}}}}
|
112
116
|
else
|
113
|
-
body
|
114
|
-
body
|
115
|
-
body
|
116
|
-
body
|
117
|
-
body
|
118
|
-
body
|
119
|
-
body
|
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
|
-
{
|
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(
|
137
|
+
def initialize_clone(origin)
|
134
138
|
STORAGES.each do |storage|
|
135
|
-
value =
|
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 = {
|
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] = {
|
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| {
|
183
|
+
_filters_join(types.map { |type| {type: {value: type}} }, :or)
|
174
184
|
end
|
175
185
|
|
176
186
|
def _request_post_filter
|
data/lib/chewy/query/filters.rb
CHANGED
@@ -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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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/, '')
|
data/lib/chewy/query/loading.rb
CHANGED
@@ -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
|
99
|
-
|
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,16 +2,18 @@ module Chewy
|
|
2
2
|
class Query
|
3
3
|
module Nodes
|
4
4
|
class Bool < Expr
|
5
|
-
METHODS = %w
|
5
|
+
METHODS = %w[must must_not should].freeze
|
6
6
|
|
7
|
-
def initialize
|
7
|
+
def initialize(options = {})
|
8
8
|
@options = options
|
9
|
-
@must
|
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}").
|
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
|
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
|
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 Field < Base
|
5
|
-
def initialize
|
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 >
|
20
|
-
Nodes::Range.new @name, *__options_merge__(gt:
|
19
|
+
def >(other)
|
20
|
+
Nodes::Range.new @name, *__options_merge__(gt: other)
|
21
21
|
end
|
22
22
|
|
23
|
-
def <
|
24
|
-
Nodes::Range.new @name, *__options_merge__(lt:
|
23
|
+
def <(other)
|
24
|
+
Nodes::Range.new @name, *__options_merge__(lt: other)
|
25
25
|
end
|
26
26
|
|
27
|
-
def >=
|
28
|
-
Nodes::Range.new @name, *__options_merge__(gt:
|
27
|
+
def >=(other)
|
28
|
+
Nodes::Range.new @name, *__options_merge__(gt: other, left_closed: true)
|
29
29
|
end
|
30
30
|
|
31
|
-
def <=
|
32
|
-
Nodes::Range.new @name, *__options_merge__(lt:
|
31
|
+
def <=(other)
|
32
|
+
Nodes::Range.new @name, *__options_merge__(lt: other, right_closed: true)
|
33
33
|
end
|
34
34
|
|
35
|
-
def ==
|
36
|
-
case
|
35
|
+
def ==(other)
|
36
|
+
case other
|
37
37
|
when nil
|
38
|
-
|
38
|
+
nil?
|
39
39
|
when ::Regexp
|
40
|
-
Nodes::Regexp.new @name,
|
40
|
+
Nodes::Regexp.new @name, other, *@args
|
41
41
|
when ::Range
|
42
|
-
Nodes::Range.new @name, *__options_merge__(gt:
|
42
|
+
Nodes::Range.new @name, *__options_merge__(gt: other.first, lt: other.last)
|
43
43
|
else
|
44
|
-
if
|
44
|
+
if other.is_a?(Array) && other.first.is_a?(::Range)
|
45
45
|
Nodes::Range.new @name, *__options_merge__(
|
46
|
-
gt:
|
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,
|
50
|
+
Nodes::Equal.new @name, other, *@args
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
def !=
|
56
|
-
case
|
55
|
+
def !=(other)
|
56
|
+
case other
|
57
57
|
when nil
|
58
58
|
Nodes::Exists.new @name
|
59
59
|
else
|
60
|
-
Nodes::Not.new self ==
|
60
|
+
Nodes::Not.new self == other
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
def =~
|
65
|
-
case
|
64
|
+
def =~(other)
|
65
|
+
case other
|
66
66
|
when ::Regexp
|
67
|
-
Nodes::Regexp.new @name,
|
67
|
+
Nodes::Regexp.new @name, other, *@args
|
68
68
|
else
|
69
|
-
Nodes::Prefix.new @name,
|
69
|
+
Nodes::Prefix.new @name, other, @args.extract_options!
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
-
def !~
|
74
|
-
Not.new(self =~
|
73
|
+
def !~(other)
|
74
|
+
Not.new(self =~ other)
|
75
75
|
end
|
76
76
|
|
77
|
-
def
|
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(
|
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__!
|
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__
|
102
|
+
def __options_merge__(additional = {})
|
99
103
|
options = @args.extract_options!
|
100
104
|
options = options.merge(additional)
|
101
105
|
@args + [options]
|