Module: ElasticGraph::GraphQL::Aggregation
- Defined in:
- lib/elastic_graph/graphql/aggregation/key.rb,
lib/elastic_graph/graphql/aggregation/query.rb,
lib/elastic_graph/graphql/aggregation/computation.rb,
lib/elastic_graph/graphql/aggregation/path_segment.rb,
lib/elastic_graph/graphql/aggregation/query_adapter.rb,
lib/elastic_graph/graphql/aggregation/term_grouping.rb,
lib/elastic_graph/graphql/aggregation/resolvers/node.rb,
lib/elastic_graph/graphql/aggregation/query_optimizer.rb,
lib/elastic_graph/graphql/aggregation/field_path_encoder.rb,
lib/elastic_graph/graphql/aggregation/field_term_grouping.rb,
lib/elastic_graph/graphql/aggregation/resolvers/grouped_by.rb,
lib/elastic_graph/graphql/aggregation/script_term_grouping.rb,
lib/elastic_graph/graphql/aggregation/nested_sub_aggregation.rb,
lib/elastic_graph/graphql/aggregation/resolvers/count_detail.rb,
lib/elastic_graph/graphql/aggregation/date_histogram_grouping.rb,
lib/elastic_graph/graphql/aggregation/composite_grouping_adapter.rb,
lib/elastic_graph/graphql/aggregation/resolvers/sub_aggregations.rb,
lib/elastic_graph/graphql/aggregation/resolvers/aggregated_values.rb,
lib/elastic_graph/graphql/aggregation/non_composite_grouping_adapter.rb,
lib/elastic_graph/graphql/aggregation/resolvers/relay_connection_builder.rb
Defined Under Namespace
Modules: CompositeGroupingAdapter, FieldPathEncoder, Key, NonCompositeGroupingAdapter, Resolvers, TermGrouping Classes: DateHistogramGrouping, FieldTermGrouping, NestedSubAggregation, Query, QueryAdapter, QueryOptimizer, ScriptTermGrouping
Constant Summary collapse
- AggregationDetail =
The details of an aggregation level, including the ‘aggs` clauses themselves and `meta` that we want echoed back to us in the response for the aggregation level.
::Data.define( # Aggregation clauses that would go under `aggs. :clauses, # Custom metadata that will be echoed back to us in the response. # https://www.elastic.co/guide/en/elasticsearch/reference/8.11/search-aggregations.html#add-metadata-to-an-agg :meta ) do # @implements AggregationDetail # Wraps this aggregation detail in another aggregation layer for the given `grouping`, # so that we can easily build up the necessary multi-level aggregation structure. def wrap_with_grouping(grouping, query:) agg_key = grouping.key = grouping..merge({ # The response just includes tuples of values for the key of each bucket. We need to know what fields those # values come from, and this `meta` field indicates that. "grouping_fields" => [agg_key] }) inner_agg_hash = { "aggs" => (clauses unless (clauses || {}).empty?), "meta" => .merge() }.compact missing_bucket_inner_agg_hash = inner_agg_hash.key?("aggs") ? inner_agg_hash : {} # : ::Hash[::String, untyped] AggregationDetail.new( { agg_key => grouping.non_composite_clause_for(query).merge(inner_agg_hash), # Here we include a `missing` aggregation as a sibling to the main grouping aggregation. We do this # so that we get a bucket of documents that have `null` values for the field we are grouping on, in # order to provide the same behavior as the `CompositeGroupingAdapter` (which uses the built-in # `missing_bucket` option). # # To work correctly, we need to include this `missing` aggregation as a sibling at _every_ level of # the aggregation structure, and the `missing` aggregation needs the same child aggregations as the # main grouping aggregation has. Given the recursive nature of how this is applied, this results in # a fairly complex structure, even though conceptually the idea behind this isn't _too_ bad. Key.missing_value_bucket_key(agg_key) => { "missing" => {"field" => grouping.encoded_index_field_path} }.merge(missing_bucket_inner_agg_hash) }, {"buckets_path" => [agg_key]} ) end end
- Computation =
Represents some sort of aggregation computation (min, max, avg, sum, etc) on a field. For the relevant Elasticsearch docs, see: www.elastic.co/guide/en/elasticsearch/reference/7.12/search-aggregations-metrics-avg-aggregation.html www.elastic.co/guide/en/elasticsearch/reference/7.12/search-aggregations-metrics-max-aggregation.html www.elastic.co/guide/en/elasticsearch/reference/7.12/search-aggregations-metrics-min-aggregation.html www.elastic.co/guide/en/elasticsearch/reference/7.12/search-aggregations-metrics-sum-aggregation.html
::Data.define(:source_field_path, :computed_index_field_name, :detail) do # @implements Computation def key(aggregation_name:) Key::AggregatedValue.new( aggregation_name: aggregation_name, field_path: source_field_path.map(&:name_in_graphql_query), function_name: computed_index_field_name ).encode end def clause encoded_path = FieldPathEncoder.join(source_field_path.filter_map(&:name_in_index)) {detail.function.to_s => {"field" => encoded_path}} end end
- PathSegment =
::Data.define( # The name of this segment's field in the GraphQL query. If it's an aliased field, this # will be the alias name. :name_in_graphql_query, # The name of this segment's field in the datastore index. :name_in_index ) do # Factory method that aids in building a `PathSegment` for a given `field` and `lookahead` node. def self.for(lookahead:, field: nil) ast_node = lookahead.ast_nodes.first # : ::GraphQL::Language::Nodes::Field new( name_in_graphql_query: ast_node.alias || ast_node.name, name_in_index: field&.name_in_index&.to_s ) end end