# `Selecto.Schema.Join`

# Join Configuration and Patterns

This module handles join configuration for various database join patterns,
providing simplified configuration helpers for common scenarios.

## Available Join Types

### :dimension (Existing)
Basic dimension table join with ID filtering and name display.
- `dimension`: Field to use for display (required)
- `name`: Display name for the join (optional)

### :tagging (New)
Many-to-many relationship through a join table (e.g., posts <-> tags).
- `tag_field`: Field to display from tag table (default: :name)
- `name`: Display name for the join (optional)
Creates custom columns for tag aggregation and faceted filtering.

### :hierarchical (New)
Self-referencing hierarchical relationships with multiple implementation patterns:
- `hierarchy_type`: :adjacency_list, :materialized_path, or :closure_table
- `depth_limit`: Maximum recursion depth for adjacency lists (default: 5)
- `path_field`: Field containing path for materialized path pattern (default: :path)
- `path_separator`: Separator used in path field (default: "/")
- `closure_table`: Name of closure table for closure table pattern
- `ancestor_field`, `descendant_field`, `depth_field`: Closure table field names

### :star_dimension (New)
Optimized for OLAP star schema dimensions.
- `display_field`: Field to use for dimension display (default: :name)
- `name`: Display name for the dimension (optional)
Creates faceted filters optimized for aggregation queries.

### :snowflake_dimension (New)
Normalized dimension tables requiring additional joins.
- `display_field`: Field to use for dimension display (default: :name)
- `normalization_joins`: List of additional joins needed for full context
- `name`: Display name for the dimension (optional)

## Standard Join Types (Default behavior)
- one_to_one - Standard lookup with all columns available
- one_to_many - Treated like one-to-one
- belongs_to - Treated like one-to-one

## Configuration Examples

```elixir
joins: %{
  # Many-to-many tagging
  tags: %{type: :tagging, tag_field: :name},

  # Hierarchical adjacency list
  manager: %{type: :hierarchical, hierarchy_type: :adjacency_list, depth_limit: 5},

  # Star schema dimension
  customer: %{type: :star_dimension, display_field: :full_name},

  # Snowflake dimension with normalization
  category: %{
    type: :snowflake_dimension,
    display_field: :name,
    normalization_joins: [%{table: "category_groups", alias: "cg"}]
  }
}
```

# `recurse_joins`

```elixir
@spec recurse_joins(Selecto.Types.source(), Selecto.Types.domain()) :: %{
  required(atom()) =&gt; Selecto.Types.processed_join()
}
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
