caoutsearch 0.0.0 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|