elasticgraph-schema_definition 0.19.3.0 → 1.0.0.rc1
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/lib/elastic_graph/schema_definition/api.rb +4 -11
- data/lib/elastic_graph/schema_definition/factory.rb +18 -4
- data/lib/elastic_graph/schema_definition/mixins/has_indices.rb +3 -16
- data/lib/elastic_graph/schema_definition/mixins/has_type_info.rb +1 -1
- data/lib/elastic_graph/schema_definition/mixins/supports_filtering_and_aggregation.rb +22 -7
- data/lib/elastic_graph/schema_definition/results.rb +4 -4
- data/lib/elastic_graph/schema_definition/schema_elements/built_in_types.rb +107 -107
- data/lib/elastic_graph/schema_definition/schema_elements/field.rb +99 -130
- data/lib/elastic_graph/schema_definition/schema_elements/scalar_type.rb +19 -1
- data/lib/elastic_graph/schema_definition/schema_elements/type_namer.rb +1 -0
- data/lib/elastic_graph/schema_definition/schema_elements/type_reference.rb +1 -0
- data/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb +6 -26
- data/lib/elastic_graph/schema_definition/scripting/scripts/update/index_data.painless +2 -22
- metadata +29 -29
@@ -8,7 +8,6 @@
|
|
8
8
|
|
9
9
|
require "delegate"
|
10
10
|
require "elastic_graph/constants"
|
11
|
-
require "elastic_graph/schema_artifacts/runtime_metadata/configured_graphql_resolver"
|
12
11
|
require "elastic_graph/schema_definition/indexing/field"
|
13
12
|
require "elastic_graph/schema_definition/indexing/field_reference"
|
14
13
|
require "elastic_graph/schema_definition/mixins/has_directives"
|
@@ -53,6 +52,8 @@ module ElasticGraph
|
|
53
52
|
# @private
|
54
53
|
# @!attribute [rw] grouped_by_customizations
|
55
54
|
# @private
|
55
|
+
# @!attribute [rw] highlights_customizations
|
56
|
+
# @private
|
56
57
|
# @!attribute [rw] sub_aggregations_customizations
|
57
58
|
# @private
|
58
59
|
# @!attribute [rw] aggregated_values_customizations
|
@@ -69,6 +70,8 @@ module ElasticGraph
|
|
69
70
|
# @private
|
70
71
|
# @!attribute [rw] groupable
|
71
72
|
# @private
|
73
|
+
# @!attribute [rw] highlightable
|
74
|
+
# @private
|
72
75
|
# @!attribute [rw] source
|
73
76
|
# @private
|
74
77
|
# @!attribute [rw] runtime_field_script
|
@@ -83,15 +86,14 @@ module ElasticGraph
|
|
83
86
|
# @private
|
84
87
|
# @!attribute [rw] as_input
|
85
88
|
# @private
|
86
|
-
# @!attribute [rw] legacy_grouping_schema
|
87
|
-
# @private
|
88
89
|
class Field < Struct.new(
|
89
90
|
:name, :original_type, :parent_type, :original_type_for_derived_types, :schema_def_state, :accuracy_confidence,
|
90
|
-
:filter_customizations, :grouped_by_customizations, :sub_aggregations_customizations,
|
91
|
-
:aggregated_values_customizations, :sort_order_enum_value_customizations,
|
92
|
-
:
|
91
|
+
:filter_customizations, :grouped_by_customizations, :highlights_customizations, :sub_aggregations_customizations,
|
92
|
+
:aggregated_values_customizations, :sort_order_enum_value_customizations, :args,
|
93
|
+
:sortable, :filterable, :aggregatable, :groupable, :highlightable,
|
94
|
+
:graphql_only, :source, :runtime_field_script, :relationship, :singular_name,
|
93
95
|
:computation_detail, :non_nullable_in_json_schema, :as_input,
|
94
|
-
:
|
96
|
+
:name_in_index, :resolver
|
95
97
|
)
|
96
98
|
include Mixins::HasDocumentation
|
97
99
|
include Mixins::HasDirectives
|
@@ -103,8 +105,8 @@ module ElasticGraph
|
|
103
105
|
name:, type:, parent_type:, schema_def_state:,
|
104
106
|
accuracy_confidence: :high, name_in_index: name,
|
105
107
|
type_for_derived_types: nil, graphql_only: nil, singular: nil,
|
106
|
-
sortable: nil, filterable: nil, aggregatable: nil, groupable: nil,
|
107
|
-
as_input: false,
|
108
|
+
sortable: nil, filterable: nil, aggregatable: nil, groupable: nil, highlightable: nil,
|
109
|
+
as_input: false, resolver: nil
|
108
110
|
)
|
109
111
|
type_ref = schema_def_state.type_ref(type)
|
110
112
|
super(
|
@@ -116,6 +118,7 @@ module ElasticGraph
|
|
116
118
|
accuracy_confidence: accuracy_confidence,
|
117
119
|
filter_customizations: [],
|
118
120
|
grouped_by_customizations: [],
|
121
|
+
highlights_customizations: [],
|
119
122
|
sub_aggregations_customizations: [],
|
120
123
|
aggregated_values_customizations: [],
|
121
124
|
sort_order_enum_value_customizations: [],
|
@@ -124,6 +127,7 @@ module ElasticGraph
|
|
124
127
|
filterable: filterable,
|
125
128
|
aggregatable: aggregatable,
|
126
129
|
groupable: groupable,
|
130
|
+
highlightable: highlightable,
|
127
131
|
graphql_only: graphql_only,
|
128
132
|
source: nil,
|
129
133
|
runtime_field_script: nil,
|
@@ -134,32 +138,17 @@ module ElasticGraph
|
|
134
138
|
name_in_index: name_in_index,
|
135
139
|
non_nullable_in_json_schema: false,
|
136
140
|
as_input: as_input,
|
137
|
-
legacy_grouping_schema: legacy_grouping_schema,
|
138
141
|
resolver: resolver
|
139
142
|
)
|
140
143
|
|
141
|
-
if name != name_in_index
|
142
|
-
|
143
|
-
schema_def_state.after_user_definition_complete do
|
144
|
-
unless backing_indexing_field
|
145
|
-
raise Errors::SchemaError,
|
146
|
-
"GraphQL-only field `#{parent_type.name}.#{name}` has a `name_in_index` (#{name_in_index}) which does not reference an " \
|
147
|
-
"existing indexing field. To proceed, remove `graphql_only: true` or update `name_in_index` to match an existing indexing field."
|
148
|
-
end
|
149
|
-
end
|
150
|
-
elsif name_in_index.include?(".")
|
151
|
-
raise Errors::SchemaError,
|
152
|
-
"#{self} has an invalid `name_in_index`: #{name_in_index.inspect}. " \
|
153
|
-
"Only `graphql_only: true` fields can have a `name_in_index` that references a child field."
|
154
|
-
end
|
144
|
+
if name != name_in_index && name_in_index.include?(".") && !graphql_only
|
145
|
+
raise Errors::SchemaError, "#{self} has an invalid `name_in_index`: #{name_in_index.inspect}. Only `graphql_only: true` fields can have a `name_in_index` that references a child field."
|
155
146
|
end
|
156
147
|
|
157
148
|
schema_def_state.register_user_defined_field(self)
|
158
149
|
yield self if block_given?
|
159
150
|
end
|
160
151
|
|
161
|
-
private :resolver=
|
162
|
-
|
163
152
|
# @private
|
164
153
|
@@initialize_param_names = instance_method(:initialize).parameters.map(&:last).to_set
|
165
154
|
|
@@ -191,6 +180,7 @@ module ElasticGraph
|
|
191
180
|
# @return [void]
|
192
181
|
# @see #customize_aggregated_values_field
|
193
182
|
# @see #customize_grouped_by_field
|
183
|
+
# @see #customize_highlights_field
|
194
184
|
# @see #customize_sort_order_enum_values
|
195
185
|
# @see #customize_sub_aggregations_field
|
196
186
|
# @see #on_each_generated_schema_element
|
@@ -223,6 +213,7 @@ module ElasticGraph
|
|
223
213
|
# @return [void]
|
224
214
|
# @see #customize_filter_field
|
225
215
|
# @see #customize_grouped_by_field
|
216
|
+
# @see #customize_highlights_field
|
226
217
|
# @see #customize_sort_order_enum_values
|
227
218
|
# @see #customize_sub_aggregations_field
|
228
219
|
# @see #on_each_generated_schema_element
|
@@ -255,6 +246,7 @@ module ElasticGraph
|
|
255
246
|
# @return [void]
|
256
247
|
# @see #customize_aggregated_values_field
|
257
248
|
# @see #customize_filter_field
|
249
|
+
# @see #customize_highlights_field
|
258
250
|
# @see #customize_sort_order_enum_values
|
259
251
|
# @see #customize_sub_aggregations_field
|
260
252
|
# @see #on_each_generated_schema_element
|
@@ -277,6 +269,39 @@ module ElasticGraph
|
|
277
269
|
grouped_by_customizations << customization_block
|
278
270
|
end
|
279
271
|
|
272
|
+
# @note For each field defined in your schema that is highlightable, a corresponding highlights field will be created on the
|
273
|
+
# `*Highlights` type derived from the parent object type.
|
274
|
+
#
|
275
|
+
# Registers a customization callback that will be applied to the corresponding highlights field that will be generated for this
|
276
|
+
# field.
|
277
|
+
#
|
278
|
+
# @yield [Field] derived highlights field
|
279
|
+
# @return [void]
|
280
|
+
# @see #customize_aggregated_values_field
|
281
|
+
# @see #customize_filter_field
|
282
|
+
# @see #customize_grouped_by_field
|
283
|
+
# @see #customize_sort_order_enum_values
|
284
|
+
# @see #customize_sub_aggregations_field
|
285
|
+
# @see #on_each_generated_schema_element
|
286
|
+
#
|
287
|
+
# @example Mark `CampaignHighlights.organizationId` with `@deprecated`
|
288
|
+
# ElasticGraph.define_schema do |schema|
|
289
|
+
# schema.object_type "Campaign" do |t|
|
290
|
+
# t.field "id", "ID"
|
291
|
+
#
|
292
|
+
# t.field "organizationId", "ID" do |f|
|
293
|
+
# f.customize_highlights_field do |gbf|
|
294
|
+
# gbf.directive "deprecated"
|
295
|
+
# end
|
296
|
+
# end
|
297
|
+
#
|
298
|
+
# t.index "campaigns"
|
299
|
+
# end
|
300
|
+
# end
|
301
|
+
def customize_highlights_field(&customization_block)
|
302
|
+
highlights_customizations << customization_block
|
303
|
+
end
|
304
|
+
|
280
305
|
# @note For each field defined in your schema that is sub-aggregatable (e.g. list fields indexed using the `nested` mapping type),
|
281
306
|
# a corresponding field will be created on the `*AggregationSubAggregations` type derived from the parent object type.
|
282
307
|
#
|
@@ -288,6 +313,7 @@ module ElasticGraph
|
|
288
313
|
# @see #customize_aggregated_values_field
|
289
314
|
# @see #customize_filter_field
|
290
315
|
# @see #customize_grouped_by_field
|
316
|
+
# @see #customize_highlights_field
|
291
317
|
# @see #customize_sort_order_enum_values
|
292
318
|
# @see #on_each_generated_schema_element
|
293
319
|
#
|
@@ -329,6 +355,7 @@ module ElasticGraph
|
|
329
355
|
# @see #customize_aggregated_values_field
|
330
356
|
# @see #customize_filter_field
|
331
357
|
# @see #customize_grouped_by_field
|
358
|
+
# @see #customize_highlights_field
|
332
359
|
# @see #customize_sub_aggregations_field
|
333
360
|
# @see #on_each_generated_schema_element
|
334
361
|
#
|
@@ -357,6 +384,8 @@ module ElasticGraph
|
|
357
384
|
# ask for values for the field in a response.
|
358
385
|
# * A {Field} may be generated on the `*FilterInput` {InputType} derived from the parent {ObjectType} or {InterfaceType}. This is
|
359
386
|
# used by clients to specify how the query should filter.
|
387
|
+
# * A {Field} may be generated on the `*Highlights` {ObjectType} derived from the parent {ObjectType} or {InterfaceType}. This is
|
388
|
+
# used by clients to request search highlights for a field.
|
360
389
|
# * A {Field} may be generated on the `*AggregationGroupedBy` {ObjectType} derived from the parent {ObjectType} or {InterfaceType}.
|
361
390
|
# This is used by clients to specify how aggregations should be grouped.
|
362
391
|
# * A {Field} may be generated on the `*AggregatedValues` {ObjectType} derived from the parent {ObjectType} or {InterfaceType}.
|
@@ -373,6 +402,7 @@ module ElasticGraph
|
|
373
402
|
# @see #customize_aggregated_values_field
|
374
403
|
# @see #customize_filter_field
|
375
404
|
# @see #customize_grouped_by_field
|
405
|
+
# @see #customize_highlights_field
|
376
406
|
# @see #customize_sort_order_enum_values
|
377
407
|
# @see #customize_sub_aggregations_field
|
378
408
|
#
|
@@ -381,15 +411,16 @@ module ElasticGraph
|
|
381
411
|
# schema.object_type "Transaction" do |t|
|
382
412
|
# t.field "id", "ID"
|
383
413
|
#
|
384
|
-
# t.field "
|
414
|
+
# t.field "currency", "String" do |f|
|
385
415
|
# f.on_each_generated_schema_element do |element|
|
386
|
-
# # Adds a `@deprecated` directive to every GraphQL schema element generated for `
|
416
|
+
# # Adds a `@deprecated` directive to every GraphQL schema element generated for `currency`:
|
387
417
|
# #
|
388
|
-
# # - The `Transaction.
|
389
|
-
# # - The `TransactionFilterInput.
|
390
|
-
# # - The `
|
391
|
-
# # - The `
|
392
|
-
# # - The `
|
418
|
+
# # - The `Transaction.currency` field.
|
419
|
+
# # - The `TransactionFilterInput.currency` field.
|
420
|
+
# # - The `TransactionHighlights.currency` field.
|
421
|
+
# # - The `TransactionAggregationGroupedBy.currency` field.
|
422
|
+
# # - The `TransactionAggregatedValues.currency` field.
|
423
|
+
# # - The `TransactionSortOrder.currency_ASC` and`TransactionSortOrder.currency_DESC` enum values.
|
393
424
|
# element.directive "deprecated"
|
394
425
|
# end
|
395
426
|
# end
|
@@ -402,6 +433,7 @@ module ElasticGraph
|
|
402
433
|
customize_filter_field(&customization_block)
|
403
434
|
customize_aggregated_values_field(&customization_block)
|
404
435
|
customize_grouped_by_field(&customization_block)
|
436
|
+
customize_highlights_field(&customization_block)
|
405
437
|
customize_sub_aggregations_field(&customization_block)
|
406
438
|
customize_sort_order_enum_values(&customization_block)
|
407
439
|
end
|
@@ -460,46 +492,6 @@ module ElasticGraph
|
|
460
492
|
)
|
461
493
|
end
|
462
494
|
|
463
|
-
# Configures the GraphQL resolver used to resolve this field. If not set, the resolver configured on the parent type
|
464
|
-
# via {Mixins::HasIndices#resolve_fields_with} will be used.
|
465
|
-
#
|
466
|
-
# @param resolver_name [Symbol] name of the GraphQL resolver
|
467
|
-
# @param config [Hash<Symbol, Object>] configuration parameters for the resolver
|
468
|
-
# @return [void]
|
469
|
-
# @see API#register_graphql_resolver
|
470
|
-
#
|
471
|
-
# @example Use a custom resolver for a custom `Query` field
|
472
|
-
# # In `add_resolver.rb`:
|
473
|
-
# class AddResolver
|
474
|
-
# def initialize(elasticgraph_graphql:, config:)
|
475
|
-
# @multiplier = config.fetch(:multiplier, 1)
|
476
|
-
# end
|
477
|
-
#
|
478
|
-
# def resolve(field:, object:, args:, context:)
|
479
|
-
# sum = args.fetch("x") + args.fetch("y")
|
480
|
-
# sum * @multiplier
|
481
|
-
# end
|
482
|
-
# end
|
483
|
-
#
|
484
|
-
# # In `config/schema.rb`:
|
485
|
-
# ElasticGraph.define_schema do |schema|
|
486
|
-
# require(resolver_path = "add_resolver")
|
487
|
-
# schema.register_graphql_resolver :add, AddResolver, defined_at: resolver_path
|
488
|
-
#
|
489
|
-
# schema.on_root_query_type do |t|
|
490
|
-
# t.field "add", "Int" do |f|
|
491
|
-
# f.argument "x", "Int!"
|
492
|
-
# f.argument "y", "Int!"
|
493
|
-
#
|
494
|
-
# # Extra args (`multiplier: 2`, in this example) are passed to the resolver within `config`.
|
495
|
-
# f.resolve_with :add, multiplier: 2
|
496
|
-
# end
|
497
|
-
# end
|
498
|
-
# end
|
499
|
-
def resolve_with(resolver_name, **config)
|
500
|
-
self.resolver = resolver_name&.then { |name| SchemaArtifacts::RuntimeMetadata::ConfiguredGraphQLResolver.new(name, config) }
|
501
|
-
end
|
502
|
-
|
503
495
|
# @private
|
504
496
|
def runtime_script(script)
|
505
497
|
self.runtime_field_script = script
|
@@ -659,6 +651,17 @@ module ElasticGraph
|
|
659
651
|
nested? || type_for_derived_types.fully_unwrapped.as_object_type&.supports?(&:sub_aggregatable?)
|
660
652
|
end
|
661
653
|
|
654
|
+
# @private
|
655
|
+
HIGHLIGHTABLE_MAPPING_TYPES = %w[keyword text match_only_text]
|
656
|
+
|
657
|
+
def highlightable?
|
658
|
+
return highlightable unless highlightable.nil?
|
659
|
+
return false if relationship
|
660
|
+
return true if HIGHLIGHTABLE_MAPPING_TYPES.include?(mapping_type)
|
661
|
+
|
662
|
+
type_for_derived_types.fully_unwrapped.as_object_type&.supports?(&:highlightable?)
|
663
|
+
end
|
664
|
+
|
662
665
|
# Defines an argument on the field.
|
663
666
|
#
|
664
667
|
# @note ElasticGraph takes care of defining arguments for all the query features it supports, so there is generally no need to use
|
@@ -724,16 +727,32 @@ module ElasticGraph
|
|
724
727
|
parent_type.field field_name, grouped_by_field_type_name, name_in_index: name_in_index, graphql_only: true do |f|
|
725
728
|
add_grouped_by_field_documentation(f)
|
726
729
|
|
727
|
-
define_legacy_timestamp_grouping_arguments_if_needed(f) if legacy_grouping_schema
|
728
|
-
|
729
730
|
grouped_by_customizations.each { |block| block.call(f) }
|
730
731
|
end
|
731
732
|
end
|
732
733
|
|
734
|
+
# @private
|
735
|
+
def define_highlights_field(parent_type)
|
736
|
+
return unless highlightable?
|
737
|
+
|
738
|
+
unwrapped_type = type_for_derived_types.fully_unwrapped
|
739
|
+
type_name =
|
740
|
+
if unwrapped_type.leaf?
|
741
|
+
"[String!]!"
|
742
|
+
else
|
743
|
+
unwrapped_type.as_highlights.name
|
744
|
+
end
|
745
|
+
|
746
|
+
parent_type.field name, type_name, name_in_index: name_in_index, graphql_only: true do |f|
|
747
|
+
f.documentation derived_documentation("Search highlights for the `#{name}`, providing snippets of the matching text")
|
748
|
+
highlights_customizations.each { |block| block.call(f) }
|
749
|
+
end
|
750
|
+
end
|
751
|
+
|
733
752
|
# @private
|
734
753
|
def grouped_by_field_type_name
|
735
754
|
unwrapped_type = type_for_derived_types.fully_unwrapped
|
736
|
-
if unwrapped_type.scalar_type_needing_grouped_by_object?
|
755
|
+
if unwrapped_type.scalar_type_needing_grouped_by_object?
|
737
756
|
unwrapped_type.with_reverted_override.as_grouped_by.name
|
738
757
|
elsif unwrapped_type.leaf?
|
739
758
|
unwrapped_type.name
|
@@ -754,7 +773,7 @@ module ElasticGraph
|
|
754
773
|
"The `#{name}` field value for this group",
|
755
774
|
list_field_grouped_by_doc_note("the selected subfields of `#{name}`")
|
756
775
|
)
|
757
|
-
elsif type_for_derived_types.fully_unwrapped.scalar_type_needing_grouped_by_object?
|
776
|
+
elsif type_for_derived_types.fully_unwrapped.scalar_type_needing_grouped_by_object?
|
758
777
|
derived_documentation("Offers the different grouping options for the `#{name}` value within this group")
|
759
778
|
else
|
760
779
|
derived_documentation("The `#{name}` field value for this group")
|
@@ -986,29 +1005,13 @@ module ElasticGraph
|
|
986
1005
|
)
|
987
1006
|
end
|
988
1007
|
|
989
|
-
|
990
|
-
|
991
|
-
#
|
992
|
-
# @private
|
1008
|
+
private
|
1009
|
+
|
993
1010
|
def backing_indexing_field
|
994
1011
|
return nil unless graphql_only
|
995
|
-
|
996
|
-
type = parent_type
|
997
|
-
field = nil
|
998
|
-
|
999
|
-
name_in_index.split(".").each do |path_part|
|
1000
|
-
if (field = type&.indexing_fields_by_name_in_index&.fetch(path_part, nil))
|
1001
|
-
type = field.type.fully_unwrapped.as_object_type
|
1002
|
-
else
|
1003
|
-
return nil
|
1004
|
-
end
|
1005
|
-
end
|
1006
|
-
|
1007
|
-
field
|
1012
|
+
parent_type.indexing_fields_by_name_in_index[name_in_index]
|
1008
1013
|
end
|
1009
1014
|
|
1010
|
-
private
|
1011
|
-
|
1012
1015
|
def args_sdl(joiner:, after_opening_paren: "", &arg_selector)
|
1013
1016
|
selected_args = args.values.select(&arg_selector)
|
1014
1017
|
args_sdl = selected_args.map(&:to_sdl).flat_map { |s| s.split("\n") }.join(joiner)
|
@@ -1021,40 +1024,6 @@ module ElasticGraph
|
|
1021
1024
|
mapping_type == "text"
|
1022
1025
|
end
|
1023
1026
|
|
1024
|
-
def define_legacy_timestamp_grouping_arguments_if_needed(grouping_field)
|
1025
|
-
case type.fully_unwrapped.name
|
1026
|
-
when "Date"
|
1027
|
-
grouping_field.argument schema_def_state.schema_elements.granularity, "DateGroupingGranularity!" do |a|
|
1028
|
-
a.documentation "Determines the grouping granularity for this field."
|
1029
|
-
end
|
1030
|
-
|
1031
|
-
grouping_field.argument schema_def_state.schema_elements.offset_days, "Int" do |a|
|
1032
|
-
a.documentation <<~EOS
|
1033
|
-
Number of days (positive or negative) to shift the `Date` boundaries of each date grouping bucket.
|
1034
|
-
|
1035
|
-
For example, when grouping by `YEAR`, this can be used to align the buckets with fiscal or school years instead of calendar years.
|
1036
|
-
EOS
|
1037
|
-
end
|
1038
|
-
when "DateTime"
|
1039
|
-
grouping_field.argument schema_def_state.schema_elements.granularity, "DateTimeGroupingGranularity!" do |a|
|
1040
|
-
a.documentation "Determines the grouping granularity for this field."
|
1041
|
-
end
|
1042
|
-
|
1043
|
-
grouping_field.argument schema_def_state.schema_elements.time_zone, "TimeZone" do |a|
|
1044
|
-
a.documentation "The time zone to use when determining which grouping a `DateTime` value falls in."
|
1045
|
-
a.default "UTC"
|
1046
|
-
end
|
1047
|
-
|
1048
|
-
grouping_field.argument schema_def_state.schema_elements.offset, "DateTimeGroupingOffsetInput" do |a|
|
1049
|
-
a.documentation <<~EOS
|
1050
|
-
Amount of offset (positive or negative) to shift the `DateTime` boundaries of each grouping bucket.
|
1051
|
-
|
1052
|
-
For example, when grouping by `WEEK`, you can shift by 24 hours to change what day-of-week weeks are considered to start on.
|
1053
|
-
EOS
|
1054
|
-
end
|
1055
|
-
end
|
1056
|
-
end
|
1057
|
-
|
1058
1027
|
def list_field_grouped_by_doc_note(individual_value_selection_description)
|
1059
1028
|
<<~EOS.strip
|
1060
1029
|
Note: `#{name}` is a collection field, but selecting this field will group on individual values of #{individual_value_selection_description}.
|
@@ -39,7 +39,16 @@ module ElasticGraph
|
|
39
39
|
# @private
|
40
40
|
# @!attribute [rw] aggregated_values_customizations
|
41
41
|
# @private
|
42
|
-
|
42
|
+
# @!attribute [rw] filter_input_customizations
|
43
|
+
# @private
|
44
|
+
class ScalarType < Struct.new(
|
45
|
+
:schema_def_state,
|
46
|
+
:type_ref,
|
47
|
+
:mapping_type,
|
48
|
+
:runtime_metadata,
|
49
|
+
:aggregated_values_customizations,
|
50
|
+
:filter_input_customizations
|
51
|
+
)
|
43
52
|
# `Struct.new` provides the following methods:
|
44
53
|
# @dynamic type_ref, runtime_metadata
|
45
54
|
prepend Mixins::VerifiesGraphQLName
|
@@ -157,6 +166,13 @@ module ElasticGraph
|
|
157
166
|
self.aggregated_values_customizations = block
|
158
167
|
end
|
159
168
|
|
169
|
+
# Registers a block which will be used to customize the derived `*FilterInput` object type.
|
170
|
+
#
|
171
|
+
# @private
|
172
|
+
def customize_filter_input_type(&block)
|
173
|
+
self.filter_input_customizations = block
|
174
|
+
end
|
175
|
+
|
160
176
|
# @private
|
161
177
|
def aggregated_values_type
|
162
178
|
if aggregated_values_customizations
|
@@ -284,6 +300,8 @@ module ElasticGraph
|
|
284
300
|
f.documentation LTE_DOC
|
285
301
|
end
|
286
302
|
end
|
303
|
+
|
304
|
+
filter_input_customizations&.call(t)
|
287
305
|
end
|
288
306
|
end
|
289
307
|
|
@@ -147,6 +147,7 @@ module ElasticGraph
|
|
147
147
|
FieldsListFilterInput: "%{base}FieldsListFilterInput",
|
148
148
|
FilterInput: "%{base}FilterInput",
|
149
149
|
GroupedBy: "%{base}GroupedBy",
|
150
|
+
Highlights: "%{base}Highlights",
|
150
151
|
InputEnum: "%{base}Input",
|
151
152
|
ListElementFilterInput: "%{base}ListElementFilterInput",
|
152
153
|
ListFilterInput: "%{base}ListFilterInput",
|
@@ -287,6 +287,7 @@ module ElasticGraph
|
|
287
287
|
# @dynamic as_edge
|
288
288
|
# @dynamic as_fields_list_filter_input
|
289
289
|
# @dynamic as_filter_input
|
290
|
+
# @dynamic as_highlights
|
290
291
|
# @dynamic as_input_enum
|
291
292
|
# @dynamic as_list_element_filter_input, list_element_filter_input?
|
292
293
|
# @dynamic as_list_filter_input, list_filter_input?
|
@@ -279,12 +279,6 @@ module ElasticGraph
|
|
279
279
|
# differently named field in the index.
|
280
280
|
# @param singular [String] indicates what the singular form of a field's name is. When provided, ElasticGraph will define a
|
281
281
|
# `groupedBy` field (using the singular form) allowing clients to group by individual values from the field.
|
282
|
-
# @param aggregatable [Boolean] force-enables or disables the ability for aggregation queries to aggregate over this field.
|
283
|
-
# When not provided, ElasticGraph will infer field aggregatability based on the field's GraphQL type and mapping type.
|
284
|
-
# @param filterable [Boolean] force-enables or disables the ability for queries to filter by this field. When not provided,
|
285
|
-
# ElasticGraph will infer field filterability based on the field's GraphQL type and mapping type.
|
286
|
-
# @param groupable [Boolean] force-enables or disables the ability for aggregation queries to group by this field. When
|
287
|
-
# not provided, ElasticGraph will infer field groupability based on the field's GraphQL type and mapping type.
|
288
282
|
# @yield [Field] the field for further customization
|
289
283
|
# @return [void]
|
290
284
|
#
|
@@ -301,37 +295,23 @@ module ElasticGraph
|
|
301
295
|
# t.index "authors"
|
302
296
|
# end
|
303
297
|
# end
|
304
|
-
def paginated_collection_field(
|
305
|
-
name,
|
306
|
-
element_type,
|
307
|
-
name_in_index: name,
|
308
|
-
graphql_only: false,
|
309
|
-
singular: nil,
|
310
|
-
groupable: !!singular,
|
311
|
-
filterable: nil,
|
312
|
-
aggregatable: nil,
|
313
|
-
&block
|
314
|
-
)
|
298
|
+
def paginated_collection_field(name, element_type, name_in_index: name, singular: nil, &block)
|
315
299
|
element_type_ref = schema_def_state.type_ref(element_type).to_final_form
|
316
300
|
element_type = element_type_ref.name
|
317
301
|
|
318
302
|
schema_def_state.paginated_collection_element_types << element_type
|
319
303
|
|
320
|
-
|
321
|
-
field(name, "[#{element_type}!]!", indexing_only: true, name_in_index: name_in_index, &block)
|
322
|
-
end
|
304
|
+
field(name, "[#{element_type}!]!", indexing_only: true, name_in_index: name_in_index, &block)
|
323
305
|
|
324
306
|
field(
|
325
307
|
name,
|
326
308
|
element_type_ref.as_connection.name,
|
327
309
|
name_in_index: name_in_index,
|
328
310
|
type_for_derived_types: "[#{element_type}]",
|
311
|
+
groupable: !!singular,
|
312
|
+
sortable: false,
|
329
313
|
graphql_only: true,
|
330
|
-
singular: singular
|
331
|
-
groupable: groupable,
|
332
|
-
filterable: filterable,
|
333
|
-
aggregatable: aggregatable,
|
334
|
-
sortable: false
|
314
|
+
singular: singular
|
335
315
|
) do |f|
|
336
316
|
f.define_relay_pagination_arguments!
|
337
317
|
block&.call(f)
|
@@ -555,7 +535,7 @@ module ElasticGraph
|
|
555
535
|
)
|
556
536
|
|
557
537
|
field.relationship = relationship
|
558
|
-
field.
|
538
|
+
field.resolver = :nested_relationships
|
559
539
|
|
560
540
|
yield relationship if block_given?
|
561
541
|
|
@@ -31,30 +31,10 @@ if (previousSourceIdsForRelationship.size() > 0) {
|
|
31
31
|
);
|
32
32
|
}
|
33
33
|
|
34
|
-
|
35
|
-
// we need to continue getting it from `__sourceVersions`. Both our old version and this versions of this
|
36
|
-
// script keep the value in `__sourceVersions` up-to-date, whereas the old script only writes it to
|
37
|
-
// `__sourceVersions`. Until we have completely migrated off of the old script for all ElasticGraph
|
38
|
-
// clusters, we need to keep using it.
|
39
|
-
//
|
40
|
-
// Later, after the old script is no longer used by any clusters, we'll stop using `__sourceVersions`.
|
41
|
-
Number _versionForSourceType = source.get("__sourceVersions")?.get(params.sourceType)?.get(sourceId);
|
42
|
-
Number _versionForRelationship = relationshipVersionsMap.get(sourceId);
|
34
|
+
Number maybeDocVersion = source.__versions.get(params.relationship)?.get(params.sourceId);
|
43
35
|
|
44
36
|
// Our JSON schema requires event versions to be non-negative, so we can safely use Long.MIN_VALUE as a stand-in when the value is null.
|
45
|
-
long
|
46
|
-
long versionForRelationship = _versionForRelationship == null ? Long.MIN_VALUE : _versionForRelationship.longValue();
|
47
|
-
|
48
|
-
// Pick the larger of the two versions as our doc version. Note that `Math.max` didn't work for me here for
|
49
|
-
// reasons I don't understand, but a simple ternary works fine.
|
50
|
-
//
|
51
|
-
// In theory, we could just use `versionForSourceType` as the `docVersion` (and not even check `__versions` at all)
|
52
|
-
// since both the old version and this version maintain the doc version in `__sourceVersions`. However, that would
|
53
|
-
// prevent this version of the script from being forward-compatible with the planned next version of this script.
|
54
|
-
// In the next version, we plan to stop writing to `__sourceVersions`, and as we can't deploy that change atomically,
|
55
|
-
// this version of the script will continue to run after that has begun to be used. So this version of the script
|
56
|
-
// must consider which version is greater here, and not simply trust either version value.
|
57
|
-
long docVersion = versionForSourceType > versionForRelationship ? versionForSourceType : versionForRelationship;
|
37
|
+
long docVersion = maybeDocVersion == null ? Long.MIN_VALUE : maybeDocVersion.longValue();
|
58
38
|
|
59
39
|
if (docVersion >= eventVersion) {
|
60
40
|
throw new IllegalArgumentException("ElasticGraph update was a no-op: [" +
|