Module: ElasticGraph::SchemaDefinition::Mixins::HasIndices

Included in:
SchemaElements::InterfaceType, SchemaElements::ObjectType, SchemaElements::UnionType
Defined in:
lib/elastic_graph/schema_definition/mixins/has_indices.rb

Overview

Provides APIs for defining datastore indices.

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#default_graphql_resolver::Symbol? (readonly)

Returns the default GraphQL resolver to use for fields on this type.

Returns:

  • (::Symbol, nil)

    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_overridesObject (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.

Returns:

  • (Boolean)


109
110
111
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 109

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.

Examples:

Derive a ‘Course` type from `StudentCourseEnrollment` events

ElasticGraph.define_schema do |schema|
  # `StudentCourseEnrollment` is a directly indexed type.
  schema.object_type "StudentCourseEnrollment" do |t|
    t.field "id", "ID"
    t.field "courseId", "ID"
    t.field "courseName", "String"
    t.field "studentName", "String"
    t.field "courseStartDate", "Date"

    t.index "student_course_enrollments"

    # Here we define how the `Course` indexed type  is derived when we index `StudentCourseEnrollment` events.
    t.derive_indexed_type_fields "Course", from_id: "courseId" do |derive|
      # `derive` is an instance of `DerivedIndexedType`.
      derive.immutable_value "name", from: "courseName"
      derive.append_only_set "students", from: "studentName"
      derive.min_value "firstOfferedDate", from: "courseStartDate"
      derive.max_value "mostRecentlyOfferedDate", from: "courseStartDate"
    end
  end

  # `Course` is an indexed type that is derived entirely from `StudentCourseEnrollment` events.
  schema.object_type "Course" do |t|
    t.field "id", "ID"
    t.field "name", "String"
    t.field "students", "[String!]!"
    t.field "firstOfferedDate", "Date"
    t.field "mostRecentlyOfferedDate", "Date"

    t.index "courses"
  end
end

Parameters:

  • name (String)

    name of the derived type

  • from_id (String)

    path to the source type field with ‘id` values for the derived type

  • route_with (String, nil) (defaults to: nil)

    path to the source type field with values for shard routing on the derived type

  • rollover_with (String, nil) (defaults to: nil)

    path to the source type field with values for index rollover on the derived type

Yields:



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 156

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_typesArray<Indexing::DerivedIndexedType>

Returns list of derived types for this source type.

Returns:



174
175
176
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 174

def derived_indexed_types
  @derived_indexed_types ||= []
end

#fields_with_sourcesObject



258
259
260
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 258

def fields_with_sources
  indexing_fields_by_name_in_index.values.reject { |f| f.source.nil? }
end

#index(name, **settings) {|Indexing::Index| ... } ⇒ void

Note:

Use #root_query_fields on indexed types to name the field that will be exposed on ‘Query`.

Note:

Indexed types must also define an ‘id` field, which ElasticGraph will use as the primary key.

Note:

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.

Converts the current type from being an embedded type (that is, a type that is embedded within another indexed type) to an indexed type that resides in the named index definition. Indexed types are directly indexed into the datastore, and will be queryable from the root ‘Query` type.

Examples:

Define a ‘campaigns` index

ElasticGraph.define_schema do |schema|
  schema.object_type "Campaign" do |t|
    t.field "id", "ID"

    t.index(
      "campaigns",
      # Configure `index.refresh_interval`.
      refresh_interval: "1s",
      # Use `index.search` to log warnings for any search query that take more than five seconds.
      search: {slowlog: {level: "WARN", threshold: {query: {warn: "5s"}}}}
    ) do |i|
      # The index can be customized further here.
    end
  end
end

Parameters:

Yields:



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 69

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 @index_def
    raise Errors::SchemaError, "Cannot define multiple indices on `#{self.name}`. " \
      "Only one index per type is supported. An index named `#{@index_def.name}` has already been defined."
  end

  @index_def = Indexing::Index.new(name, settings, schema_def_state, self, &block)
end

#index_defIndexing::Index?

Returns the defined index for this type, or nil if no index is defined.

Returns:

  • (Indexing::Index, nil)

    the defined index for this type, or nil if no index is defined



97
98
99
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 97

def index_def
  @index_def
end

#indexed?Boolean

Returns true if this type has an index.

Returns:

  • (Boolean)

    true if this type has an index



102
103
104
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 102

def indexed?
  !@index_def.nil?
end

#initialize(*args, **options) {|_self| ... } ⇒ Object

Yields:

  • (_self)

Yield Parameters:



27
28
29
30
31
32
33
34
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 27

def initialize(*args, **options)
  super(*args, **options)
  @runtime_metadata_overrides = {}
  @can_configure_index = true
  resolve_fields_with :get_record_field_value
  yield self
  @can_configure_index = false
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`.



183
184
185
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 183

def (**overrides)
  @runtime_metadata_overrides.merge!(overrides)
end

#plural_root_query_field_nameString

Returns the plural name of the entity; used for the root ‘Query` field that queries documents of this indexed type.

Returns:

  • (String)

    the plural name of the entity; used for the root ‘Query` field that queries documents of this indexed type



241
242
243
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 241

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.

Parameters:

  • default_resolver_name (Symbol)

    name of the GraphQL resolver to use as the default for fields of this type

  • config (Hash<Symbol, Object>)

    configuration parameters for the resolver

See Also:



90
91
92
93
94
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 90

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_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).

Examples:

Set ‘plural` and `singular` names

ElasticGraph.define_schema do |schema|
  schema.object_type "Person" do |t|
    t.field "id", "ID"

    # Results in `Query.people` and `Query.personAggregations`.
    t.root_query_fields plural: "people", singular: "person"

    t.index "people"
  end
end

Customize ‘Query` fields

ElasticGraph.define_schema do |schema|
  schema.object_type "Person" do |t|
    t.field "id", "ID"

    t.root_query_fields plural: "people", singular: "person" do |f|
      # Marks `Query.people` and `Query.personAggregations` as deprecated.
      f.directive "deprecated"
    end

    t.index "people"
  end
end

Parameters:

  • plural (String)

    the plural name of the entity; used for the root ‘Query` field that queries documents of this indexed type

  • singular (String, nil) (defaults to: nil)

    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).

Yields:

  • (SchemaElements::Field)

    field on the root ‘Query` type used to query this indexed type, to support customization



234
235
236
237
238
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 234

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_customizationsObject



253
254
255
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 253

def root_query_fields_customizations
  @root_query_fields_customizations
end

#runtime_metadata(extra_update_targets) ⇒ Object



188
189
190
191
192
193
194
195
196
197
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 188

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_nameString

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).

Returns:

  • (String)

    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).



248
249
250
# File 'lib/elastic_graph/schema_definition/mixins/has_indices.rb', line 248

def singular_root_query_field_name
  @singular_root_query_field_name || to_field_name(name)
end