caoutsearch 0.0.0 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +819 -6
- data/lib/caoutsearch/config/mappings.rb +1 -1
- data/lib/caoutsearch/filter/base.rb +11 -7
- data/lib/caoutsearch/filter/boolean.rb +1 -1
- data/lib/caoutsearch/filter/date.rb +93 -22
- data/lib/caoutsearch/filter/default.rb +10 -10
- data/lib/caoutsearch/filter/geo_point.rb +1 -1
- data/lib/caoutsearch/filter/match.rb +5 -5
- data/lib/caoutsearch/filter/none.rb +1 -1
- data/lib/caoutsearch/filter/range.rb +6 -6
- data/lib/caoutsearch/index/document.rb +11 -11
- data/lib/caoutsearch/index/indice_versions.rb +3 -3
- data/lib/caoutsearch/index/internal_dsl.rb +3 -3
- data/lib/caoutsearch/index/reindex.rb +11 -11
- data/lib/caoutsearch/index/scoping.rb +4 -4
- data/lib/caoutsearch/index/serialization.rb +13 -13
- data/lib/caoutsearch/instrumentation/base.rb +12 -12
- data/lib/caoutsearch/instrumentation/search.rb +11 -2
- data/lib/caoutsearch/mappings.rb +1 -1
- data/lib/caoutsearch/model/indexable.rb +57 -0
- data/lib/caoutsearch/model/searchable.rb +31 -0
- data/lib/caoutsearch/model.rb +12 -0
- data/lib/caoutsearch/response/aggregations.rb +50 -0
- data/lib/caoutsearch/response/response.rb +9 -0
- data/lib/caoutsearch/response/suggestions.rb +9 -0
- data/lib/caoutsearch/response.rb +6 -0
- data/lib/caoutsearch/search/adapter/active_record.rb +39 -0
- data/lib/caoutsearch/search/base.rb +16 -15
- data/lib/caoutsearch/search/batch/scroll.rb +93 -0
- data/lib/caoutsearch/search/batch/search_after.rb +70 -0
- data/lib/caoutsearch/search/batch_methods.rb +63 -0
- data/lib/caoutsearch/search/callbacks.rb +28 -0
- data/lib/caoutsearch/search/delete_methods.rb +19 -0
- data/lib/caoutsearch/search/dsl/item.rb +2 -2
- data/lib/caoutsearch/search/inspect.rb +34 -0
- data/lib/caoutsearch/search/instrumentation.rb +19 -0
- data/lib/caoutsearch/search/internal_dsl.rb +107 -0
- data/lib/caoutsearch/search/naming.rb +45 -0
- data/lib/caoutsearch/search/point_in_time.rb +28 -0
- data/lib/caoutsearch/search/query/boolean.rb +4 -4
- data/lib/caoutsearch/search/query/nested.rb +1 -1
- data/lib/caoutsearch/search/query/setters.rb +4 -4
- data/lib/caoutsearch/search/query_builder/aggregations.rb +49 -0
- data/lib/caoutsearch/search/query_builder.rb +89 -0
- data/lib/caoutsearch/search/query_methods.rb +157 -0
- data/lib/caoutsearch/search/records.rb +23 -0
- data/lib/caoutsearch/search/resettable.rb +38 -0
- data/lib/caoutsearch/search/response.rb +97 -0
- data/lib/caoutsearch/search/sanitizer.rb +2 -2
- data/lib/caoutsearch/search/search_methods.rb +239 -0
- data/lib/caoutsearch/search/type_cast.rb +14 -6
- data/lib/caoutsearch/search/value.rb +10 -10
- data/lib/caoutsearch/search/value_overflow.rb +1 -1
- data/lib/caoutsearch/settings.rb +1 -1
- data/lib/caoutsearch/testing/mock_requests.rb +105 -0
- data/lib/caoutsearch/testing.rb +3 -0
- data/lib/caoutsearch/version.rb +1 -1
- data/lib/caoutsearch.rb +10 -5
- metadata +44 -126
- data/lib/caoutsearch/search/search/delete_methods.rb +0 -21
- data/lib/caoutsearch/search/search/inspect.rb +0 -36
- data/lib/caoutsearch/search/search/instrumentation.rb +0 -21
- data/lib/caoutsearch/search/search/internal_dsl.rb +0 -77
- data/lib/caoutsearch/search/search/naming.rb +0 -47
- data/lib/caoutsearch/search/search/query_builder.rb +0 -94
- data/lib/caoutsearch/search/search/query_methods.rb +0 -180
- data/lib/caoutsearch/search/search/resettable.rb +0 -35
- data/lib/caoutsearch/search/search/response.rb +0 -88
- data/lib/caoutsearch/search/search/scroll_methods.rb +0 -113
- data/lib/caoutsearch/search/search/search_methods.rb +0 -230
@@ -1,180 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Caoutsearch
|
4
|
-
module Search
|
5
|
-
module Search
|
6
|
-
module QueryMethods
|
7
|
-
delegate :merge, :merge!, :to_h, :to_json, :as_json, :filters,
|
8
|
-
:add_none, :add_filter, :add_sort, :add_aggregation, :add_suggestion,
|
9
|
-
:build_terms, :should_filter_on, :must_filter_on, :must_not_filter_on,
|
10
|
-
:nested_queries, :nested_query,
|
11
|
-
to: :elasticsearch_query
|
12
|
-
|
13
|
-
# Accessors
|
14
|
-
# ------------------------------------------------------------------------
|
15
|
-
def elasticsearch_query
|
16
|
-
@elasticsearch_query ||= Caoutsearch::Search::Query::Base.new
|
17
|
-
end
|
18
|
-
|
19
|
-
# Applying criteria
|
20
|
-
# ------------------------------------------------------------------------
|
21
|
-
def search_by(criteria)
|
22
|
-
case criteria
|
23
|
-
when Array then criteria.each { |criterion| search_by(criterion) }
|
24
|
-
when Hash then criteria.each { |key, value| filter_by(key, value) }
|
25
|
-
when String then apply_dsl_match_all(criteria)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def filter_by(key, value)
|
30
|
-
case key
|
31
|
-
when Array
|
32
|
-
items = key.filter_map { |k| config[:filters][k] }
|
33
|
-
apply_dsl_filters(items, value)
|
34
|
-
when Caoutsearch::Search::DSL::Item
|
35
|
-
apply_dsl_filter(key, value)
|
36
|
-
else
|
37
|
-
if config[:filters].key?(key)
|
38
|
-
apply_dsl_filter(config[:filters][key], value)
|
39
|
-
elsif config[:filters].key?(:__undef__)
|
40
|
-
block = config[:filters][:__undef__]
|
41
|
-
instance_exec(key, value, &block)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Applying DSL filters items
|
47
|
-
# ------------------------------------------------------------------------
|
48
|
-
def apply_dsl_match_all(value)
|
49
|
-
return unless (block = config[:match_all])
|
50
|
-
|
51
|
-
instance_exec(value, &block)
|
52
|
-
end
|
53
|
-
|
54
|
-
def apply_dsl_filter(item, value)
|
55
|
-
return instance_exec(value, &item.block) if item.has_block?
|
56
|
-
|
57
|
-
terms = []
|
58
|
-
indexes = item.indexes
|
59
|
-
options = item.options.dup
|
60
|
-
query = elasticsearch_query
|
61
|
-
|
62
|
-
if options[:nested_query]
|
63
|
-
query = nested_query(options[:nested_query])
|
64
|
-
options[:nested] = nil
|
65
|
-
end
|
66
|
-
|
67
|
-
indexes.each do |index|
|
68
|
-
options_index = options.dup
|
69
|
-
options_index[:type] = mappings.find_type(index) unless options_index.key?(:type)
|
70
|
-
options_index[:nested] = mappings.nested_path(index) unless options_index.key?(:nested)
|
71
|
-
options_index[:include_in_parent] = mappings.include_in_parent?(index) unless options_index.key?(:include_in_parent) || !options_index[:nested]
|
72
|
-
|
73
|
-
terms += query.build_terms(index, value, **options_index)
|
74
|
-
end
|
75
|
-
|
76
|
-
query.should_filter_on(terms)
|
77
|
-
end
|
78
|
-
|
79
|
-
def apply_dsl_filters(items, value)
|
80
|
-
terms = []
|
81
|
-
|
82
|
-
items.each do |item|
|
83
|
-
terms += isolate_dsl_filter(item, value)
|
84
|
-
end
|
85
|
-
|
86
|
-
should_filter_on(terms)
|
87
|
-
end
|
88
|
-
|
89
|
-
def isolate_dsl_filter(item, value)
|
90
|
-
isolated_instance = clone
|
91
|
-
isolated_instance.apply_dsl_filter(item, value)
|
92
|
-
isolated_instance.elasticsearch_query.dig(:query, :bool, :filter) || []
|
93
|
-
end
|
94
|
-
|
95
|
-
# Applying orders
|
96
|
-
# ------------------------------------------------------------------------
|
97
|
-
def order_by(keys)
|
98
|
-
case keys
|
99
|
-
when Array then keys.each { |key| order_by(key) }
|
100
|
-
when Hash then keys.each { |key, direction| sort_by(key, direction) }
|
101
|
-
when String, Symbol then sort_by(keys)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def sort_by(key, direction = nil)
|
106
|
-
if config[:sorts].key?(key)
|
107
|
-
apply_dsl_sort(config[:sorts][key], direction)
|
108
|
-
elsif config[:sorts].key?(:__undef__)
|
109
|
-
block = config[:sorts][:__undef__]
|
110
|
-
instance_exec(key, direction, &block)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def apply_dsl_sort(item, direction)
|
115
|
-
return instance_exec(direction, &item.block) if item.has_block?
|
116
|
-
|
117
|
-
indexes = item.indexes
|
118
|
-
indexes.each do |index|
|
119
|
-
case index
|
120
|
-
when :default, "default"
|
121
|
-
sort_by(:default, direction)
|
122
|
-
|
123
|
-
when Hash
|
124
|
-
index.map do |key, value|
|
125
|
-
key_direction = (value.to_s == direction.to_s ? :asc : :desc)
|
126
|
-
add_sort(key, key_direction)
|
127
|
-
end
|
128
|
-
|
129
|
-
else
|
130
|
-
add_sort(index, direction)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
# Applying aggregations
|
136
|
-
# ------------------------------------------------------------------------
|
137
|
-
def aggregate_with(*args)
|
138
|
-
args.each do |arg|
|
139
|
-
if arg.is_a?(Hash)
|
140
|
-
arg.each do |key, value|
|
141
|
-
next unless (item = config[:aggregations][key])
|
142
|
-
|
143
|
-
apply_dsl_aggregate(item, value)
|
144
|
-
end
|
145
|
-
elsif (item = config[:aggregations][arg])
|
146
|
-
apply_dsl_aggregate(item)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
def apply_dsl_aggregate(item, *args)
|
152
|
-
return instance_exec(*args, &item.block) if item.has_block?
|
153
|
-
|
154
|
-
add_aggregation(item.name, item.options)
|
155
|
-
end
|
156
|
-
|
157
|
-
# Applying Suggests
|
158
|
-
# ------------------------------------------------------------------------
|
159
|
-
def suggest_with(*args)
|
160
|
-
args.each do |(hash, options)|
|
161
|
-
raise ArgumentError unless hash.is_a?(Hash)
|
162
|
-
|
163
|
-
hash.each do |key, value|
|
164
|
-
next unless (item = config[:suggestions][key.to_s])
|
165
|
-
|
166
|
-
options ||= {}
|
167
|
-
apply_dsl_suggest(item, value, **options)
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
def apply_dsl_suggest(item, query, **options)
|
173
|
-
return instance_exec(query, **options, &item.block) if item.has_block?
|
174
|
-
|
175
|
-
add_suggestion(item.name, query, **options)
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Caoutsearch
|
4
|
-
module Search
|
5
|
-
module Search
|
6
|
-
module Resettable
|
7
|
-
def spawn
|
8
|
-
clone
|
9
|
-
end
|
10
|
-
|
11
|
-
def clone
|
12
|
-
super.reset
|
13
|
-
end
|
14
|
-
|
15
|
-
def dup
|
16
|
-
super.reset
|
17
|
-
end
|
18
|
-
|
19
|
-
def reset
|
20
|
-
reset_variable(:@elasticsearch_query)
|
21
|
-
reset_variable(:@nested_queries)
|
22
|
-
reset_variable(:@response)
|
23
|
-
reset_variable(:@total_count)
|
24
|
-
self
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def reset_variable(key)
|
30
|
-
remove_instance_variable(key) if instance_variable_defined?(key)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Caoutsearch
|
4
|
-
module Search
|
5
|
-
module Search
|
6
|
-
module Response
|
7
|
-
delegate :empty?, :size, :slice, :[], :to_a, :to_ary, to: :hits
|
8
|
-
delegate_missing_to :each
|
9
|
-
|
10
|
-
def response
|
11
|
-
load unless @response
|
12
|
-
@response
|
13
|
-
end
|
14
|
-
|
15
|
-
def took
|
16
|
-
response["took"]
|
17
|
-
end
|
18
|
-
|
19
|
-
def timed_out
|
20
|
-
response["timed_out"]
|
21
|
-
end
|
22
|
-
|
23
|
-
def shards
|
24
|
-
response["_shards"]
|
25
|
-
end
|
26
|
-
|
27
|
-
def hits
|
28
|
-
response.dig("hits", "hits")
|
29
|
-
end
|
30
|
-
|
31
|
-
def max_score
|
32
|
-
response.dig("hits", "max_score")
|
33
|
-
end
|
34
|
-
|
35
|
-
def total_count
|
36
|
-
if response.dig("hits", "total", "relation") == "gte" && !@track_total_hits
|
37
|
-
@total_count ||= spawn.track_total_hits(true).total_count
|
38
|
-
else
|
39
|
-
response.dig("hits", "total", "value")
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def total_pages
|
44
|
-
(total_count.to_f / current_limit).ceil
|
45
|
-
end
|
46
|
-
|
47
|
-
def ids
|
48
|
-
hits.pluck("_id")
|
49
|
-
end
|
50
|
-
|
51
|
-
def aggregations
|
52
|
-
# TODO
|
53
|
-
end
|
54
|
-
|
55
|
-
def suggestions
|
56
|
-
# TODO
|
57
|
-
end
|
58
|
-
|
59
|
-
def records
|
60
|
-
model.where(model.primary_key => ids)
|
61
|
-
end
|
62
|
-
|
63
|
-
def each(&block)
|
64
|
-
return to_enum(:each) { hits.size } unless block
|
65
|
-
|
66
|
-
hits.each(&block)
|
67
|
-
end
|
68
|
-
|
69
|
-
def load
|
70
|
-
@response = perform_search_query(build.to_h)
|
71
|
-
self
|
72
|
-
end
|
73
|
-
|
74
|
-
def perform_search_query(query)
|
75
|
-
request_payload = {
|
76
|
-
index: index_name,
|
77
|
-
body: query
|
78
|
-
}
|
79
|
-
|
80
|
-
instrument(:search) do |event_payload|
|
81
|
-
event_payload[:request] = request_payload
|
82
|
-
event_payload[:response] = client.search(request_payload)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
@@ -1,113 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Caoutsearch
|
4
|
-
module Search
|
5
|
-
module Search
|
6
|
-
module ScrollMethods
|
7
|
-
def scroll(scroll: "1h", &block)
|
8
|
-
return to_enum(scroll, scroll: scroll) unless block
|
9
|
-
|
10
|
-
request_payload = {
|
11
|
-
index: index_name,
|
12
|
-
scroll: scroll,
|
13
|
-
body: build.to_h
|
14
|
-
}
|
15
|
-
|
16
|
-
total = 0
|
17
|
-
progress = 0
|
18
|
-
requested_at = nil
|
19
|
-
last_response_time = nil
|
20
|
-
|
21
|
-
results = instrument(:scroll_search) do |event_payload|
|
22
|
-
response = client.search(request_payload)
|
23
|
-
last_response_time = Time.current
|
24
|
-
|
25
|
-
total = response["hits"]["total"]["value"]
|
26
|
-
progress += response["hits"]["hits"].size
|
27
|
-
|
28
|
-
event_payload[:request] = request_payload
|
29
|
-
event_payload[:response] = response
|
30
|
-
event_payload[:total] = total
|
31
|
-
event_payload[:progress] = progress
|
32
|
-
|
33
|
-
response
|
34
|
-
end
|
35
|
-
|
36
|
-
scroll_id = results["_scroll_id"]
|
37
|
-
hits = results["hits"]["hits"]
|
38
|
-
|
39
|
-
yield hits, { progress: progress, total: total, scroll_id: scroll_id }
|
40
|
-
|
41
|
-
while progress < total
|
42
|
-
request_payload = {
|
43
|
-
scroll_id: scroll_id,
|
44
|
-
scroll: scroll
|
45
|
-
}
|
46
|
-
|
47
|
-
requested_at = Time.current
|
48
|
-
|
49
|
-
results = instrument(:scroll, scroll: scroll_id) do |event_payload|
|
50
|
-
response = client.scroll(request_payload)
|
51
|
-
last_response_time = Time.current
|
52
|
-
|
53
|
-
total = response["hits"]["total"]["value"]
|
54
|
-
progress += response["hits"]["hits"].size
|
55
|
-
|
56
|
-
event_payload[:request] = request_payload
|
57
|
-
event_payload[:response] = response
|
58
|
-
event_payload[:total] = total
|
59
|
-
event_payload[:progress] = progress
|
60
|
-
|
61
|
-
response
|
62
|
-
rescue Elastic::Transport::Transport::Errors::NotFound => e
|
63
|
-
raise_enhance_message_when_scroll_failed(e, scroll, requested_at, last_response_time)
|
64
|
-
end
|
65
|
-
|
66
|
-
hits = results["hits"]["hits"]
|
67
|
-
progress += hits.size
|
68
|
-
|
69
|
-
break if hits.empty?
|
70
|
-
|
71
|
-
yield hits, { progress: progress, total: total, scroll_id: scroll_id }
|
72
|
-
end
|
73
|
-
|
74
|
-
total
|
75
|
-
ensure
|
76
|
-
clear_scroll(scroll_id) if scroll_id
|
77
|
-
end
|
78
|
-
|
79
|
-
def clear_scroll(scroll_id)
|
80
|
-
client.clear_scroll(scroll_id: scroll_id)
|
81
|
-
rescue ::Elastic::Transport::Transport::Errors::NotFound
|
82
|
-
# We dont care if the scroll ID is already expired
|
83
|
-
end
|
84
|
-
|
85
|
-
def scroll_records_in_batches(**options)
|
86
|
-
return to_enum(:scroll_records_in_batches, **options) unless block_given?
|
87
|
-
|
88
|
-
scroll(**options) do |hits|
|
89
|
-
ids = hits.map { |doc| doc["_id"] }
|
90
|
-
yield model.where(id: ids)
|
91
|
-
model.connection.clear_query_cache
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def scroll_records(**options, &block)
|
96
|
-
return to_enum(:scroll_records, **options) unless block
|
97
|
-
|
98
|
-
scroll_records_in_batches(**options) do |relation|
|
99
|
-
relation.each(&block)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
private
|
104
|
-
|
105
|
-
def raise_enhance_message_when_scroll_failed(error, scroll, requested_at, last_response_time)
|
106
|
-
elapsed = (requested_at - last_response_time).round(1).seconds
|
107
|
-
|
108
|
-
raise error.exception("Scroll registered for #{scroll}, #{elapsed.inspect} elapsed between. #{error.message}")
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
@@ -1,230 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Caoutsearch
|
4
|
-
module Search
|
5
|
-
module Search
|
6
|
-
module SearchMethods
|
7
|
-
attr_reader :current_context, :current_order, :current_aggregations,
|
8
|
-
:current_suggestions, :current_fields, :current_source
|
9
|
-
|
10
|
-
# Public API
|
11
|
-
# ------------------------------------------------------------------------
|
12
|
-
def search(...)
|
13
|
-
spawn.search!(...)
|
14
|
-
end
|
15
|
-
|
16
|
-
def context(...)
|
17
|
-
spawn.context!(...)
|
18
|
-
end
|
19
|
-
|
20
|
-
def order(...)
|
21
|
-
spawn.order!(...)
|
22
|
-
end
|
23
|
-
|
24
|
-
def page(...)
|
25
|
-
spawn.page!(...)
|
26
|
-
end
|
27
|
-
|
28
|
-
def limit(...)
|
29
|
-
spawn.limit!(...)
|
30
|
-
end
|
31
|
-
alias_method :per, :limit
|
32
|
-
|
33
|
-
def offset(...)
|
34
|
-
spawn.offset!(...)
|
35
|
-
end
|
36
|
-
|
37
|
-
def aggregate(...)
|
38
|
-
spawn.aggregate!(...)
|
39
|
-
end
|
40
|
-
|
41
|
-
def suggest(...)
|
42
|
-
spawn.suggest!(...)
|
43
|
-
end
|
44
|
-
|
45
|
-
def fields(...)
|
46
|
-
spawn.fields!(...)
|
47
|
-
end
|
48
|
-
alias_method :returns, :fields
|
49
|
-
|
50
|
-
def source(...)
|
51
|
-
spawn.source!(...)
|
52
|
-
end
|
53
|
-
alias_method :with_sources, :source
|
54
|
-
|
55
|
-
def without_sources
|
56
|
-
spawn.source!(false)
|
57
|
-
end
|
58
|
-
|
59
|
-
def without_hits
|
60
|
-
spawn.source!(false).limit!(0)
|
61
|
-
end
|
62
|
-
|
63
|
-
def track_total_hits(...)
|
64
|
-
spawn.track_total_hits!(...)
|
65
|
-
end
|
66
|
-
|
67
|
-
def prepend(...)
|
68
|
-
spawn.prepend!(...)
|
69
|
-
end
|
70
|
-
|
71
|
-
def append(...)
|
72
|
-
spawn.append!(...)
|
73
|
-
end
|
74
|
-
|
75
|
-
def unscope(...)
|
76
|
-
spawn.unscope!(...)
|
77
|
-
end
|
78
|
-
|
79
|
-
# Setters
|
80
|
-
# ------------------------------------------------------------------------
|
81
|
-
def search!(*values)
|
82
|
-
values = values.flatten.map do |value|
|
83
|
-
value = value.stringify_keys if value.is_a?(Hash)
|
84
|
-
value
|
85
|
-
end
|
86
|
-
|
87
|
-
@search_criteria ||= []
|
88
|
-
@search_criteria += values
|
89
|
-
self
|
90
|
-
end
|
91
|
-
|
92
|
-
def context!(value)
|
93
|
-
@current_context = value
|
94
|
-
self
|
95
|
-
end
|
96
|
-
|
97
|
-
def order!(value)
|
98
|
-
@current_order = value
|
99
|
-
self
|
100
|
-
end
|
101
|
-
|
102
|
-
def page!(value)
|
103
|
-
@current_page = value
|
104
|
-
self
|
105
|
-
end
|
106
|
-
|
107
|
-
def limit!(value)
|
108
|
-
@current_limit = value
|
109
|
-
self
|
110
|
-
end
|
111
|
-
|
112
|
-
def offset!(value)
|
113
|
-
@current_offset = value
|
114
|
-
self
|
115
|
-
end
|
116
|
-
|
117
|
-
def aggregate!(*values)
|
118
|
-
@current_aggregations ||= []
|
119
|
-
@current_aggregations += values.flatten
|
120
|
-
self
|
121
|
-
end
|
122
|
-
|
123
|
-
def suggest!(values, **options)
|
124
|
-
raise ArgumentError unless values.is_a?(Hash)
|
125
|
-
|
126
|
-
@current_suggestions ||= []
|
127
|
-
@current_suggestions << [values, options]
|
128
|
-
self
|
129
|
-
end
|
130
|
-
|
131
|
-
def fields!(*values)
|
132
|
-
@current_fields ||= []
|
133
|
-
@current_fields += values.flatten
|
134
|
-
self
|
135
|
-
end
|
136
|
-
|
137
|
-
def source!(*values)
|
138
|
-
@current_source ||= []
|
139
|
-
@current_source += values.flatten
|
140
|
-
self
|
141
|
-
end
|
142
|
-
|
143
|
-
def track_total_hits!(value = true)
|
144
|
-
@track_total_hits = value
|
145
|
-
self
|
146
|
-
end
|
147
|
-
|
148
|
-
def prepend!(hash)
|
149
|
-
@prepend_hash = hash
|
150
|
-
self
|
151
|
-
end
|
152
|
-
|
153
|
-
def append!(hash)
|
154
|
-
@append_hash = hash
|
155
|
-
self
|
156
|
-
end
|
157
|
-
|
158
|
-
UNSCOPE_KEYS = {
|
159
|
-
"search" => :@search_criteria,
|
160
|
-
"search_criteria" => :@search_criteria,
|
161
|
-
"limit" => :@current_limit,
|
162
|
-
"per" => :@current_limit,
|
163
|
-
"aggregate" => :@current_aggregations,
|
164
|
-
"aggregations" => :@current_aggregations,
|
165
|
-
"suggest" => :@current_suggestions,
|
166
|
-
"suggestions" => :@current_suggestions,
|
167
|
-
"context" => :@current_context,
|
168
|
-
"order" => :@current_order,
|
169
|
-
"page" => :@current_page,
|
170
|
-
"offset" => :@current_offset,
|
171
|
-
"fields" => :@current_fields,
|
172
|
-
"source" => :@current_source
|
173
|
-
}.freeze
|
174
|
-
|
175
|
-
def unscope!(key)
|
176
|
-
raise ArgumentError unless (variable = UNSCOPE_KEYS[key.to_s])
|
177
|
-
|
178
|
-
reset_variable(variable)
|
179
|
-
self
|
180
|
-
end
|
181
|
-
|
182
|
-
# Getters
|
183
|
-
# ------------------------------------------------------------------------
|
184
|
-
def search_criteria
|
185
|
-
@search_criteria ||= []
|
186
|
-
end
|
187
|
-
|
188
|
-
def current_page
|
189
|
-
@current_page&.to_i || 1
|
190
|
-
end
|
191
|
-
|
192
|
-
def current_limit
|
193
|
-
@current_limit&.to_i || 10
|
194
|
-
end
|
195
|
-
|
196
|
-
def current_offset
|
197
|
-
if @current_offset
|
198
|
-
@current_offset.to_i
|
199
|
-
elsif @current_page
|
200
|
-
(current_limit * (current_page - 1))
|
201
|
-
else
|
202
|
-
0
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
# Criteria handlers
|
207
|
-
# ------------------------------------------------------------------------
|
208
|
-
def find_criterion(key)
|
209
|
-
key = key.to_s
|
210
|
-
search_criteria.find do |value|
|
211
|
-
return value[key] if value.is_a?(Hash) && value.key?(key)
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
def has_criterion?(key)
|
216
|
-
key = key.to_s
|
217
|
-
search_criteria.any? do |value|
|
218
|
-
return true if value.is_a?(Hash) && value.key?(key)
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
def search_criteria_keys
|
223
|
-
search_criteria.each_with_object([]) do |criterion, keys|
|
224
|
-
keys.concat(criterion.keys) if criterion.is_a?(Hash)
|
225
|
-
end
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|