elasticgraph-indexer 1.1.0 → 1.2.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '0308b6d8490bd282e073ec4ca59840aa95fb5fa0617aeeb0f6abf8c43d767a0b'
|
|
4
|
+
data.tar.gz: f8fa720ceb8cfed471671a155069dbddd9857ea91cd6a23af787ead0e7e221fc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 70d14ee0336b0d99c2c470b6acddd04e6d7c34d7ab664bea6bf9b87a1a140fa81826feca1d69f437105f833bed0a1ea069fe08b5841b524727cdfbc348851542
|
|
7
|
+
data.tar.gz: eec5e893caf16c8bcb888f2bba16122f45b52a006b3350032a33598d42f8384b5cf683a79d0e88d7481b2efb27cbf341b4c12f17fc4843e392ef874803aeef81
|
|
@@ -10,6 +10,7 @@ require "elastic_graph/constants"
|
|
|
10
10
|
require "elastic_graph/errors"
|
|
11
11
|
require "elastic_graph/indexer/event_id"
|
|
12
12
|
require "elastic_graph/indexer/indexing_failures_error"
|
|
13
|
+
require "elastic_graph/support/opaque_id"
|
|
13
14
|
require "elastic_graph/support/threading"
|
|
14
15
|
|
|
15
16
|
module ElasticGraph
|
|
@@ -188,7 +189,14 @@ module ElasticGraph
|
|
|
188
189
|
]
|
|
189
190
|
end
|
|
190
191
|
|
|
191
|
-
|
|
192
|
+
headers = {
|
|
193
|
+
OPAQUE_ID_HEADER => Support::OpaqueID.build_header(opaque_id_parts_for_source_event_versions(ops))
|
|
194
|
+
}.compact # : ::Hash[::String, ::String]
|
|
195
|
+
|
|
196
|
+
client.msearch(
|
|
197
|
+
body: body,
|
|
198
|
+
headers: headers
|
|
199
|
+
)
|
|
192
200
|
else
|
|
193
201
|
# The named client doesn't exist, so we don't have any versions for the docs.
|
|
194
202
|
{"responses" => ops.map { |op| {"hits" => {"hits" => _ = []}} }}
|
|
@@ -256,6 +264,22 @@ module ElasticGraph
|
|
|
256
264
|
"for document versions:\n\n#{failures.join("\n")}"
|
|
257
265
|
end
|
|
258
266
|
end
|
|
267
|
+
|
|
268
|
+
private
|
|
269
|
+
|
|
270
|
+
def opaque_id_parts_for_source_event_versions(operations)
|
|
271
|
+
type_counts = operations
|
|
272
|
+
.group_by { |op| op.event.fetch("type") }
|
|
273
|
+
.sort_by(&:first)
|
|
274
|
+
.map { |type_name, ops| "#{type_name}:#{ops.size}" }
|
|
275
|
+
|
|
276
|
+
[
|
|
277
|
+
"elasticgraph-indexer",
|
|
278
|
+
"purpose=source_event_versions",
|
|
279
|
+
"operation_count=#{operations.size}",
|
|
280
|
+
"type_counts=#{type_counts.join(",")}"
|
|
281
|
+
]
|
|
282
|
+
end
|
|
259
283
|
end
|
|
260
284
|
end
|
|
261
285
|
end
|
|
@@ -27,7 +27,11 @@ module ElasticGraph
|
|
|
27
27
|
update_target:,
|
|
28
28
|
destination_index_mapping:
|
|
29
29
|
)
|
|
30
|
-
prepared_record = record_preparer.prepare_for_index(
|
|
30
|
+
prepared_record = record_preparer.prepare_for_index(
|
|
31
|
+
event["type"],
|
|
32
|
+
event["record"] || {"id" => event["id"]},
|
|
33
|
+
destination_index_mapping.fetch("properties")
|
|
34
|
+
)
|
|
31
35
|
|
|
32
36
|
Support::HashUtil
|
|
33
37
|
.fetch_leaf_values_at_path(prepared_record, update_target.id_source.split("."))
|
|
@@ -50,10 +50,6 @@ module ElasticGraph
|
|
|
50
50
|
{} # : ::Hash[::String, untyped]
|
|
51
51
|
end # : ::Hash[::String, untyped]
|
|
52
52
|
|
|
53
|
-
required_fields = type_def.fetch("required") do
|
|
54
|
-
[] # : ::Array[::String]
|
|
55
|
-
end # : ::Array[::String]
|
|
56
|
-
|
|
57
53
|
eg_meta_by_field_name = properties.filter_map do |prop_name, prop|
|
|
58
54
|
eg_meta = prop["ElasticGraph"]
|
|
59
55
|
[prop_name, eg_meta] if eg_meta
|
|
@@ -61,7 +57,6 @@ module ElasticGraph
|
|
|
61
57
|
|
|
62
58
|
TypeMetadata.new(
|
|
63
59
|
name: type,
|
|
64
|
-
requires_typename: required_fields.include?("__typename"),
|
|
65
60
|
eg_meta_by_field_name: eg_meta_by_field_name
|
|
66
61
|
)
|
|
67
62
|
end
|
|
@@ -76,8 +71,8 @@ module ElasticGraph
|
|
|
76
71
|
# still build operations for it, and the operations require a `RecordPreparer`, but we do
|
|
77
72
|
# not send them to the datastore.
|
|
78
73
|
module Identity
|
|
79
|
-
def self.prepare_for_index(type_name,
|
|
80
|
-
|
|
74
|
+
def self.prepare_for_index(type_name, value, mapping_properties)
|
|
75
|
+
value
|
|
81
76
|
end
|
|
82
77
|
end
|
|
83
78
|
|
|
@@ -86,10 +81,6 @@ module ElasticGraph
|
|
|
86
81
|
@eg_meta_by_field_name_by_concrete_type = type_metas.to_h do |meta|
|
|
87
82
|
[meta.name, meta.eg_meta_by_field_name]
|
|
88
83
|
end
|
|
89
|
-
|
|
90
|
-
@types_requiring_typename = type_metas.filter_map do |meta|
|
|
91
|
-
meta.name if meta.requires_typename
|
|
92
|
-
end.to_set
|
|
93
84
|
end
|
|
94
85
|
|
|
95
86
|
# Prepares the given payload for being indexed into the named index.
|
|
@@ -104,27 +95,21 @@ module ElasticGraph
|
|
|
104
95
|
# the set union of fields and this will take care of dropping any unsupported
|
|
105
96
|
# fields before we attempt to index the record.
|
|
106
97
|
#
|
|
107
|
-
# Note: this method does not mutate the given `
|
|
98
|
+
# Note: this method does not mutate the given `value`. Instead it returns a
|
|
108
99
|
# copy with any updates applied to it.
|
|
109
|
-
def prepare_for_index(type_name,
|
|
110
|
-
prepare_value_for_indexing(record, type_name)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
private
|
|
114
|
-
|
|
115
|
-
def prepare_value_for_indexing(value, type_name)
|
|
100
|
+
def prepare_for_index(type_name, value, mapping_properties)
|
|
116
101
|
type_name = type_name.delete_suffix("!")
|
|
117
102
|
|
|
118
|
-
return nil if value.nil?
|
|
103
|
+
return (_ = nil) if value.nil? # Steep 2.0 narrows to nil here but can't see it satisfies T
|
|
119
104
|
|
|
120
105
|
if (preparer = @indexing_preparer_by_scalar_type_name[type_name])
|
|
121
106
|
return (_ = preparer).prepare_for_indexing(value)
|
|
122
107
|
end
|
|
123
108
|
|
|
124
|
-
case value
|
|
109
|
+
_ = case value # Steep 2.0 can't narrow generic T through case/when branches
|
|
125
110
|
when ::Array
|
|
126
111
|
element_type_name = type_name.delete_prefix("[").delete_suffix("]")
|
|
127
|
-
value.map { |v|
|
|
112
|
+
value.map { |v| prepare_for_index(element_type_name, v, mapping_properties) }
|
|
128
113
|
when ::Hash
|
|
129
114
|
# `@eg_meta_by_field_name_by_concrete_type` does not have abstract types in it (e.g. type unions).
|
|
130
115
|
# Instead, it'll have each concrete subtype in it.
|
|
@@ -133,15 +118,30 @@ module ElasticGraph
|
|
|
133
118
|
# what the concrete subtype is. `__typename` is required on abstract types and indicates that.
|
|
134
119
|
eg_meta_by_field_name = @eg_meta_by_field_name_by_concrete_type.fetch(value["__typename"] || type_name)
|
|
135
120
|
|
|
136
|
-
|
|
121
|
+
# We only want to consider __typename if it's in the per-record mapping in order to determine
|
|
122
|
+
# whether __typename is required on records. When it's a constant_keyword it exists at the index
|
|
123
|
+
# level and therefore should be ignored for this purpose.
|
|
124
|
+
typename_type = mapping_properties&.dig("__typename", "type")
|
|
125
|
+
typename_in_record_mapping = typename_type && typename_type != "constant_keyword"
|
|
126
|
+
|
|
127
|
+
prepared_fields = value.filter_map do |field_name, field_value|
|
|
137
128
|
if field_name == "__typename"
|
|
138
|
-
#
|
|
139
|
-
|
|
140
|
-
[field_name, field_value] if @types_requiring_typename.include?(type_name)
|
|
129
|
+
# Only include __typename if the index mapping has it at this position.
|
|
130
|
+
[field_name, field_value] if typename_in_record_mapping
|
|
141
131
|
elsif (eg_meta = eg_meta_by_field_name[field_name])
|
|
142
|
-
|
|
132
|
+
name_in_index = eg_meta.fetch("nameInIndex")
|
|
133
|
+
nested_mapping_properties = mapping_properties&.dig(name_in_index, "properties")
|
|
134
|
+
[name_in_index, prepare_for_index(eg_meta.fetch("type"), field_value, nested_mapping_properties)]
|
|
143
135
|
end
|
|
144
136
|
end.to_h
|
|
137
|
+
|
|
138
|
+
# Inject __typename if the mapping requires it but it's absent from the record
|
|
139
|
+
# (e.g. for a concrete type indexed in a mixed-type index).
|
|
140
|
+
if typename_in_record_mapping && !value.key?("__typename")
|
|
141
|
+
prepared_fields["__typename"] = type_name
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
prepared_fields
|
|
145
145
|
else
|
|
146
146
|
# We won't have a registered preparer for enum types, since those aren't dumped in
|
|
147
147
|
# runtime metadata `scalar_types_by_name`, and we can just return the value as-is in
|
|
@@ -153,8 +153,6 @@ module ElasticGraph
|
|
|
153
153
|
TypeMetadata = ::Data.define(
|
|
154
154
|
# The name of the type this metadata object is for.
|
|
155
155
|
:name,
|
|
156
|
-
# Indicates if this type requires a `__typename` field.
|
|
157
|
-
:requires_typename,
|
|
158
156
|
# The per-field ElasticGraph metadata, keyed by field name.
|
|
159
157
|
:eg_meta_by_field_name
|
|
160
158
|
)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: elasticgraph-indexer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Myron Marston
|
|
@@ -17,42 +17,42 @@ dependencies:
|
|
|
17
17
|
requirements:
|
|
18
18
|
- - '='
|
|
19
19
|
- !ruby/object:Gem::Version
|
|
20
|
-
version: 1.
|
|
20
|
+
version: 1.2.0
|
|
21
21
|
type: :runtime
|
|
22
22
|
prerelease: false
|
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
24
24
|
requirements:
|
|
25
25
|
- - '='
|
|
26
26
|
- !ruby/object:Gem::Version
|
|
27
|
-
version: 1.
|
|
27
|
+
version: 1.2.0
|
|
28
28
|
- !ruby/object:Gem::Dependency
|
|
29
29
|
name: elasticgraph-schema_artifacts
|
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
|
31
31
|
requirements:
|
|
32
32
|
- - '='
|
|
33
33
|
- !ruby/object:Gem::Version
|
|
34
|
-
version: 1.
|
|
34
|
+
version: 1.2.0
|
|
35
35
|
type: :runtime
|
|
36
36
|
prerelease: false
|
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
|
38
38
|
requirements:
|
|
39
39
|
- - '='
|
|
40
40
|
- !ruby/object:Gem::Version
|
|
41
|
-
version: 1.
|
|
41
|
+
version: 1.2.0
|
|
42
42
|
- !ruby/object:Gem::Dependency
|
|
43
43
|
name: elasticgraph-support
|
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
|
45
45
|
requirements:
|
|
46
46
|
- - '='
|
|
47
47
|
- !ruby/object:Gem::Version
|
|
48
|
-
version: 1.
|
|
48
|
+
version: 1.2.0
|
|
49
49
|
type: :runtime
|
|
50
50
|
prerelease: false
|
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
|
52
52
|
requirements:
|
|
53
53
|
- - '='
|
|
54
54
|
- !ruby/object:Gem::Version
|
|
55
|
-
version: 1.
|
|
55
|
+
version: 1.2.0
|
|
56
56
|
- !ruby/object:Gem::Dependency
|
|
57
57
|
name: hashdiff
|
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -79,56 +79,56 @@ dependencies:
|
|
|
79
79
|
requirements:
|
|
80
80
|
- - '='
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: 1.
|
|
82
|
+
version: 1.2.0
|
|
83
83
|
type: :development
|
|
84
84
|
prerelease: false
|
|
85
85
|
version_requirements: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
87
|
- - '='
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: 1.
|
|
89
|
+
version: 1.2.0
|
|
90
90
|
- !ruby/object:Gem::Dependency
|
|
91
91
|
name: elasticgraph-elasticsearch
|
|
92
92
|
requirement: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
94
|
- - '='
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: 1.
|
|
96
|
+
version: 1.2.0
|
|
97
97
|
type: :development
|
|
98
98
|
prerelease: false
|
|
99
99
|
version_requirements: !ruby/object:Gem::Requirement
|
|
100
100
|
requirements:
|
|
101
101
|
- - '='
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: 1.
|
|
103
|
+
version: 1.2.0
|
|
104
104
|
- !ruby/object:Gem::Dependency
|
|
105
105
|
name: elasticgraph-opensearch
|
|
106
106
|
requirement: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
108
|
- - '='
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: 1.
|
|
110
|
+
version: 1.2.0
|
|
111
111
|
type: :development
|
|
112
112
|
prerelease: false
|
|
113
113
|
version_requirements: !ruby/object:Gem::Requirement
|
|
114
114
|
requirements:
|
|
115
115
|
- - '='
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: 1.
|
|
117
|
+
version: 1.2.0
|
|
118
118
|
- !ruby/object:Gem::Dependency
|
|
119
119
|
name: elasticgraph-schema_definition
|
|
120
120
|
requirement: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements:
|
|
122
122
|
- - '='
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: 1.
|
|
124
|
+
version: 1.2.0
|
|
125
125
|
type: :development
|
|
126
126
|
prerelease: false
|
|
127
127
|
version_requirements: !ruby/object:Gem::Requirement
|
|
128
128
|
requirements:
|
|
129
129
|
- - '='
|
|
130
130
|
- !ruby/object:Gem::Version
|
|
131
|
-
version: 1.
|
|
131
|
+
version: 1.2.0
|
|
132
132
|
email:
|
|
133
133
|
- myron@squareup.com
|
|
134
134
|
executables: []
|
|
@@ -161,10 +161,10 @@ licenses:
|
|
|
161
161
|
- MIT
|
|
162
162
|
metadata:
|
|
163
163
|
bug_tracker_uri: https://github.com/block/elasticgraph/issues
|
|
164
|
-
changelog_uri: https://github.com/block/elasticgraph/releases/tag/v1.
|
|
165
|
-
documentation_uri: https://block.github.io/elasticgraph/api-docs/v1.
|
|
164
|
+
changelog_uri: https://github.com/block/elasticgraph/releases/tag/v1.2.0
|
|
165
|
+
documentation_uri: https://block.github.io/elasticgraph/api-docs/v1.2.0/
|
|
166
166
|
homepage_uri: https://block.github.io/elasticgraph/
|
|
167
|
-
source_code_uri: https://github.com/block/elasticgraph/tree/v1.
|
|
167
|
+
source_code_uri: https://github.com/block/elasticgraph/tree/v1.2.0/elasticgraph-indexer
|
|
168
168
|
gem_category: core
|
|
169
169
|
rdoc_options: []
|
|
170
170
|
require_paths:
|
|
@@ -183,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
183
183
|
- !ruby/object:Gem::Version
|
|
184
184
|
version: '0'
|
|
185
185
|
requirements: []
|
|
186
|
-
rubygems_version: 4.0.
|
|
186
|
+
rubygems_version: 4.0.6
|
|
187
187
|
specification_version: 4
|
|
188
188
|
summary: Indexes ElasticGraph data into a datastore.
|
|
189
189
|
test_files: []
|