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.
@@ -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
- :args, :sortable, :filterable, :aggregatable, :groupable, :graphql_only, :source, :runtime_field_script, :relationship, :singular_name,
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
- :legacy_grouping_schema, :name_in_index, :resolver
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, legacy_grouping_schema: false, resolver: nil
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
- if graphql_only
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 "amount", "Int" do |f|
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 `amount`:
416
+ # # Adds a `@deprecated` directive to every GraphQL schema element generated for `currency`:
387
417
  # #
388
- # # - The `Transaction.amount` field.
389
- # # - The `TransactionFilterInput.amount` field.
390
- # # - The `TransactionAggregationGroupedBy.amount` field.
391
- # # - The `TransactionAggregatedValues.amount` field.
392
- # # - The `TransactionSortOrder.amount_ASC` and`TransactionSortOrder.amount_DESC` enum values.
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? && !legacy_grouping_schema
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? && !legacy_grouping_schema
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
- # The alternate field that is backing this field in the datastore index. Will only be non-`nil` for `graphql_only` fields.
990
- # @return [Field, nil] the field backing this field in the index
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
- class ScalarType < Struct.new(:schema_def_state, :type_ref, :mapping_type, :runtime_metadata, :aggregated_values_customizations)
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
- unless graphql_only
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.resolve_with :nested_relationships
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
- // While the version in `__versions` is going to be used for the doc version in the future, for now
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 versionForSourceType = _versionForSourceType == null ? Long.MIN_VALUE : _versionForSourceType.longValue();
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: [" +