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
clear_subselects(selecto)
@spec clear_subselects(Selecto.Types.t()) :: Selecto.Types.t()
Clear all subselect configurations from a Selecto query.
get_subselect_configs(selecto)
@spec get_subselect_configs(Selecto.Types.t()) :: [Selecto.Types.subselect_selector()]
Get all subselect configurations from a Selecto query.
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.
has_subselects?(selecto)
@spec has_subselects?(Selecto.Types.t()) :: boolean()
Check if a Selecto query has subselect configuration applied.
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.
subselect(selecto, field_specs, opts \\ [])
@spec subselect( Selecto.Types.t(), [String.t() | Selecto.Types.subselect_selector()], keyword() ) :: Selecto.Types.t()
Add subselect fields to return related data as aggregated arrays.
parameters
Parameters
selecto- The Selecto structfield_specs- List of field specifications with optional configurationopts- 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.
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.