search-engine-for-typesense 1.0.0
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 +7 -0
- data/LICENSE +21 -0
- data/README.md +148 -0
- data/app/search_engine/search_engine/app_info.rb +11 -0
- data/app/search_engine/search_engine/index_partition_job.rb +170 -0
- data/lib/generators/search_engine/install/install_generator.rb +20 -0
- data/lib/generators/search_engine/install/templates/initializer.rb.tt +230 -0
- data/lib/generators/search_engine/model/model_generator.rb +86 -0
- data/lib/generators/search_engine/model/templates/model.rb.tt +12 -0
- data/lib/search-engine-for-typesense.rb +12 -0
- data/lib/search_engine/active_record_syncable.rb +247 -0
- data/lib/search_engine/admin/stopwords.rb +125 -0
- data/lib/search_engine/admin/synonyms.rb +125 -0
- data/lib/search_engine/admin.rb +12 -0
- data/lib/search_engine/ast/and.rb +52 -0
- data/lib/search_engine/ast/binary_op.rb +75 -0
- data/lib/search_engine/ast/eq.rb +19 -0
- data/lib/search_engine/ast/group.rb +18 -0
- data/lib/search_engine/ast/gt.rb +12 -0
- data/lib/search_engine/ast/gte.rb +12 -0
- data/lib/search_engine/ast/in.rb +28 -0
- data/lib/search_engine/ast/lt.rb +12 -0
- data/lib/search_engine/ast/lte.rb +12 -0
- data/lib/search_engine/ast/matches.rb +55 -0
- data/lib/search_engine/ast/node.rb +176 -0
- data/lib/search_engine/ast/not_eq.rb +13 -0
- data/lib/search_engine/ast/not_in.rb +24 -0
- data/lib/search_engine/ast/or.rb +52 -0
- data/lib/search_engine/ast/prefix.rb +51 -0
- data/lib/search_engine/ast/raw.rb +41 -0
- data/lib/search_engine/ast/unary_op.rb +43 -0
- data/lib/search_engine/ast.rb +101 -0
- data/lib/search_engine/base/creation.rb +727 -0
- data/lib/search_engine/base/deletion.rb +80 -0
- data/lib/search_engine/base/display_coercions.rb +36 -0
- data/lib/search_engine/base/hydration.rb +312 -0
- data/lib/search_engine/base/index_maintenance/cleanup.rb +202 -0
- data/lib/search_engine/base/index_maintenance/lifecycle.rb +251 -0
- data/lib/search_engine/base/index_maintenance/schema.rb +117 -0
- data/lib/search_engine/base/index_maintenance.rb +459 -0
- data/lib/search_engine/base/indexing_dsl.rb +255 -0
- data/lib/search_engine/base/joins.rb +479 -0
- data/lib/search_engine/base/model_dsl.rb +472 -0
- data/lib/search_engine/base/presets.rb +43 -0
- data/lib/search_engine/base/pretty_printer.rb +315 -0
- data/lib/search_engine/base/relation_delegation.rb +42 -0
- data/lib/search_engine/base/scopes.rb +113 -0
- data/lib/search_engine/base/updating.rb +92 -0
- data/lib/search_engine/base.rb +38 -0
- data/lib/search_engine/bulk.rb +284 -0
- data/lib/search_engine/cache.rb +33 -0
- data/lib/search_engine/cascade.rb +531 -0
- data/lib/search_engine/cli/doctor.rb +631 -0
- data/lib/search_engine/cli/support.rb +217 -0
- data/lib/search_engine/cli.rb +222 -0
- data/lib/search_engine/client/http_adapter.rb +63 -0
- data/lib/search_engine/client/request_builder.rb +92 -0
- data/lib/search_engine/client/services/base.rb +74 -0
- data/lib/search_engine/client/services/collections.rb +161 -0
- data/lib/search_engine/client/services/documents.rb +214 -0
- data/lib/search_engine/client/services/operations.rb +152 -0
- data/lib/search_engine/client/services/search.rb +190 -0
- data/lib/search_engine/client/services.rb +29 -0
- data/lib/search_engine/client.rb +765 -0
- data/lib/search_engine/client_options.rb +20 -0
- data/lib/search_engine/collection_resolver.rb +191 -0
- data/lib/search_engine/collections_graph.rb +330 -0
- data/lib/search_engine/compiled_params.rb +143 -0
- data/lib/search_engine/compiler.rb +383 -0
- data/lib/search_engine/config/observability.rb +27 -0
- data/lib/search_engine/config/presets.rb +92 -0
- data/lib/search_engine/config/selection.rb +16 -0
- data/lib/search_engine/config/typesense.rb +48 -0
- data/lib/search_engine/config/validators.rb +97 -0
- data/lib/search_engine/config.rb +917 -0
- data/lib/search_engine/console_helpers.rb +130 -0
- data/lib/search_engine/deletion.rb +103 -0
- data/lib/search_engine/dispatcher.rb +125 -0
- data/lib/search_engine/dsl/parser.rb +582 -0
- data/lib/search_engine/engine.rb +167 -0
- data/lib/search_engine/errors.rb +290 -0
- data/lib/search_engine/filters/sanitizer.rb +189 -0
- data/lib/search_engine/hydration/materializers.rb +808 -0
- data/lib/search_engine/hydration/selection_context.rb +96 -0
- data/lib/search_engine/indexer/batch_planner.rb +76 -0
- data/lib/search_engine/indexer/bulk_import.rb +626 -0
- data/lib/search_engine/indexer/import_dispatcher.rb +198 -0
- data/lib/search_engine/indexer/retry_policy.rb +103 -0
- data/lib/search_engine/indexer.rb +747 -0
- data/lib/search_engine/instrumentation.rb +308 -0
- data/lib/search_engine/joins/guard.rb +202 -0
- data/lib/search_engine/joins/resolver.rb +95 -0
- data/lib/search_engine/logging/color.rb +78 -0
- data/lib/search_engine/logging/format_helpers.rb +92 -0
- data/lib/search_engine/logging/partition_progress.rb +53 -0
- data/lib/search_engine/logging_subscriber.rb +388 -0
- data/lib/search_engine/mapper.rb +785 -0
- data/lib/search_engine/multi.rb +286 -0
- data/lib/search_engine/multi_result.rb +186 -0
- data/lib/search_engine/notifications/compact_logger.rb +675 -0
- data/lib/search_engine/observability.rb +162 -0
- data/lib/search_engine/operations.rb +58 -0
- data/lib/search_engine/otel.rb +227 -0
- data/lib/search_engine/partitioner.rb +128 -0
- data/lib/search_engine/ranking_plan.rb +118 -0
- data/lib/search_engine/registry.rb +158 -0
- data/lib/search_engine/relation/compiler.rb +711 -0
- data/lib/search_engine/relation/deletion.rb +37 -0
- data/lib/search_engine/relation/dsl/filters.rb +624 -0
- data/lib/search_engine/relation/dsl/selection.rb +240 -0
- data/lib/search_engine/relation/dsl.rb +903 -0
- data/lib/search_engine/relation/dx/dry_run.rb +59 -0
- data/lib/search_engine/relation/dx/friendly_where.rb +24 -0
- data/lib/search_engine/relation/dx.rb +231 -0
- data/lib/search_engine/relation/materializers.rb +118 -0
- data/lib/search_engine/relation/options.rb +138 -0
- data/lib/search_engine/relation/state.rb +274 -0
- data/lib/search_engine/relation/updating.rb +44 -0
- data/lib/search_engine/relation.rb +623 -0
- data/lib/search_engine/result.rb +664 -0
- data/lib/search_engine/schema.rb +1083 -0
- data/lib/search_engine/sources/active_record_source.rb +185 -0
- data/lib/search_engine/sources/base.rb +62 -0
- data/lib/search_engine/sources/lambda_source.rb +55 -0
- data/lib/search_engine/sources/sql_source.rb +196 -0
- data/lib/search_engine/sources.rb +71 -0
- data/lib/search_engine/stale_rules.rb +160 -0
- data/lib/search_engine/test/minitest_assertions.rb +57 -0
- data/lib/search_engine/test/offline_client.rb +134 -0
- data/lib/search_engine/test/rspec_matchers.rb +77 -0
- data/lib/search_engine/test/stub_client.rb +201 -0
- data/lib/search_engine/test.rb +66 -0
- data/lib/search_engine/test_autoload.rb +8 -0
- data/lib/search_engine/update.rb +35 -0
- data/lib/search_engine/version.rb +7 -0
- data/lib/search_engine.rb +332 -0
- data/lib/tasks/search_engine.rake +501 -0
- data/lib/tasks/search_engine_doctor.rake +16 -0
- metadata +225 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchEngine
|
|
4
|
+
class Relation
|
|
5
|
+
# Canonical immutable state helpers and defaults for Relation.
|
|
6
|
+
# Owns deep-freeze and duplication utilities, plus initial state normalization.
|
|
7
|
+
module State
|
|
8
|
+
# Internal normalized state keys (authoritative defaults)
|
|
9
|
+
DEFAULT_STATE = {
|
|
10
|
+
filters: [].freeze,
|
|
11
|
+
ast: [].freeze,
|
|
12
|
+
orders: [].freeze,
|
|
13
|
+
select: [].freeze,
|
|
14
|
+
select_nested: {}.freeze,
|
|
15
|
+
select_nested_order: [].freeze,
|
|
16
|
+
exclude: [].freeze,
|
|
17
|
+
exclude_nested: {}.freeze,
|
|
18
|
+
exclude_nested_order: [].freeze,
|
|
19
|
+
joins: [].freeze,
|
|
20
|
+
limit: nil,
|
|
21
|
+
offset: nil,
|
|
22
|
+
page: nil,
|
|
23
|
+
per_page: nil,
|
|
24
|
+
grouping: nil,
|
|
25
|
+
options: {}.freeze,
|
|
26
|
+
preset_name: nil,
|
|
27
|
+
preset_mode: nil,
|
|
28
|
+
facet_fields: [].freeze,
|
|
29
|
+
facet_max_values: [].freeze,
|
|
30
|
+
facet_queries: [].freeze,
|
|
31
|
+
highlight: {}.freeze,
|
|
32
|
+
highlight_fields: [].freeze,
|
|
33
|
+
highlight_full_fields: [].freeze,
|
|
34
|
+
highlight_start_tag: nil,
|
|
35
|
+
highlight_end_tag: nil,
|
|
36
|
+
highlight_affix_num_tokens: nil,
|
|
37
|
+
highlight_snippet_threshold: nil,
|
|
38
|
+
use_synonyms: nil,
|
|
39
|
+
use_stopwords: nil,
|
|
40
|
+
ranking: nil,
|
|
41
|
+
hit_limits: {}.freeze
|
|
42
|
+
}.freeze
|
|
43
|
+
|
|
44
|
+
# Normalize the provided initial state Hash using the Relation's normalizers.
|
|
45
|
+
# @param state [Hash]
|
|
46
|
+
# @return [Hash]
|
|
47
|
+
def normalize_initial_state(state)
|
|
48
|
+
return {} if state.nil? || state.empty?
|
|
49
|
+
raise ArgumentError, 'state must be a Hash' unless state.is_a?(Hash)
|
|
50
|
+
|
|
51
|
+
normalized = {}
|
|
52
|
+
state.each { |key, value| apply_initial_state_key!(normalized, key, value) }
|
|
53
|
+
normalized
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Apply a single initial state key with normalization.
|
|
57
|
+
# Delegates to the same normalizers used by DSL chainers.
|
|
58
|
+
def apply_initial_state_key!(normalized, key, value)
|
|
59
|
+
handlers = {
|
|
60
|
+
filters: :handle_state_filters!,
|
|
61
|
+
filters_ast: :handle_state_filters_ast!,
|
|
62
|
+
ast: :handle_state_ast!,
|
|
63
|
+
orders: :handle_state_orders!,
|
|
64
|
+
select: :handle_state_select!,
|
|
65
|
+
select_nested: :handle_state_select_nested!,
|
|
66
|
+
select_nested_order: :handle_state_select_nested_order!,
|
|
67
|
+
exclude: :handle_state_exclude!,
|
|
68
|
+
exclude_nested: :handle_state_exclude_nested!,
|
|
69
|
+
exclude_nested_order: :handle_state_exclude_nested_order!,
|
|
70
|
+
joins: :handle_state_joins!,
|
|
71
|
+
limit: :handle_state_limit!,
|
|
72
|
+
offset: :handle_state_offset!,
|
|
73
|
+
page: :handle_state_page!,
|
|
74
|
+
per_page: :handle_state_per_page!,
|
|
75
|
+
options: :handle_state_options!,
|
|
76
|
+
grouping: :handle_state_grouping!,
|
|
77
|
+
preset_name: :handle_state_preset_name!,
|
|
78
|
+
preset_mode: :handle_state_preset_mode!,
|
|
79
|
+
curation: :handle_state_curation!,
|
|
80
|
+
facet_fields: :handle_state_facet_fields!,
|
|
81
|
+
facet_max_values: :handle_state_facet_max_values!,
|
|
82
|
+
facet_queries: :handle_state_facet_queries!,
|
|
83
|
+
highlight: :handle_state_highlight!,
|
|
84
|
+
ranking: :handle_state_ranking!,
|
|
85
|
+
hit_limits: :handle_state_hit_limits!
|
|
86
|
+
}
|
|
87
|
+
h = handlers[key.to_sym]
|
|
88
|
+
return unless h
|
|
89
|
+
|
|
90
|
+
send(h, normalized, value)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
private
|
|
94
|
+
|
|
95
|
+
def handle_state_filters!(normalized, value)
|
|
96
|
+
normalized[:filters] = normalize_where(Array(value))
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def handle_state_filters_ast!(normalized, value)
|
|
100
|
+
nodes = Array(value).flatten.compact
|
|
101
|
+
normalized[:ast] ||= []
|
|
102
|
+
normalized[:ast] += if nodes.all? { |n| n.is_a?(SearchEngine::AST::Node) }
|
|
103
|
+
nodes
|
|
104
|
+
else
|
|
105
|
+
SearchEngine::DSL::Parser.parse_list(nodes, klass: @klass)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def handle_state_ast!(normalized, value)
|
|
110
|
+
nodes = Array(value).flatten.compact
|
|
111
|
+
normalized[:ast] = if nodes.all? { |n| n.is_a?(SearchEngine::AST::Node) }
|
|
112
|
+
nodes
|
|
113
|
+
else
|
|
114
|
+
SearchEngine::DSL::Parser.parse_list(nodes, klass: @klass)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# One-time migration: when AST is empty and legacy string filters exist, map legacy to AST::Raw.
|
|
119
|
+
# Idempotent and safe for repeated calls.
|
|
120
|
+
# @param state [Hash]
|
|
121
|
+
# @return [void]
|
|
122
|
+
def migrate_legacy_filters_to_ast!(state)
|
|
123
|
+
return unless state.is_a?(Hash)
|
|
124
|
+
|
|
125
|
+
ast_nodes = Array(state[:ast]).flatten.compact
|
|
126
|
+
legacy = Array(state[:filters]).flatten.compact
|
|
127
|
+
return if !ast_nodes.empty? || legacy.empty?
|
|
128
|
+
|
|
129
|
+
raw_nodes = legacy.map { |fragment| SearchEngine::AST.raw(String(fragment)) }
|
|
130
|
+
state[:ast] = raw_nodes
|
|
131
|
+
nil
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def handle_state_options!(normalized, value)
|
|
135
|
+
normalized[:options] = (value || {}).dup
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def handle_state_grouping!(normalized, value)
|
|
139
|
+
normalized[:grouping] = normalize_grouping(value)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def handle_state_preset_name!(normalized, value)
|
|
143
|
+
normalized[:preset_name] = value&.to_s&.strip
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def handle_state_preset_mode!(normalized, value)
|
|
147
|
+
normalized[:preset_mode] = value&.to_sym
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def handle_state_curation!(normalized, value)
|
|
151
|
+
normalized[:curation] = normalize_curation_input(value)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def handle_state_facet_fields!(normalized, value)
|
|
155
|
+
normalized[:facet_fields] = Array(value).flatten.compact
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def handle_state_facet_max_values!(normalized, value)
|
|
159
|
+
normalized[:facet_max_values] = Array(value).flatten.compact
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def handle_state_facet_queries!(normalized, value)
|
|
163
|
+
normalized[:facet_queries] = Array(value).flatten.compact
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def handle_state_highlight!(normalized, value)
|
|
167
|
+
normalized[:highlight] = normalize_highlight_input(value)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def handle_state_ranking!(normalized, value)
|
|
171
|
+
normalized[:ranking] = normalize_ranking_input(value || {})
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def handle_state_hit_limits!(normalized, value)
|
|
175
|
+
normalized[:hit_limits] = normalize_hit_limits_input(value || {})
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Newly added handlers for remaining state keys
|
|
179
|
+
def handle_state_orders!(normalized, value)
|
|
180
|
+
additions = normalize_order(value)
|
|
181
|
+
normalized[:orders] = dedupe_orders_last_wins(additions)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def handle_state_select!(normalized, value)
|
|
185
|
+
normalized[:select] = normalize_select(value)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def handle_state_select_nested!(normalized, value)
|
|
189
|
+
nested_in = value || {}
|
|
190
|
+
nested = {}
|
|
191
|
+
nested_in.each do |k, v|
|
|
192
|
+
key = k.to_sym
|
|
193
|
+
fields = Array(v).flatten.compact
|
|
194
|
+
nested[key] = fields
|
|
195
|
+
end
|
|
196
|
+
normalized[:select_nested] = nested
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def handle_state_select_nested_order!(normalized, value)
|
|
200
|
+
normalized[:select_nested_order] = Array(value).flatten.compact.map(&:to_sym)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def handle_state_exclude!(normalized, value)
|
|
204
|
+
normalized[:exclude] = normalize_select(value)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def handle_state_exclude_nested!(normalized, value)
|
|
208
|
+
nested_in = value || {}
|
|
209
|
+
nested = {}
|
|
210
|
+
nested_in.each do |k, v|
|
|
211
|
+
key = k.to_sym
|
|
212
|
+
fields = Array(v).flatten.compact
|
|
213
|
+
nested[key] = fields
|
|
214
|
+
end
|
|
215
|
+
normalized[:exclude_nested] = nested
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def handle_state_exclude_nested_order!(normalized, value)
|
|
219
|
+
normalized[:exclude_nested_order] = Array(value).flatten.compact.map(&:to_sym)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def handle_state_joins!(normalized, value)
|
|
223
|
+
normalized[:joins] = normalize_joins(value)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def handle_state_limit!(normalized, value)
|
|
227
|
+
normalized[:limit] = coerce_integer_min(value, :limit, 1)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def handle_state_offset!(normalized, value)
|
|
231
|
+
normalized[:offset] = coerce_integer_min(value, :offset, 0)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def handle_state_page!(normalized, value)
|
|
235
|
+
normalized[:page] = coerce_integer_min(value, :page, 1)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def handle_state_per_page!(normalized, value)
|
|
239
|
+
normalized[:per_page] = coerce_integer_min(value, :per, 1)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Deep duplicate Hash/Array trees; leaves are returned as-is.
|
|
243
|
+
# @param obj [Object]
|
|
244
|
+
# @return [Object]
|
|
245
|
+
def deep_dup(obj)
|
|
246
|
+
case obj
|
|
247
|
+
when Hash
|
|
248
|
+
obj.transform_values(&method(:deep_dup))
|
|
249
|
+
when Array
|
|
250
|
+
obj.map(&method(:deep_dup))
|
|
251
|
+
else
|
|
252
|
+
obj
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Deep-freeze Hash/Array/String trees in-place; returns the frozen object.
|
|
257
|
+
# @param obj [Object]
|
|
258
|
+
# @return [Object]
|
|
259
|
+
def deep_freeze_inplace(obj)
|
|
260
|
+
case obj
|
|
261
|
+
when Hash
|
|
262
|
+
obj.each_value { |v| deep_freeze_inplace(v) }
|
|
263
|
+
obj.freeze
|
|
264
|
+
when Array
|
|
265
|
+
obj.each { |el| deep_freeze_inplace(el) }
|
|
266
|
+
obj.freeze
|
|
267
|
+
else
|
|
268
|
+
obj.freeze if obj.is_a?(String)
|
|
269
|
+
end
|
|
270
|
+
obj
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SearchEngine
|
|
4
|
+
class Relation
|
|
5
|
+
# Updating helpers bound to a relation instance.
|
|
6
|
+
#
|
|
7
|
+
# Provides `update_all` which updates documents that match the current
|
|
8
|
+
# relation predicates. When no predicates are present, it updates all
|
|
9
|
+
# documents from the collection by using a safe match-all filter.
|
|
10
|
+
module Updating
|
|
11
|
+
# Update all documents matching the current relation filters.
|
|
12
|
+
#
|
|
13
|
+
# When the relation has no filters, updates all documents from the
|
|
14
|
+
# collection using a safe match-all filter (`id:!=null`).
|
|
15
|
+
#
|
|
16
|
+
# @param attributes [Hash, nil] fields to update (or pass as kwargs)
|
|
17
|
+
# @param into [String, nil] override physical collection name
|
|
18
|
+
# @param partition [Object, nil] partition token for resolvers
|
|
19
|
+
# @param timeout_ms [Integer, nil] optional read timeout override in ms
|
|
20
|
+
# @return [Integer] number of updated documents
|
|
21
|
+
def update_all(attributes = nil, into: nil, partition: nil, timeout_ms: nil, **kwattrs)
|
|
22
|
+
attrs = if attributes.is_a?(Hash) && !attributes.empty?
|
|
23
|
+
attributes
|
|
24
|
+
elsif kwattrs && !kwattrs.empty?
|
|
25
|
+
kwattrs
|
|
26
|
+
end
|
|
27
|
+
raise ArgumentError, 'attributes must be a non-empty Hash' if attrs.nil? || attrs.empty?
|
|
28
|
+
|
|
29
|
+
ast_nodes = Array(@state[:ast]).flatten.compact
|
|
30
|
+
filter = compiled_filter_by(ast_nodes)
|
|
31
|
+
filter = 'id:!=null' if filter.to_s.strip.empty?
|
|
32
|
+
|
|
33
|
+
SearchEngine::Update.update_by(
|
|
34
|
+
klass: @klass,
|
|
35
|
+
attributes: attrs,
|
|
36
|
+
filter: filter,
|
|
37
|
+
into: into,
|
|
38
|
+
partition: partition,
|
|
39
|
+
timeout_ms: timeout_ms
|
|
40
|
+
)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|