Selecto.Subselect (Selecto v0.3.8)

Subselect functionality for array-based data aggregation from related tables.

The Subselect feature enables returning related data as arrays or JSON objects, preventing result set denormalization while maintaining relational context.

examples

Examples

# Basic subselect - get orders as JSON array for each attendee
selecto
|> Selecto.select(["attendee[name]"])
|> Selecto.subselect([
     "order[product_name]", 
     "order[quantity]"
   ])
|> Selecto.filter([{"event_id", 123}])

# This generates SQL like:
# SELECT 
#   a.name,
#   (SELECT json_agg(json_build_object(
#     'product_name', o.product_name,
#     'quantity', o.quantity
#   )) FROM orders o WHERE o.attendee_id = a.attendee_id) as orders
# FROM attendees a
# WHERE a.event_id = 123

aggregation-formats

Aggregation Formats

  • :json_agg - Returns JSON array of objects (default)
  • :array_agg - Returns PostgreSQL array
  • :string_agg - Returns delimited string
  • :count - Returns count of related records

Link to this section Summary

Functions

Clear all subselect configurations from a Selecto query.

Get all subselect configurations from a Selecto query.

Group subselects by their target table for efficient SQL generation.

Check if a Selecto query has subselect configuration applied.

Resolve the join path needed to reach a target schema from the current context.

Add subselect fields to return related data as aggregated arrays.

Validate that a subselect configuration is valid for the given domain.

Link to this section Functions

Link to this function

clear_subselects(selecto)

@spec clear_subselects(Selecto.Types.t()) :: Selecto.Types.t()

Clear all subselect configurations from a Selecto query.

Link to this function

get_subselect_configs(selecto)

@spec get_subselect_configs(Selecto.Types.t()) :: [Selecto.Types.subselect_selector()]

Get all subselect configurations from a Selecto query.

Link to this function

group_subselects_by_table(selecto)

@spec group_subselects_by_table(Selecto.Types.t()) :: %{
  required(atom()) => [Selecto.Types.subselect_selector()]
}

Group subselects by their target table for efficient SQL generation.

Link to this function

has_subselects?(selecto)

@spec has_subselects?(Selecto.Types.t()) :: boolean()

Check if a Selecto query has subselect configuration applied.

Link to this function

resolve_join_path(selecto, target_schema)

@spec resolve_join_path(Selecto.Types.t(), atom()) ::
  {:ok, [atom()]} | {:error, String.t()}

Resolve the join path needed to reach a target schema from the current context.

If we're in a pivoted context, the path is calculated from the pivot target. Otherwise, the path is calculated from the source.

Link to this function

subselect(selecto, field_specs, opts \\ [])

Add subselect fields to return related data as aggregated arrays.

parameters

Parameters

  • selecto - The Selecto struct
  • field_specs - List of field specifications with optional configuration
  • opts - Global options for subselects

field-specification-formats

Field Specification Formats

# Simple field list (uses defaults)
["order[product_name]", "order[quantity]"]

# With custom configuration
[
  %{
    fields: ["product_name", "quantity"],
    target_schema: :order,
    format: :json_agg,
    alias: "order_items"
  }
]

options

Options

  • :format - Default aggregation format (:json_agg, :array_agg, :string_agg, :count)
  • :alias_prefix - Prefix for generated field aliases
  • :order_by - Default ordering for aggregated results

returns

Returns

Updated Selecto struct with subselect configuration applied.

Link to this function

validate_subselect_config(selecto, subselect_config)

@spec validate_subselect_config(Selecto.Types.t(), Selecto.Types.subselect_selector()) ::
  :ok | {:error, String.t()}

Validate that a subselect configuration is valid for the given domain.