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
@@ -28,7 +28,7 @@ module Caoutsearch
|
|
28
28
|
path = ::Rails.root.join("config/elasticsearch/#{index_name}.json")
|
29
29
|
raise ArgumentError, "No mappings file found for #{index_name} at #{path}" unless path.exist?
|
30
30
|
|
31
|
-
|
31
|
+
MultiJson.load(path.read)
|
32
32
|
end
|
33
33
|
|
34
34
|
def get_remote_mappings
|
@@ -5,11 +5,15 @@ module Caoutsearch
|
|
5
5
|
class Base
|
6
6
|
attr_reader :key, :original_value, :type, :options
|
7
7
|
|
8
|
+
def self.call(...)
|
9
|
+
new(...).as_json
|
10
|
+
end
|
11
|
+
|
8
12
|
def initialize(key, original_value, type, options = {})
|
9
|
-
@key
|
13
|
+
@key = key
|
10
14
|
@original_value = original_value
|
11
|
-
@type
|
12
|
-
@options
|
15
|
+
@type = type
|
16
|
+
@options = options
|
13
17
|
end
|
14
18
|
|
15
19
|
def value
|
@@ -25,7 +29,7 @@ module Caoutsearch
|
|
25
29
|
filter = {
|
26
30
|
nested: {
|
27
31
|
path: nested_path,
|
28
|
-
query: {
|
32
|
+
query: {bool: {filter: Array.wrap(filter)}}
|
29
33
|
}
|
30
34
|
}
|
31
35
|
end
|
@@ -54,7 +58,7 @@ module Caoutsearch
|
|
54
58
|
def original_values
|
55
59
|
case original_value
|
56
60
|
when String then original_value.split(",")
|
57
|
-
when Array
|
61
|
+
when Array then original_value
|
58
62
|
else Array.wrap(original_value)
|
59
63
|
end
|
60
64
|
end
|
@@ -72,9 +76,9 @@ module Caoutsearch
|
|
72
76
|
grouped_terms.each { |term| terms.delete(term) }
|
73
77
|
|
74
78
|
terms << if values.size == 1
|
75
|
-
{
|
79
|
+
{term: {key => values[0]}}
|
76
80
|
else
|
77
|
-
{
|
81
|
+
{terms: {key => values}}
|
78
82
|
end
|
79
83
|
end
|
80
84
|
|
@@ -4,45 +4,116 @@ module Caoutsearch
|
|
4
4
|
module Filter
|
5
5
|
class Date < Base
|
6
6
|
def filter
|
7
|
-
original_values.map do |
|
8
|
-
case
|
7
|
+
original_values.map do |input|
|
8
|
+
case input
|
9
9
|
when true
|
10
|
-
{
|
10
|
+
{exists: {field: key}}
|
11
11
|
when false
|
12
|
-
{
|
13
|
-
when
|
14
|
-
|
15
|
-
|
16
|
-
case
|
17
|
-
when
|
18
|
-
|
19
|
-
when
|
20
|
-
|
21
|
-
when
|
22
|
-
|
23
|
-
{ range: { key => { gte: dates[0], lt: dates[1] } } }
|
12
|
+
{bool: {must_not: {exists: {field: key}}}}
|
13
|
+
when ::Date
|
14
|
+
{range: {key => {gte: input.as_json, lte: input.as_json}}}
|
15
|
+
when ::String
|
16
|
+
case input
|
17
|
+
when /\A\.\.(.+)\Z/
|
18
|
+
build_range_query(..$1)
|
19
|
+
when /\A(.+)\.\.\Z/
|
20
|
+
build_range_query($1..)
|
21
|
+
when /\A(.+)\.\.(.+)\Z/
|
22
|
+
build_range_query($1..$2)
|
24
23
|
else
|
25
|
-
|
24
|
+
{range: {key => {gte: input, lte: input}}}
|
26
25
|
end
|
26
|
+
when ::Range, ::Array
|
27
|
+
build_range_query(input)
|
28
|
+
when ::Hash
|
29
|
+
case input
|
30
|
+
in { operator:, value:, **other}
|
31
|
+
build_legacy_range_query_from_hash(input)
|
32
|
+
in { between: dates }
|
33
|
+
build_range_query(dates)
|
34
|
+
else
|
35
|
+
parameters = input.to_h do |operator, value|
|
36
|
+
[cast_operator(operator), cast_value(value)]
|
37
|
+
end
|
38
|
+
|
39
|
+
{range: {key => parameters}}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def build_range_query(input)
|
46
|
+
lower_bound = input.is_a?(::Range) ? input.begin : input.first
|
47
|
+
upper_bound = input.is_a?(::Range) ? input.end : input.last
|
48
|
+
return unless upper_bound || lower_bound
|
49
|
+
|
50
|
+
query = {range: {key => {}}}
|
51
|
+
query[:range][key][:gte] = cast_value(lower_bound) if lower_bound
|
52
|
+
|
53
|
+
if upper_bound
|
54
|
+
if input.is_a?(::Range) && input.exclude_end?
|
55
|
+
query[:range][key][:lt] = cast_value(upper_bound)
|
56
|
+
else
|
57
|
+
query[:range][key][:lte] = cast_value(upper_bound)
|
27
58
|
end
|
28
59
|
end
|
60
|
+
|
61
|
+
query
|
62
|
+
end
|
63
|
+
|
64
|
+
def build_legacy_range_query_from_hash(input)
|
65
|
+
ActiveSupport::Deprecation.warn("This form of hash to search for dates will be removed")
|
66
|
+
operator, value, unit = input.values_at(:operator, :value, :unit)
|
67
|
+
|
68
|
+
case operator
|
69
|
+
when "less_than"
|
70
|
+
{range: {key => {gte: cast_date(value, unit)}}}
|
71
|
+
when "greater_than"
|
72
|
+
{range: {key => {lt: cast_date(value, unit)}}}
|
73
|
+
when "between"
|
74
|
+
dates = value.map { |v| cast_date(v, unit) }.sort
|
75
|
+
{range: {key => {gte: dates[0], lt: dates[1]}}}
|
76
|
+
else
|
77
|
+
raise ArgumentError, "unknown operator #{operator.inspect} in #{value.inspect}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
RANGE_OPERATORS = {
|
82
|
+
"less_than" => "lt",
|
83
|
+
"less_than_or_equal" => "lte",
|
84
|
+
"greater_than" => "gt",
|
85
|
+
"greater_than_or_equal" => "gte"
|
86
|
+
}.freeze
|
87
|
+
|
88
|
+
def cast_operator(original_operator)
|
89
|
+
operator = original_operator.to_s
|
90
|
+
return original_operator if RANGE_OPERATORS.value?(operator)
|
91
|
+
|
92
|
+
operator = RANGE_OPERATORS[operator]
|
93
|
+
if operator.nil?
|
94
|
+
raise ArgumentError, "unknown operator #{original_operator.inspect}"
|
95
|
+
elsif original_operator.is_a?(Symbol)
|
96
|
+
operator.to_sym
|
97
|
+
else
|
98
|
+
operator
|
99
|
+
end
|
29
100
|
end
|
30
101
|
|
31
102
|
def cast_date(value, unit)
|
32
103
|
if value.is_a?(Numeric) && unit
|
33
104
|
case unit
|
34
|
-
when "day"
|
35
|
-
when "week"
|
36
|
-
when "month"
|
37
|
-
when "year", nil
|
105
|
+
when "day" then value = value.days.ago.to_date
|
106
|
+
when "week" then value = value.weeks.ago.to_date
|
107
|
+
when "month" then value = value.months.ago.to_date
|
108
|
+
when "year", nil then value = value.years.ago.to_date
|
38
109
|
else
|
39
110
|
raise ArgumentError, "unknown unit #{unit.inspect} in #{value.inspect}"
|
40
111
|
end
|
41
112
|
elsif value.is_a?(ActiveSupport::Duration)
|
42
|
-
value = value.ago
|
113
|
+
value = value.ago.to_date
|
43
114
|
end
|
44
115
|
|
45
|
-
cast_value(value
|
116
|
+
cast_value(value)
|
46
117
|
end
|
47
118
|
end
|
48
119
|
end
|
@@ -8,42 +8,42 @@ module Caoutsearch
|
|
8
8
|
{
|
9
9
|
bool: {
|
10
10
|
should: [
|
11
|
-
{
|
12
|
-
{
|
11
|
+
{bool: {must_not: {exists: {field: key}}}},
|
12
|
+
{term: {key => ""}}
|
13
13
|
]
|
14
14
|
}
|
15
15
|
}
|
16
16
|
|
17
17
|
elsif value.nil?
|
18
|
-
{
|
18
|
+
{bool: {must_not: {exists: {field: key}}}}
|
19
19
|
|
20
20
|
elsif value.is_a?(Array) && value.any?(&:nil?)
|
21
21
|
terms = []
|
22
|
-
terms << {
|
22
|
+
terms << {bool: {must_not: {exists: {field: key}}}}
|
23
23
|
|
24
24
|
terms_values = value.compact
|
25
25
|
terms_values += [""] if %w[text keyword].include?(type)
|
26
26
|
|
27
27
|
if terms_values.size == 1
|
28
|
-
terms << {
|
28
|
+
terms << {term: {key => terms_values[0]}}
|
29
29
|
elsif terms_values.size > 1
|
30
|
-
terms << {
|
30
|
+
terms << {terms: {key => terms_values}}
|
31
31
|
end
|
32
32
|
|
33
33
|
if terms.size == 1
|
34
34
|
terms[0]
|
35
35
|
else
|
36
|
-
{
|
36
|
+
{bool: {should: terms}}
|
37
37
|
end
|
38
38
|
|
39
39
|
elsif value.is_a?(Array) && value.size == 1
|
40
|
-
{
|
40
|
+
{term: {key => value[0]}}
|
41
41
|
|
42
42
|
elsif value.is_a?(Array)
|
43
|
-
{
|
43
|
+
{terms: {key => value}}
|
44
44
|
|
45
45
|
else
|
46
|
-
{
|
46
|
+
{term: {key => value}}
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -6,17 +6,17 @@ module Caoutsearch
|
|
6
6
|
def filter
|
7
7
|
if use_query_string?
|
8
8
|
{
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
simple_query_string: {
|
10
|
+
fields: [key],
|
11
|
+
query: sanitized_for_query_string,
|
12
12
|
default_operator: "and",
|
13
13
|
analyze_wildcard: true
|
14
14
|
}
|
15
15
|
}
|
16
16
|
elsif multiple_words?
|
17
|
-
{
|
17
|
+
{match: {key => {query: value, operator: "and"}}}
|
18
18
|
else
|
19
|
-
{
|
19
|
+
{match: {key => value}}
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -6,12 +6,12 @@ module Caoutsearch
|
|
6
6
|
def filter
|
7
7
|
original_values.map do |value|
|
8
8
|
case value
|
9
|
-
when />(.+)/
|
10
|
-
when /<(.+)/
|
11
|
-
when /≥(.+)/
|
12
|
-
when /≤(.+)/
|
13
|
-
when /(.+)-(.+)/
|
14
|
-
else
|
9
|
+
when />(.+)/ then {range: {key => {gt: cast_value_with_overflow($1, :lower)}}}
|
10
|
+
when /<(.+)/ then {range: {key => {lt: cast_value_with_overflow($1, :upper)}}}
|
11
|
+
when /≥(.+)/ then {range: {key => {gte: cast_value_with_overflow($1, :lower)}}}
|
12
|
+
when /≤(.+)/ then {range: {key => {lte: cast_value_with_overflow($1, :upper)}}}
|
13
|
+
when /(.+)-(.+)/ then {range: {key => {gte: cast_value_with_overflow($1, :lower), lte: cast_value_with_overflow($2, :upper)}}}
|
14
|
+
else {term: {key => cast_value(value)}}
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -13,11 +13,11 @@ module Caoutsearch
|
|
13
13
|
def indexed_document
|
14
14
|
request_payload = {
|
15
15
|
index: index_name,
|
16
|
-
id:
|
16
|
+
id: record.id
|
17
17
|
}
|
18
18
|
|
19
19
|
response = instrument(:get) do |event_payload|
|
20
|
-
event_payload[:request]
|
20
|
+
event_payload[:request] = request_payload
|
21
21
|
event_payload[:response] = client.get(request_payload)
|
22
22
|
end
|
23
23
|
|
@@ -33,21 +33,21 @@ module Caoutsearch
|
|
33
33
|
def update_document(*keys, index: index_name, refresh: false)
|
34
34
|
request_payload = {
|
35
35
|
index: index,
|
36
|
-
id:
|
36
|
+
id: id
|
37
37
|
}
|
38
38
|
|
39
39
|
if keys.empty?
|
40
40
|
request_payload[:body] = as_json
|
41
41
|
|
42
42
|
instrument(:index) do |event_payload|
|
43
|
-
event_payload[:request]
|
43
|
+
event_payload[:request] = request_payload
|
44
44
|
event_payload[:response] = client.index(request_payload)
|
45
45
|
end
|
46
46
|
else
|
47
47
|
request_payload[:body] = bulkify(:update, keys)
|
48
48
|
|
49
49
|
instrument(:bulk, method: :update) do |event_payload|
|
50
|
-
event_payload[:request]
|
50
|
+
event_payload[:request] = request_payload
|
51
51
|
event_payload[:response] = client.bulk(request_payload)
|
52
52
|
end
|
53
53
|
end
|
@@ -71,13 +71,13 @@ module Caoutsearch
|
|
71
71
|
#
|
72
72
|
def delete_document(id, index: index_name, refresh: false)
|
73
73
|
request_payload = {
|
74
|
-
index:
|
75
|
-
id:
|
74
|
+
index: index,
|
75
|
+
id: id,
|
76
76
|
ignore: 404
|
77
77
|
}
|
78
78
|
|
79
79
|
instrument(:delete) do |event_payload|
|
80
|
-
event_payload[:request]
|
80
|
+
event_payload[:request] = request_payload
|
81
81
|
event_payload[:response] = client.delete(request_payload)
|
82
82
|
end
|
83
83
|
|
@@ -90,12 +90,12 @@ module Caoutsearch
|
|
90
90
|
#
|
91
91
|
def delete_documents(ids, index: index_name, refresh: false)
|
92
92
|
request_payload = {
|
93
|
-
index:
|
94
|
-
body:
|
93
|
+
index: index,
|
94
|
+
body: ids.map { |id| {delete: {_id: id}} }
|
95
95
|
}
|
96
96
|
|
97
97
|
instrument(:bulk, method: :delete) do |event_payload|
|
98
|
-
event_payload[:request]
|
98
|
+
event_payload[:request] = request_payload
|
99
99
|
event_payload[:response] = client.bulk(request_payload)
|
100
100
|
end
|
101
101
|
|
@@ -83,14 +83,14 @@ module Caoutsearch
|
|
83
83
|
version_name = last_indice_version if version_name == :__last__
|
84
84
|
|
85
85
|
actions = []
|
86
|
-
actions << {
|
86
|
+
actions << {add: {index: version_name, alias: index_name}}
|
87
87
|
|
88
88
|
aliased_indice_versions.each do |alias_name|
|
89
89
|
return false if alias_name == version_name
|
90
|
-
actions << {
|
90
|
+
actions << {remove: {index: alias_name, alias: index_name}}
|
91
91
|
end
|
92
92
|
|
93
|
-
client.indices.update_aliases(body: {
|
93
|
+
client.indices.update_aliases(body: {actions: actions})
|
94
94
|
refresh_indice
|
95
95
|
version_name
|
96
96
|
end
|
@@ -9,7 +9,7 @@ module Caoutsearch
|
|
9
9
|
# Be careful with these class attributes
|
10
10
|
# Always use `+=` or `.dup.merge` to assign a new copy
|
11
11
|
#
|
12
|
-
class_attribute :properties,
|
12
|
+
class_attribute :properties, instance_writer: false, default: []
|
13
13
|
class_attribute :partial_reindexations, instance_writer: false, default: {}
|
14
14
|
end
|
15
15
|
|
@@ -54,13 +54,13 @@ module Caoutsearch
|
|
54
54
|
raise ArgumentError, "The allow_partial_reindex body needs to be callable." if body && !body.respond_to?(:call)
|
55
55
|
|
56
56
|
name = name.to_s
|
57
|
-
self.partial_reindexations = partial_reindexations.dup.merge(name => {
|
57
|
+
self.partial_reindexations = partial_reindexations.dup.merge(name => {properties: properties})
|
58
58
|
|
59
59
|
if body
|
60
60
|
define_method(name, &body)
|
61
61
|
else
|
62
62
|
define_method(name) do
|
63
|
-
body = {
|
63
|
+
body = {doc: properties.index_with { |key| send(key) }}
|
64
64
|
body[:doc_as_upsert] = true if upsert
|
65
65
|
body
|
66
66
|
end
|
@@ -32,17 +32,17 @@ module Caoutsearch
|
|
32
32
|
records = apply_scopes(records, keys)
|
33
33
|
records = records.strict_loading
|
34
34
|
|
35
|
-
index
|
36
|
-
refresh
|
37
|
-
method
|
38
|
-
batch_size
|
39
|
-
total
|
40
|
-
progress
|
35
|
+
index = options.fetch(:index, index_name)
|
36
|
+
refresh = options.fetch(:refresh, false)
|
37
|
+
method = options.fetch(:method) { keys.present? ? :update : :index }
|
38
|
+
batch_size = options[:batch_size] || 100
|
39
|
+
total = options[:total] || records.count(:all)
|
40
|
+
progress = options[:progress]
|
41
41
|
current_progress = 0
|
42
42
|
|
43
43
|
return if total.zero?
|
44
44
|
|
45
|
-
progress&.total
|
45
|
+
progress&.total = total
|
46
46
|
progress&.progress = current_progress
|
47
47
|
|
48
48
|
finder = if total <= batch_size
|
@@ -53,13 +53,13 @@ module Caoutsearch
|
|
53
53
|
|
54
54
|
finder.each do |batch|
|
55
55
|
current_progress += batch.size
|
56
|
-
request_payload
|
57
|
-
index:
|
58
|
-
body:
|
56
|
+
request_payload = {
|
57
|
+
index: index,
|
58
|
+
body: bulkify(batch, method, keys)
|
59
59
|
}
|
60
60
|
|
61
61
|
instrument(:reindex, total: total, progress: current_progress, records: batch) do |event_payload|
|
62
|
-
event_payload[:request]
|
62
|
+
event_payload[:request] = request_payload
|
63
63
|
event_payload[:response] = client.bulk(request_payload)
|
64
64
|
end
|
65
65
|
|
@@ -6,7 +6,7 @@ module Caoutsearch
|
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
8
|
included do
|
9
|
-
class_attribute :scopes,
|
9
|
+
class_attribute :scopes, instance_accessor: false, default: {}
|
10
10
|
class_attribute :preloads, instance_accessor: false, default: {}
|
11
11
|
end
|
12
12
|
|
@@ -37,12 +37,12 @@ module Caoutsearch
|
|
37
37
|
names += %w[_default] # Use += instead of << to create a copy
|
38
38
|
|
39
39
|
names.each do |name|
|
40
|
-
if scopes.include?
|
41
|
-
scope
|
40
|
+
if scopes.include?(name)
|
41
|
+
scope = scopes[name]
|
42
42
|
records = scope.call(records)
|
43
43
|
elsif partial_reindexations.include?(name)
|
44
44
|
properties = partial_reindexations.dig(name, :properties)
|
45
|
-
records
|
45
|
+
records = apply_scopes(records, properties) if properties&.any?
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -5,10 +5,6 @@ module Caoutsearch
|
|
5
5
|
module Serialization
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
|
-
included do
|
9
|
-
delegate :to_json, to: :as_json
|
10
|
-
end
|
11
|
-
|
12
8
|
class_methods do
|
13
9
|
# Transform record or array of records to JSON:
|
14
10
|
#
|
@@ -60,6 +56,10 @@ module Caoutsearch
|
|
60
56
|
simplify(json)
|
61
57
|
end
|
62
58
|
|
59
|
+
def to_json(*)
|
60
|
+
MultiJson.dump(as_json)
|
61
|
+
end
|
62
|
+
|
63
63
|
# Recursive objects simplication:
|
64
64
|
#
|
65
65
|
# [nil, 'A', 'A', 'B'] => ['A', 'B']
|
@@ -90,30 +90,30 @@ module Caoutsearch
|
|
90
90
|
def bulkify(method, keys)
|
91
91
|
raise ArgumentError, "unknown method #{method}" unless %i[index update delete].include?(method)
|
92
92
|
|
93
|
-
keys
|
94
|
-
payload
|
93
|
+
keys = keys.map(&:to_s)
|
94
|
+
payload = []
|
95
95
|
property_keys, partial_keys = analyze_keys(keys)
|
96
96
|
|
97
97
|
case method
|
98
98
|
when :index
|
99
99
|
raise SerializationError, format("cannot serialize the following keys: %{keys}", keys: partial_keys.to_sentence) if partial_keys.any?
|
100
100
|
|
101
|
-
payload << {
|
101
|
+
payload << {index: {_id: record.id}}
|
102
102
|
payload << as_json(*keys)
|
103
103
|
|
104
104
|
when :update
|
105
105
|
if property_keys.any?
|
106
|
-
payload << {
|
107
|
-
payload << {
|
106
|
+
payload << {update: {_id: record.id}}
|
107
|
+
payload << {doc: as_json(*property_keys)}
|
108
108
|
end
|
109
109
|
|
110
110
|
partial_keys.each do |key|
|
111
|
-
payload << {
|
111
|
+
payload << {update: {_id: record.id}}
|
112
112
|
payload << as_json(*key)
|
113
113
|
end
|
114
114
|
|
115
115
|
when :delete
|
116
|
-
payload << {
|
116
|
+
payload << {update: {_id: record.id}}
|
117
117
|
end
|
118
118
|
|
119
119
|
payload
|
@@ -122,9 +122,9 @@ module Caoutsearch
|
|
122
122
|
private
|
123
123
|
|
124
124
|
def analyze_keys(keys)
|
125
|
-
partial_keys
|
125
|
+
partial_keys = partial_reindexations.keys & keys
|
126
126
|
property_keys = properties & keys
|
127
|
-
unknown_keys
|
127
|
+
unknown_keys = keys - property_keys - partial_keys
|
128
128
|
|
129
129
|
raise ArgumentError, format("unknown keys: %{keys}", keys: unknown_keys.to_sentence) if unknown_keys.any?
|
130
130
|
|
@@ -8,11 +8,11 @@ module Caoutsearch
|
|
8
8
|
def log_request(subject, event, format: nil)
|
9
9
|
return unless format
|
10
10
|
|
11
|
-
payload
|
12
|
-
request
|
11
|
+
payload = event.payload
|
12
|
+
request = payload[:request]
|
13
13
|
|
14
14
|
debug do
|
15
|
-
title
|
15
|
+
title = color("#{payload[:klass]} #{subject}", GREEN, true)
|
16
16
|
request_body = format_request_body(request, format: format)
|
17
17
|
|
18
18
|
message = " #{title} #{request_body}"
|
@@ -22,20 +22,20 @@ module Caoutsearch
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def log_response(subject, event, warn_errors: false)
|
25
|
-
payload
|
25
|
+
payload = event.payload
|
26
26
|
response = payload[:response]
|
27
27
|
return unless response
|
28
28
|
|
29
29
|
debug do
|
30
|
-
title
|
30
|
+
title = color("#{payload[:klass]} #{subject}", GREEN, true)
|
31
31
|
|
32
|
-
duration
|
32
|
+
duration = "#{event.duration.round(1)}ms"
|
33
33
|
duration += " / took #{response["took"]}ms" if response.key?("took")
|
34
|
-
duration
|
34
|
+
duration = color("(#{duration})", GREEN, true)
|
35
35
|
|
36
|
-
message
|
36
|
+
message = " #{title} #{duration}"
|
37
37
|
message += " got errors" if response["errors"]
|
38
|
-
message
|
38
|
+
message = yield(message, payload) if block_given?
|
39
39
|
|
40
40
|
message
|
41
41
|
end
|
@@ -53,16 +53,16 @@ module Caoutsearch
|
|
53
53
|
when "amazing_print", "awesome_print"
|
54
54
|
body.ai(limit: true, index: false)
|
55
55
|
when "full"
|
56
|
-
json =
|
56
|
+
json = MultiJson.dump(body)
|
57
57
|
color(json, BLUE, true)
|
58
58
|
when "truncated"
|
59
|
-
json =
|
59
|
+
json = MultiJson.dump(body).truncate(200, omission: "…}")
|
60
60
|
color(json, BLUE, true)
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
64
|
def inspect_json_size(json)
|
65
|
-
ApplicationController.helpers.number_to_human_size(
|
65
|
+
ApplicationController.helpers.number_to_human_size(MultiJson.dump(json).bytesize)
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|