Class: ElasticGraph::GraphQL::Resolvers::QuerySource

Inherits:
GraphQL::Dataloader::Source
  • Object
show all
Defined in:
lib/elastic_graph/graphql/resolvers/query_source.rb

Overview

Provides a way to avoid N+1 request problems by batching up multiple datastore queries into one ‘msearch` request. In general, it is recommended that you use this from any resolver that needs to query the datastore, to maximize our ability to combine multiple datastore requests. Importantly, this should never be instantiated directly; instead use the `execute` method from below.

Note: ‘NestedRelationshipsSource` implements further optimizations on top of this, and should be used rather than this class when applicable.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(datastore_router, query_tracker, opaque_id_parts = []) ⇒ QuerySource

Returns a new instance of QuerySource.



23
24
25
26
27
# File 'lib/elastic_graph/graphql/resolvers/query_source.rb', line 23

def initialize(datastore_router, query_tracker, opaque_id_parts = [])
  @datastore_router = datastore_router
  @query_tracker = query_tracker
  @opaque_id_parts = opaque_id_parts
end

Class Method Details

.execute_many(queries, for_context:) ⇒ Object



38
39
40
41
42
43
44
45
46
# File 'lib/elastic_graph/graphql/resolvers/query_source.rb', line 38

def self.execute_many(queries, for_context:)
  datastore_router = for_context.fetch(:datastore_search_router)
  query_tracker = for_context.fetch(:elastic_graph_query_tracker)
  opaque_id_parts = datastore_opaque_id_parts_for(for_context)
  dataloader = for_context.dataloader

  responses = dataloader.with(self, datastore_router, query_tracker, opaque_id_parts).load_all(queries)
  queries.zip(responses).to_h
end

.execute_one(query, for_context:) ⇒ Object



48
49
50
# File 'lib/elastic_graph/graphql/resolvers/query_source.rb', line 48

def self.execute_one(query, for_context:)
  execute_many([query], for_context: for_context).fetch(query)
end

Instance Method Details

#fetch(queries) ⇒ Object



29
30
31
32
33
34
35
36
# File 'lib/elastic_graph/graphql/resolvers/query_source.rb', line 29

def fetch(queries)
  responses_by_query = @datastore_router.msearch(
    queries,
    query_tracker: @query_tracker,
    opaque_id_parts: @opaque_id_parts
  )
  queries.map { |q| responses_by_query.fetch(q) }
end