Module: ElasticGraph::SchemaDefinition::Mixins::HasIndices
- Defined in:
- lib/elastic_graph/schema_definition/mixins/has_indices.rb
Overview
Provides APIs for defining datastore indices.
Instance Attribute Summary collapse
-
#default_graphql_resolver ⇒ ::Symbol?
readonly
The default GraphQL resolver to use for fields on this type.
- #runtime_metadata_overrides ⇒ Object readonly
Instance Method Summary collapse
-
#abstract? ⇒ Boolean
Abstract types are rare, so return false.
-
#derive_indexed_type_fields(name, from_id:, route_with: nil, rollover_with: nil) {|Indexing::DerivedIndexedType| ... } ⇒ void
Configures the ElasticGraph indexer to derive another type from this indexed type, using the ‘from_id` field as the source of the `id` of the derived type, and the provided block for the definitions of the derived fields.
-
#derived_indexed_types ⇒ Array<Indexing::DerivedIndexedType>
List of derived types for this source type.
-
#directly_queryable? ⇒ Boolean
True if this type is directly queryable via a type-specific field on the root ‘Query` type.
- #fields_with_sources ⇒ Object
-
#has_own_index_def? ⇒ Boolean
True if this type has its own index definition (not inherited from an abstract parent).
-
#index(name, **settings) {|Indexing::Index| ... } ⇒ void
Declares a datastore index for the current type, converting it from an embedded type to an indexed type that is directly queryable from the root ‘Query` type.
-
#index_def ⇒ Indexing::Index?
Resolves this type’s index definition.
- #initialize(*args, **options) ⇒ Object
-
#override_runtime_metadata(**overrides) ⇒ void
Configures overrides for runtime metadata.
-
#own_index_def ⇒ Indexing::Index?
The index definition directly defined on this type, or nil if no index is defined directly.
-
#plural_root_query_field_name ⇒ String
The plural name of the entity; used for the root ‘Query` field that queries documents of this indexed type.
-
#resolve_fields_with(default_resolver_name, **config) ⇒ void
Configures the default GraphQL resolver that will be used to resolve the fields of this type.
-
#root_document_type? ⇒ Boolean
True if this type is a root document type that lives at a document root in the datastore (is indexed).
-
#root_query_fields(plural:, singular: nil) {|SchemaElements::Field| ... } ⇒ void
Determines what the root ‘Query` fields will be to query this indexed type.
- #root_query_fields_customizations ⇒ Object
- #runtime_metadata(extra_update_targets) ⇒ Object
-
#singular_root_query_field_name ⇒ String
The singular name of the entity; used for the root ‘Query` field (with an `Aggregations` suffix) that queries aggregations of this indexed type.
-
#source_excludes_paths(path_prefix = "", under_non_returnable_parent = false) ⇒ Object
Returns the list of ‘_source.excludes` paths for non-returnable, non-highlightable fields.
Instance Attribute Details
#default_graphql_resolver ⇒ ::Symbol? (readonly)
Returns the default GraphQL resolver to use for fields on this type.
23 24 25 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 23 def default_graphql_resolver @default_graphql_resolver end |
#runtime_metadata_overrides ⇒ Object (readonly)
20 21 22 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 20 def @runtime_metadata_overrides end |
Instance Method Details
#abstract? ⇒ Boolean
Abstract types are rare, so return false. This can be overridden in the host class.
175 176 177 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 175 def abstract? false end |
#derive_indexed_type_fields(name, from_id:, route_with: nil, rollover_with: nil) {|Indexing::DerivedIndexedType| ... } ⇒ void
This method returns an undefined value.
Configures the ElasticGraph indexer to derive another type from this indexed type, using the ‘from_id` field as the source of the `id` of the derived type, and the provided block for the definitions of the derived fields.
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 222 def derive_indexed_type_fields( name, from_id:, route_with: nil, rollover_with: nil, &block ) Indexing::DerivedIndexedType.new( source_type: self, destination_type_ref: schema_def_state.type_ref(name).to_final_form, id_source: from_id, routing_value_source: route_with, rollover_timestamp_value_source: rollover_with, &block ).tap { |dit| derived_indexed_types << dit } end |
#derived_indexed_types ⇒ Array<Indexing::DerivedIndexedType>
Returns list of derived types for this source type.
240 241 242 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 240 def derived_indexed_types @derived_indexed_types ||= [] end |
#directly_queryable? ⇒ Boolean
A concrete subtype that inherits an index from an abstract parent is NOT directly queryable on its own —only the abstract type that declared the index is. Use #root_document_type? to check whether a type is stored at the root of any index (own or inherited).
Returns true if this type is directly queryable via a type-specific field on the root ‘Query` type.
168 169 170 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 168 def directly_queryable? has_own_index_def? end |
#fields_with_sources ⇒ Object
324 325 326 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 324 def fields_with_sources indexing_fields_by_name_in_index.values.reject { |f| f.source.nil? } end |
#has_own_index_def? ⇒ Boolean
Returns true if this type has its own index definition (not inherited from an abstract parent).
129 130 131 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 129 def has_own_index_def? !@own_index_def.nil? end |
#index(name, **settings) {|Indexing::Index| ... } ⇒ void
Use #root_query_fields on indexed types to name the field that will be exposed on ‘Query`.
Indexed types must also define an ‘id` field, which ElasticGraph will use as the primary key. When an abstract type declares the index, each concrete subtype must also define `id`.
Datastore index settings can also be defined (or overridden) in an environment-specific settings YAML file. Index settings that you want to configure differently for different environments (such as ‘index.number_of_shards`—-production and staging will probably need different numbers!) should be configured in the per-environment YAML configuration files rather than here.
This method returns an undefined value.
Declares a datastore index for the current type, converting it from an embedded type to an indexed type that is directly queryable from the root ‘Query` type. When called on an abstract `interface_type` or `union_type`, concrete subtypes inherit the index by default — they share the same datastore index without needing to call `t.index` themselves. A subtype can opt out of this shared index inheritance by calling `t.index` with a different name to use a dedicated index instead.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 94 def index(name, **settings, &block) unless @can_configure_index raise Errors::SchemaError, "Cannot define an index on `#{self.name}` after initialization is complete. " \ "Indices must be configured during initial type definition." end if @own_index_def raise Errors::SchemaError, "Cannot define multiple indices on `#{self.name}`. " \ "Only one index per type is supported. An index named `#{@own_index_def.name}` has already been defined." end schema_def_state.register_index(name, self) @own_index_def = schema_def_state.factory.new_index(name, settings, self, &block) end |
#index_def ⇒ Indexing::Index?
Resolves this type’s index definition. This will be one of:
-
This type’s own_index_def (if it directly defines an index)
-
An inherited index from an abstract supertype (union/interface) that has an index
This type can be a subtype of multiple abstract types (e.g., implements multiple interfaces), but unless it defines its own index, at most one of its supertypes may have an index. If multiple parent types are indexed, this method raises an error to prevent ambiguity about which index to inherit.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 143 def index_def return own_index_def if has_own_index_def? indexed_supertypes = recursively_resolve_supertypes.select(&:has_own_index_def?) if indexed_supertypes.size > 1 parent_names = indexed_supertypes.map { |p| p.own_index_def.name }.join(", ") raise Errors::SchemaError, "The `#{name}` type is a subtype of multiple indexed abstract types (#{parent_names}). " \ "If a concrete type does not define an index, it may not be a member of multiple indexed abstract types." end indexed_supertypes.first&.own_index_def end |
#initialize(*args, **options) ⇒ Object
27 28 29 30 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 27 def initialize(*args, **) super(*args, **) initialize_has_indices { yield self } end |
#override_runtime_metadata(**overrides) ⇒ void
This method returns an undefined value.
Configures overrides for runtime metadata. The provided runtime metadata values will be persisted in the ‘runtime_metadata.yaml` schema artifact and made available at runtime to `elasticgraph-graphql` and `elasticgraph-indexer`.
249 250 251 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 249 def (**overrides) @runtime_metadata_overrides.merge!(overrides) end |
#own_index_def ⇒ Indexing::Index?
Returns the index definition directly defined on this type, or nil if no index is defined directly. This will be nil when a type is inheriting an index definition from an abstract parent type.
124 125 126 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 124 def own_index_def @own_index_def end |
#plural_root_query_field_name ⇒ String
Returns the plural name of the entity; used for the root ‘Query` field that queries documents of this indexed type.
307 308 309 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 307 def plural_root_query_field_name @plural_root_query_field_name || naively_pluralize_type_name(name) end |
#resolve_fields_with(default_resolver_name, **config) ⇒ void
This method returns an undefined value.
Configures the default GraphQL resolver that will be used to resolve the fields of this type. Individual fields can override this using SchemaElements::Field#resolve_with.
116 117 118 119 120 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 116 def resolve_fields_with(default_resolver_name, **config) @default_graphql_resolver = default_resolver_name&.then do SchemaArtifacts::RuntimeMetadata::ConfiguredGraphQLResolver.new(it, config) end end |
#root_document_type? ⇒ Boolean
Returns true if this type is a root document type that lives at a document root in the datastore (is indexed). This returns true for types with their own index definition or types that inherit an index from a supertype.
160 161 162 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 160 def root_document_type? !index_def.nil? end |
#root_query_fields(plural:, singular: nil) {|SchemaElements::Field| ... } ⇒ void
This method returns an undefined value.
Determines what the root ‘Query` fields will be to query this indexed type. In addition, this method accepts a block, which you can use to customize the root query field (such as adding a GraphQL directive to it).
300 301 302 303 304 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 300 def root_query_fields(plural:, singular: nil, &customization_block) @plural_root_query_field_name = plural @singular_root_query_field_name = singular @root_query_fields_customizations = customization_block end |
#root_query_fields_customizations ⇒ Object
319 320 321 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 319 def root_query_fields_customizations @root_query_fields_customizations end |
#runtime_metadata(extra_update_targets) ⇒ Object
254 255 256 257 258 259 260 261 262 263 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 254 def (extra_update_targets) SchemaArtifacts::RuntimeMetadata::ObjectType.new( update_targets: derived_indexed_types.map(&:runtime_metadata_for_source_type) + [self_update_target].compact + extra_update_targets, index_definition_names: [index_def&.name].compact, graphql_fields_by_name: , elasticgraph_category: nil, source_type: nil, graphql_only_return_type: graphql_only? ).with(**) end |
#singular_root_query_field_name ⇒ String
Returns the singular name of the entity; used for the root ‘Query` field (with an `Aggregations` suffix) that queries aggregations of this indexed type. If not provided, will derive it from the type name (e.g. converting it to `camelCase` or `snake_case`, depending on configuration).
314 315 316 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 314 def singular_root_query_field_name @singular_root_query_field_name || to_field_name(name) end |
#source_excludes_paths(path_prefix = "", under_non_returnable_parent = false) ⇒ Object
Returns the list of ‘_source.excludes` paths for non-returnable, non-highlightable fields.
Hidden highlightable fields must remain in ‘_source` so the datastore can still produce search highlight snippets for them.
Uses ‘indexing_fields_by_name_in_index` for traversal (same as `index_field_runtime_metadata_tuples`) to avoid infinite recursion through interface/union subtype cycles.
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 338 def source_excludes_paths(path_prefix = "", under_non_returnable_parent = false) indexing_fields_by_name_in_index.flat_map do |name, field| path = path_prefix + name object_type = field.type.fully_unwrapped.as_object_type non_returnable = under_non_returnable_parent || !field.returnable? if object_type if non_returnable && !field.highlightable? ["#{path}.*"] else object_type.source_excludes_paths("#{path}.", non_returnable) end elsif non_returnable && !field.highlightable? [path] else [] end end end |