Search

Sort and pagination

/ Sort, / Pagination, / Search

Sort and pagination #

Control which documents come back and in what order — sort, from/size, search_after/search_before, and total-hit accounting.

POST /my-collection/_search

How it works #

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.

...

Highlighting

/ Highlight, / Search

Highlighting #

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.

POST /my-collection/_search

How it works #

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.

...

Intervals and more-like-this queries

/ Search, / Query-Dsl

Intervals and more-like-this queries #

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”:

POST /my-collection/_search
{
  "query": {
    "intervals": {
      "body": {
        "all_of": {
          "ordered": true,
          "intervals": [
            { "match": { "query": "search engine", "max_gaps": 0, "ordered": true } },
            { "match": { "query": "ranking", "max_gaps": 2 } }
          ],
          "filter": { "not_overlapping": { "match": { "query": "deprecated" } } }
        }
      }
    }
  }
}

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.

...

Hybrid search and scoring pipeline

/ Hybrid, / Vector, / Rescoring, / Search

Hybrid search and scoring pipeline #

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.

...

Sandboxed scripting — scripted_metric, script_fields, script_score

/ Scripting, / Search, / Aggregation

Sandboxed scripting — scripted_metric, script_fields, script_score #

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 query

/ Semantic, / Vector, / Search

Semantic query #

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.

Examples #

POST /my-collection/_search
{"query": {"semantic": "find documents about search engines"}}

The clause composes inside bool like any other leaf — the text is embedded and the clause rewritten before execution:

...

Field collapsing

/ Collapse, / Deduplication, / Search

Field collapsing #

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).

POST /my-collection/_search

How it works #

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:

...

Streaming search

/ Stream, / Realtime, / Search

Streaming #

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.

POST /my-collection/_search

How it works #

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:

...

Script fields

/ Script_fields, / Search, / Scripting

Script fields #

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:

...

Search

/ Search

Search #

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.

...