Query planner that executes search queries against the inverted index.
Takes a parsed query AST and:
- Analyzes each term from the query
- Looks up posting lists from
search_post_terms— one multi-partition, fully-paged query per analyzed term (shard IN (0..n-1)); terms within a group are fetched concurrently - Applies boolean operations (AND/OR/NOT)
- Returns a map of
%{post_id => [{term, tf}]}for downstream ranking, keyed by the real analyzed terms so per-term statistics (doc frequency) remain usable
Boolean semantics
ANDgroups (explicit or implicit) — intersection of all positive terms, minus documents matching any excluded term (NOT termor-term)ORgroups — union of branches; each branch is evaluated as an independent AND group- Phrases (
"phoenix framework") — matched as an unordered AND of their analyzed words. The index does not store token positions, so word order is not verified. - Stop words contribute nothing: a positive term that analyzes to zero
terms is dropped, and a query with no remaining positive terms fails
with
{:error, :missing_positive_term}.
Summary
Types
Matched documents with their per-term scores.
Functions
Plans and executes a parsed query against the inverted index.
Types
@type scored_results() :: %{required(String.t()) => [{String.t(), non_neg_integer()}]}
Matched documents with their per-term scores.
Functions
@spec plan(module(), String.t(), AshScylla.Search.Query.Parser.ast_node(), keyword()) :: {:ok, scored_results()} | {:error, term()}
Plans and executes a parsed query against the inverted index.
Returns {:ok, results} where results maps each matching post_id to its
[{term, tf}] contributions, or {:error, reason}.
Options
:num_shards— number of shards used at indexing time (default: 16):analyzer_opts— options forwarded to the analyzer
Errors
{:error, :invalid_num_shards}—:num_shardsis less than 1{:error, :missing_positive_term}— the query has no searchable positive terms (e.g. only stop words or only exclusions){:error, reason}— propagated from the repo lookup