Class: ElasticGraph::SchemaDefinition::SchemaElements::Relationship

Inherits:
Field
  • Object
show all
Defined in:
elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/relationship.rb

Overview

Wraps a Field to provide additional relationship-specific functionality when defining a field via TypeWithSubfields#relates_to_one or TypeWithSubfields#relates_to_many.

Examples:

Define relationships between two types

ElasticGraph.define_schema do |schema|
  schema.object_type "Orchestra" do |t|
    t.field "id", "ID"
    t.relates_to_many "musicians", "Musician", via: "orchestraId", dir: :in, singular: "musician" do |r|
      # In this block, `r` is a `Relationship`.
    end
    t.index "orchestras"
  end

  schema.object_type "Musician" do |t|
    t.field "id", "ID"
    t.field "instrument", "String"
    t.relates_to_one "orchestra", "Orchestra", via: "orchestraId", dir: :out do |r|
      # In this block, `r` is a `Relationship`.
    end
    t.index "musicians"
  end
end

Constant Summary

Constants included from Mixins::HasTypeInfo

Mixins::HasTypeInfo::CUSTOMIZABLE_DATASTORE_PARAMS

Instance Attribute Summary collapse

Attributes inherited from Field

#graphql_only, #name, #name_in_index, #resolver, #schema_def_state

Attributes included from Mixins::HasDocumentation

#doc_comment

Instance Method Summary collapse

Methods inherited from Field

#aggregatable?, #argument, #customize_aggregated_values_field, #customize_filter_field, #customize_grouped_by_field, #customize_highlights_field, #customize_sort_order_enum_values, #customize_sub_aggregations_field, #filterable?, #groupable?, #highlightable?, #json_schema, #mapping, #mapping_type, #on_each_generated_schema_element, #renamed_from, #resolve_with, #returnable?, #sortable?, #sourced_from, #sub_aggregatable?, #type

Methods included from Mixins::HasTypeInfo

#json_schema, #json_schema_options, #mapping, #mapping_options

Methods included from Mixins::HasDirectives

#directive, #directives, #directives_sdl

Methods included from Mixins::HasDocumentation

#append_to_documentation, #derived_documentation, #documentation, #formatted_documentation

Methods included from Mixins::VerifiesGraphQLName

verify_name!

Instance Attribute Details

Returns the type this relationship relates to.

Returns:



46
47
48
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/relationship.rb', line 46

def related_type
  @related_type
end

Instance Method Details

#additional_filter(filter) ⇒ void

This method returns an undefined value.

Adds additional filter conditions to a relationship beyond the foreign key.

Examples:

Define additional filter conditions on a relates_to_one relationship

ElasticGraph.define_schema do |schema|
  schema.object_type "Orchestra" do |t|
    t.field "id", "ID"
    t.relates_to_many "musicians", "Musician", via: "orchestraId", dir: :in, singular: "musician"
    t.relates_to_one "firstViolin", "Musician", via: "orchestraId", dir: :in do |r|
      r.additional_filter isFirstViolon: true
    end

    t.index "orchestras"
  end

  schema.object_type "Musician" do |t|
    t.field "id", "ID"
    t.field "instrument", "String"
    t.field "isFirstViolon", "Boolean"
    t.relates_to_one "orchestra", "Orchestra", via: "orchestraId", dir: :out
    t.index "musicians"
  end
end

Parameters:

  • filter (Hash<Symbol, Object>, Hash<String, Object>)

    additional filter conditions for this relationship



101
102
103
104
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/relationship.rb', line 101

def additional_filter(filter)
  stringified_filter = Support::HashUtil.stringify_keys(filter)
  @additional_filter = Support::HashUtil.deep_merge(@additional_filter, stringified_filter)
end

#equivalent_field(path, locally_named: path) ⇒ void

This method returns an undefined value.

Indicates that path (a field on the related type) is the equivalent of locally_named on this type.

Use this API to specify a local field's equivalent path on the related type. This must be used on relationships used by Field#sourced_from when the local type uses Indexing::Index#route_with or Indexing::Index#rollover so that ElasticGraph can determine what field from the related type to use to route the update requests to the correct index and shard.

Examples:

ElasticGraph.define_schema do |schema|
  schema.object_type "Campaign" do |t|
    t.field "id", "ID!"
    t.field "name", "String"
    t.field "createdAt", "DateTime"

    t.relates_to_one "launchPlan", "CampaignLaunchPlan", via: "campaignId", dir: :in do |r|
      r.equivalent_field "campaignCreatedAt", locally_named: "createdAt"
    end

    t.field "launchDate", "Date" do |f|
      f.sourced_from "launchPlan", "launchDate"
    end

    t.index "campaigns" do |i|
      i.rollover :yearly, "createdAt"
      i.has_had_multiple_sources!
    end
  end

  schema.object_type "CampaignLaunchPlan" do |t|
    t.field "id", "ID"
    t.field "campaignId", "ID"
    t.field "campaignCreatedAt", "DateTime"
    t.field "launchDate", "Date"

    t.index "campaign_launch_plans"
  end
end

Parameters:

  • path (String)

    path to a routing or rollover field on the related type

  • locally_named (String) (defaults to: path)

    path on the local type to the equivalent field



146
147
148
149
150
151
152
153
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/relationship.rb', line 146

def equivalent_field(path, locally_named: path)
  if @equivalent_field_paths_by_local_path.key?(locally_named)
    raise Errors::SchemaError, "`equivalent_field` has been called multiple times on `#{parent_type.name}.#{name}` with the same " \
      "`locally_named` value (#{locally_named.inspect}), but each local field can have only one `equivalent_field`."
  else
    @equivalent_field_paths_by_local_path[locally_named] = path
  end
end

#parent_relationship(parent_type_name, parent_relationship_name, parent_field_name: nil) ⇒ void

This method returns an undefined value.

Indicates that this relationship chains through a parent relationship to reach the root indexed type.

Use this API when defining relationships on embedded (non-indexed) types that need to use sourced_from on their fields. By chaining relationships through parent types, ElasticGraph can resolve the path from the nested type up to the root indexed type and properly update nested fields when source events arrive.

Examples:

Define a nested sourced_from relationship chain

ElasticGraph.define_schema do |schema|
  schema.object_type "Team" do |t|
    t.field "id", "ID!"
    t.field "name", "String"
    t.field "players", "[Player!]!" do |f|
      f.mapping type: "nested"
    end
    t.relates_to_many "statLines", "StatLine", via: "teamId", dir: :in, indexing_only: true
    t.index "teams" do |i|
      i.has_had_multiple_sources!
    end
  end

  schema.object_type "Player" do |t|
    t.field "id", "ID!"
    t.field "name", "String"
    t.field "goalsScored", "Int" do |f|
      f.sourced_from "statLine", "goals"
    end
    t.relates_to_one "statLine", "StatLine", via: "playerId", dir: :in, indexing_only: true do |r|
      r.parent_relationship "Team", "statLines"
    end
  end

  schema.object_type "StatLine" do |t|
    t.field "id", "ID!"
    t.field "teamId", "ID"
    t.field "playerId", "ID"
    t.field "goals", "Int"
    t.index "stat_lines"
  end
end

Parameters:

  • parent_type_name (String)

    name of the parent type in the nesting hierarchy

  • parent_relationship_name (String)

    name of the relationship on the parent type

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

    name of the field on the parent type that embeds this type. When omitted, auto-discovered by finding the field on the parent type whose type matches this type. Required when the parent type has multiple fields of this type.



201
202
203
204
205
206
207
208
209
210
211
212
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/relationship.rb', line 201

def parent_relationship(parent_type_name, parent_relationship_name, parent_field_name: nil)
  if @parent_ref
    raise Errors::SchemaError, "`parent_relationship` has been called multiple times on `#{parent_type.name}.#{name}`, " \
      "but each relationship can have only one `parent_relationship`."
  end

  @parent_ref = ParentRef.new(
    type_ref: schema_def_state.type_ref(parent_type_name),
    relationship_name: parent_relationship_name,
    field_name: parent_field_name
  )
end