elasticgraph-schema_definition 0.19.3.1 → 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/LICENSE.txt +1 -1
- data/lib/elastic_graph/schema_definition/api.rb +5 -12
- data/lib/elastic_graph/schema_definition/factory.rb +19 -5
- data/lib/elastic_graph/schema_definition/indexing/derived_fields/append_only_set.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/derived_fields/field_initializer_support.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/derived_fields/immutable_value.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/derived_fields/min_or_max_value.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/derived_indexed_type.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/event_envelope.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/field.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/field_reference.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/field_type/enum.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/field_type/object.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/field_type/scalar.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/field_type/union.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/index.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/json_schema_field_metadata.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/json_schema_with_metadata.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/list_counts_mapping.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/relationship_resolver.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/rollover_config.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/update_target_factory.rb +1 -1
- data/lib/elastic_graph/schema_definition/indexing/update_target_resolver.rb +1 -1
- data/lib/elastic_graph/schema_definition/json_schema_pruner.rb +1 -1
- data/lib/elastic_graph/schema_definition/mixins/can_be_graphql_only.rb +1 -1
- data/lib/elastic_graph/schema_definition/mixins/has_derived_graphql_type_customizations.rb +1 -1
- data/lib/elastic_graph/schema_definition/mixins/has_directives.rb +1 -1
- data/lib/elastic_graph/schema_definition/mixins/has_documentation.rb +1 -1
- data/lib/elastic_graph/schema_definition/mixins/has_indices.rb +4 -17
- data/lib/elastic_graph/schema_definition/mixins/has_readable_to_s_and_inspect.rb +1 -1
- data/lib/elastic_graph/schema_definition/mixins/has_subtypes.rb +1 -1
- data/lib/elastic_graph/schema_definition/mixins/has_type_info.rb +2 -2
- data/lib/elastic_graph/schema_definition/mixins/implements_interfaces.rb +2 -13
- data/lib/elastic_graph/schema_definition/mixins/supports_default_value.rb +1 -1
- data/lib/elastic_graph/schema_definition/mixins/supports_filtering_and_aggregation.rb +23 -8
- data/lib/elastic_graph/schema_definition/mixins/verifies_graphql_name.rb +1 -1
- data/lib/elastic_graph/schema_definition/rake_tasks.rb +1 -1
- data/lib/elastic_graph/schema_definition/results.rb +5 -5
- data/lib/elastic_graph/schema_definition/schema_artifact_manager.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/argument.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/built_in_types.rb +108 -216
- data/lib/elastic_graph/schema_definition/schema_elements/deprecated_element.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/directive.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/enum_type.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/enum_value.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/enum_value_namer.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/enums_for_indexed_types.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/field.rb +103 -142
- data/lib/elastic_graph/schema_definition/schema_elements/field_path.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/field_source.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/graphql_sdl_enumerator.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/input_field.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/input_type.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/interface_type.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/list_counts_state.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/object_type.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/relationship.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/scalar_type.rb +20 -2
- data/lib/elastic_graph/schema_definition/schema_elements/sort_order_enum_value.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/sub_aggregation_path.rb +1 -1
- data/lib/elastic_graph/schema_definition/schema_elements/type_namer.rb +2 -1
- data/lib/elastic_graph/schema_definition/schema_elements/type_reference.rb +8 -10
- data/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb +7 -27
- data/lib/elastic_graph/schema_definition/schema_elements/union_type.rb +1 -1
- data/lib/elastic_graph/schema_definition/scripting/file_system_repository.rb +1 -1
- data/lib/elastic_graph/schema_definition/scripting/script.rb +1 -1
- data/lib/elastic_graph/schema_definition/scripting/scripts/update/index_data.painless +2 -22
- data/lib/elastic_graph/schema_definition/state.rb +1 -1
- data/lib/elastic_graph/schema_definition/test_support.rb +1 -1
- metadata +28 -28
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2024 -
|
|
1
|
+
# Copyright 2024 - 2025 Block, Inc.
|
|
2
2
|
#
|
|
3
3
|
# Use of this source code is governed by an MIT-style
|
|
4
4
|
# license that can be found in the LICENSE file or at
|
|
@@ -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
|
|
@@ -609,14 +601,13 @@ module ElasticGraph
|
|
|
609
601
|
# instead.
|
|
610
602
|
return false if parent_type.indexed? && name == "id"
|
|
611
603
|
|
|
612
|
-
return false if relationship ||
|
|
604
|
+
return false if relationship || type.fully_unwrapped.as_object_type&.does_not_support?(&:groupable?)
|
|
613
605
|
|
|
614
606
|
# We don't support grouping an entire list of values, but we do support grouping on individual values in a list.
|
|
615
607
|
# However, we only do so when a `singular_name` has been provided (so that we know what to call the grouped_by field).
|
|
616
608
|
# The semantics are a little odd (since one document can be duplicated in multiple grouping buckets) so we're ok
|
|
617
609
|
# with not offering it by default--the user has to opt-in by telling us what to call the field in its singular form.
|
|
618
|
-
|
|
619
|
-
return list_field_groupable_by_single_values? if type.list? && (type.fully_unwrapped.leaf? || original_type.fully_unwrapped.grouped_by_type_defined?)
|
|
610
|
+
return list_field_groupable_by_single_values? if type.list? && type.fully_unwrapped.leaf?
|
|
620
611
|
|
|
621
612
|
# Nested fields will be supported through specific nested aggregation support, and do not
|
|
622
613
|
# work as expected when grouping on the root document type.
|
|
@@ -660,6 +651,17 @@ module ElasticGraph
|
|
|
660
651
|
nested? || type_for_derived_types.fully_unwrapped.as_object_type&.supports?(&:sub_aggregatable?)
|
|
661
652
|
end
|
|
662
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
|
+
|
|
663
665
|
# Defines an argument on the field.
|
|
664
666
|
#
|
|
665
667
|
# @note ElasticGraph takes care of defining arguments for all the query features it supports, so there is generally no need to use
|
|
@@ -725,19 +727,33 @@ module ElasticGraph
|
|
|
725
727
|
parent_type.field field_name, grouped_by_field_type_name, name_in_index: name_in_index, graphql_only: true do |f|
|
|
726
728
|
add_grouped_by_field_documentation(f)
|
|
727
729
|
|
|
728
|
-
define_legacy_timestamp_grouping_arguments_if_needed(f) if legacy_grouping_schema
|
|
729
|
-
|
|
730
730
|
grouped_by_customizations.each { |block| block.call(f) }
|
|
731
731
|
end
|
|
732
732
|
end
|
|
733
733
|
|
|
734
|
-
#
|
|
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
|
+
|
|
735
752
|
# @private
|
|
736
753
|
def grouped_by_field_type_name
|
|
737
754
|
unwrapped_type = type_for_derived_types.fully_unwrapped
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
original_unwrapped_type.as_grouped_by.name
|
|
755
|
+
if unwrapped_type.scalar_type_needing_grouped_by_object?
|
|
756
|
+
unwrapped_type.with_reverted_override.as_grouped_by.name
|
|
741
757
|
elsif unwrapped_type.leaf?
|
|
742
758
|
unwrapped_type.name
|
|
743
759
|
else
|
|
@@ -757,7 +773,7 @@ module ElasticGraph
|
|
|
757
773
|
"The `#{name}` field value for this group",
|
|
758
774
|
list_field_grouped_by_doc_note("the selected subfields of `#{name}`")
|
|
759
775
|
)
|
|
760
|
-
elsif
|
|
776
|
+
elsif type_for_derived_types.fully_unwrapped.scalar_type_needing_grouped_by_object?
|
|
761
777
|
derived_documentation("Offers the different grouping options for the `#{name}` value within this group")
|
|
762
778
|
else
|
|
763
779
|
derived_documentation("The `#{name}` field value for this group")
|
|
@@ -989,29 +1005,13 @@ module ElasticGraph
|
|
|
989
1005
|
)
|
|
990
1006
|
end
|
|
991
1007
|
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
#
|
|
995
|
-
# @private
|
|
1008
|
+
private
|
|
1009
|
+
|
|
996
1010
|
def backing_indexing_field
|
|
997
1011
|
return nil unless graphql_only
|
|
998
|
-
|
|
999
|
-
type = parent_type
|
|
1000
|
-
field = nil
|
|
1001
|
-
|
|
1002
|
-
name_in_index.split(".").each do |path_part|
|
|
1003
|
-
if (field = type&.indexing_fields_by_name_in_index&.fetch(path_part, nil))
|
|
1004
|
-
type = field.type.fully_unwrapped.as_object_type
|
|
1005
|
-
else
|
|
1006
|
-
return nil
|
|
1007
|
-
end
|
|
1008
|
-
end
|
|
1009
|
-
|
|
1010
|
-
field
|
|
1012
|
+
parent_type.indexing_fields_by_name_in_index[name_in_index]
|
|
1011
1013
|
end
|
|
1012
1014
|
|
|
1013
|
-
private
|
|
1014
|
-
|
|
1015
1015
|
def args_sdl(joiner:, after_opening_paren: "", &arg_selector)
|
|
1016
1016
|
selected_args = args.values.select(&arg_selector)
|
|
1017
1017
|
args_sdl = selected_args.map(&:to_sdl).flat_map { |s| s.split("\n") }.join(joiner)
|
|
@@ -1019,50 +1019,11 @@ module ElasticGraph
|
|
|
1019
1019
|
"(#{after_opening_paren}#{args_sdl})"
|
|
1020
1020
|
end
|
|
1021
1021
|
|
|
1022
|
-
# Identifies types that disallow grouping, except for types that define their own `GroupedBy` type.
|
|
1023
|
-
def type_disallows_grouping?
|
|
1024
|
-
!original_type.fully_unwrapped.grouped_by_type_defined? && !!type.fully_unwrapped.as_object_type&.does_not_support?(&:groupable?)
|
|
1025
|
-
end
|
|
1026
|
-
|
|
1027
1022
|
# Indicates if the field uses the `text` mapping type.
|
|
1028
1023
|
def text?
|
|
1029
1024
|
mapping_type == "text"
|
|
1030
1025
|
end
|
|
1031
1026
|
|
|
1032
|
-
def define_legacy_timestamp_grouping_arguments_if_needed(grouping_field)
|
|
1033
|
-
case type.fully_unwrapped.name
|
|
1034
|
-
when "Date"
|
|
1035
|
-
grouping_field.argument schema_def_state.schema_elements.granularity, "DateGroupingGranularity!" do |a|
|
|
1036
|
-
a.documentation "Determines the grouping granularity for this field."
|
|
1037
|
-
end
|
|
1038
|
-
|
|
1039
|
-
grouping_field.argument schema_def_state.schema_elements.offset_days, "Int" do |a|
|
|
1040
|
-
a.documentation <<~EOS
|
|
1041
|
-
Number of days (positive or negative) to shift the `Date` boundaries of each date grouping bucket.
|
|
1042
|
-
|
|
1043
|
-
For example, when grouping by `YEAR`, this can be used to align the buckets with fiscal or school years instead of calendar years.
|
|
1044
|
-
EOS
|
|
1045
|
-
end
|
|
1046
|
-
when "DateTime"
|
|
1047
|
-
grouping_field.argument schema_def_state.schema_elements.granularity, "DateTimeGroupingGranularity!" do |a|
|
|
1048
|
-
a.documentation "Determines the grouping granularity for this field."
|
|
1049
|
-
end
|
|
1050
|
-
|
|
1051
|
-
grouping_field.argument schema_def_state.schema_elements.time_zone, "TimeZone" do |a|
|
|
1052
|
-
a.documentation "The time zone to use when determining which grouping a `DateTime` value falls in."
|
|
1053
|
-
a.default "UTC"
|
|
1054
|
-
end
|
|
1055
|
-
|
|
1056
|
-
grouping_field.argument schema_def_state.schema_elements.offset, "DateTimeGroupingOffsetInput" do |a|
|
|
1057
|
-
a.documentation <<~EOS
|
|
1058
|
-
Amount of offset (positive or negative) to shift the `DateTime` boundaries of each grouping bucket.
|
|
1059
|
-
|
|
1060
|
-
For example, when grouping by `WEEK`, you can shift by 24 hours to change what day-of-week weeks are considered to start on.
|
|
1061
|
-
EOS
|
|
1062
|
-
end
|
|
1063
|
-
end
|
|
1064
|
-
end
|
|
1065
|
-
|
|
1066
1027
|
def list_field_grouped_by_doc_note(individual_value_selection_description)
|
|
1067
1028
|
<<~EOS.strip
|
|
1068
1029
|
Note: `#{name}` is a collection field, but selecting this field will group on individual values of #{individual_value_selection_description}.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2024 -
|
|
1
|
+
# Copyright 2024 - 2025 Block, Inc.
|
|
2
2
|
#
|
|
3
3
|
# Use of this source code is governed by an MIT-style
|
|
4
4
|
# license that can be found in the LICENSE file or at
|
|
@@ -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
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2024 -
|
|
1
|
+
# Copyright 2024 - 2025 Block, Inc.
|
|
2
2
|
#
|
|
3
3
|
# Use of this source code is governed by an MIT-style
|
|
4
4
|
# license that can be found in the LICENSE file or at
|
|
@@ -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",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2024 -
|
|
1
|
+
# Copyright 2024 - 2025 Block, Inc.
|
|
2
2
|
#
|
|
3
3
|
# Use of this source code is governed by an MIT-style
|
|
4
4
|
# license that can be found in the LICENSE file or at
|
|
@@ -153,15 +153,12 @@ module ElasticGraph
|
|
|
153
153
|
.sub(/[\]!]+\z/, "") # strip `]` and `!` characters from the end: https://rubular.com/r/pC8C0i7EpvHDbf
|
|
154
154
|
end
|
|
155
155
|
|
|
156
|
-
#
|
|
157
|
-
#
|
|
158
|
-
#
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
schema_def_state.types_by_name.key?(as_grouped_by.name)
|
|
156
|
+
# Generally speaking, scalar types have `grouped_by` fields which are scalars of the same types,
|
|
157
|
+
# and object types have `grouped_by` fields which are special `[object_type]GroupedBy` types.
|
|
158
|
+
#
|
|
159
|
+
# ...except for some special cases (Date and DateTime), which this predicate detects.
|
|
160
|
+
def scalar_type_needing_grouped_by_object?
|
|
161
|
+
%w[Date DateTime].include?(type_namer.revert_override_for(name))
|
|
165
162
|
end
|
|
166
163
|
|
|
167
164
|
# Returns a new `TypeReference` with any type name overrides reverted (to provide the "original" type name).
|
|
@@ -290,6 +287,7 @@ module ElasticGraph
|
|
|
290
287
|
# @dynamic as_edge
|
|
291
288
|
# @dynamic as_fields_list_filter_input
|
|
292
289
|
# @dynamic as_filter_input
|
|
290
|
+
# @dynamic as_highlights
|
|
293
291
|
# @dynamic as_input_enum
|
|
294
292
|
# @dynamic as_list_element_filter_input, list_element_filter_input?
|
|
295
293
|
# @dynamic as_list_filter_input, list_filter_input?
|