sort is an array of sort clauses evaluated in order; the first clause
that produces a difference decides the order. Sorting on an indexed field
lets the collector skip documents that cannot make the cut (early
termination), so field sorts — and _doc above all — are cheaper than
score sorts, not just differently ordered.
Ask for matched fragments of your text fields back alongside each hit, with
the matched terms wrapped in tags — ready to render as a search result list.
Highlighting is an engine-native enrich step that runs on the returned page
only — after ranking and truncation, exactly like
script
fields. It has two phases (lib/engine/src/search/highlight/):
1. Term extraction. The engine walks the query tree and collects
(field, term) pairs worth highlighting: term, terms, fuzzy,
span_term, intervals, match, multi_match, match_phrase, and
bool clauses. Text queries (match, multi_match, phrase) are
re-tokenized through the field’s search analyzer (or the query’s explicit
analyzer override), so the highlighted terms mirror what the query
scored. must_not clauses never contribute — documents excluded by them
get no tags from them. match_all, range, geo and
vector queries carry nothing to highlight.
Two Elasticsearch-compatible queries landed natively in the engine —
no more shape-shifting through match_phrase compositions.
intervals is a rule language over term positions. Say “these two
phrases within two positions of each other, but only if neither
overlaps this third one”:
Eight rule shapes (match, all_of, any_of, prefix, wildcard,
fuzzy, regexp, range) and eight positional filter predicates
(containing, before, not_overlapping, …) compose into one tree.
Unsupported knobs are rejected with named errors instead of silently
ignored — ask for a script filter and you will be told no.
Pizza runs lexical (BM25) and vector retrieval side by side and gives you
explicit, composable stages to combine and re-shape scores:
graph LR
B("bm25 leg") --> F("fuse rrf / linear / disjmax")
V("vector leg") --> F
F --> SC("score_functions per-document function scoring")
P["a plain query, no retrieve"] --> SC
SC --> RS("rescore second pass on the top window")
RS --> H["one ranked list"]
Every stage is optional and combines with a plain query: use
score_functions alone on a keyword search, or the full chain for
hybrid retrieval.
Scripts landed across the whole request path — the engine runs the
examples from the Elasticsearch docs unmodified. The engine is Rhai
rather than Painless, but doc['x'].value, _score and
params.<name> mean what they mean there.
Aggregations.scripted_metric
runs your own four-phase map/reduce — init_script, map_script,
combine_script, reduce_script — with per-segment states folded at the
end. The single-value metric aggs (sum, avg, min, max,
cardinality) accept a script in place of a field
(
details),
and pipeline aggregations keep their buckets_path arithmetic.
Semantic search with zero field knowledge: the vector field and the
embedding model resolve from the collection schema, and the request is
plain text — the retrieval question asked without naming a field, a
model, or a vector.
Collapse the result list so each distinct value of a field appears at most
once — “best product per merchant”, “best article per author” — without a
terms aggregation, keeping full hit semantics (scores, source, highlight).
Collapse is engine-native and runs as a post-retrieval step. The collector
normally stops at from + size, but collapse pages over GROUPS, so the
engine first gathers a wider window — max(1000, from + size) hits
(COLLAPSE_WINDOW in lib/engine/src/search/mod.rs) — in request sort
order, then:
Search on Pizza is real-time — documents are visible the moment they are
written. The stream block attaches delivery directives to a search
request: how the engine should pace and batch the emission of a result
that outgrows one response, instead of making the client poll.
stream is a native, parsed block of the Pizza request DSL
(StreamConfig in lib/engine/src/search/request/mod.rs) — accepted,
validated, and carried through the engine with every request. Its knobs
describe the emission strategy of the search pipeline:
Compute extra values for each hit, at fetch time, from the hit’s own
_source — like
highlighting, but producing numbers and
strings instead of fragments. Scripts run on Pizza’s sandboxed script
engine (see
the script language reference),
only for the hits actually returned on the page.
Every returned hit carries the computed values under fields, as arrays:
A search query, or query, is a request for information about documents in Pizza
collections.
A search consists of one or more queries that are combined and sent to Pizza.
Documents that match a search’s queries are returned in the hits, or search
results, of the response.
A search may also contain additional information used to better process its
queries. For example, a search may be limited to a specific collection or only
return a specific number of results.