Skip to main content

Crate flusso_query

Crate flusso_query 

Source
Expand description

flusso-query — a typed query client for a flusso-maintained search index.

Targets OpenSearch and Elasticsearch 7.x, which share the _search query DSL this crate emits; any future backend divergence is handled on the Client, not by separate crates.

This is the runtime layer described in CLIENT.md: the transport, the field-handle / Query / Search builder, and the typed SearchResponse. It is generic over the caller’s document type T.

§What this first cut covers

  • Client transport over OpenSearch (connect, basic_auth, search, msearch, get).
  • Field handles (Keyword, Text, Bool, Number, Date, Nested, Binary, Json) with operators that build a Query.
  • Query composition (and / or / not) and the Search bool-clause builder (query / filter / must_not / should, plus sort / from / size / raw). A Search is a plain client-free value — build it anywhere, store and reuse it; a Client appears only at the terminals: Search::send (a typed page), Search::ids (a page of bare document ids, _source: false), or Search::count (just the number of matches, via _count).
  • Several searches in one round-trip: Client::msearch (a tuple of &Search<T>, mixed document types, one typed response per slot) and Client::msearch_all (a slice of one type).
  • Combined (blended) search: FlussoMultiDocument — a caller-owned enum with one variant per document type — and its MultiSearch builder. One query across all the union’s indexes, one relevance-ranked result list, each hit decoded into the variant matching its physical _index.
  • Typed SearchResponse / Hit.

Also covered: optional filters (Option<Q> is a Query); object/to-one-join handles (Object); shaping returned nested arrays (Search::filter_nested with Nested::matching, via inner_hits); and scope-tagged queries — Query<S> carries the scope S it was built in (Root for the document root and flattened objects, the element type for a nested array), so a nested query must be lifted through Nested::any/Nested::all before it can join a root query; the compiler enforces it.

§Not yet built (see CLIENT.md for the endgame)

  • The #[derive(FlussoDocument)] and #[derive(FlussoMultiDocument)] proc-macros live in flusso-query-derive (the derive feature). Without them, document structs + handles and union impls are written by hand — exactly the calls this crate exposes (see the integration tests).
  • filter_nested’s keep_source() opt-out (it always replaces the array in source today) and a typed hit.nested(handle) accessor.

§Example (hand-written until the derive lands)

use flusso_query::{Client, Keyword, Number, Nested};

#[derive(serde::Deserialize)]
struct User {
    email: String,
    #[serde(rename = "orderCount")]
    order_count: i64,
}

impl User {
    fn email() -> Keyword { Keyword::at("email") }
    fn order_count() -> Number<i64> { Number::at("orderCount") }
    fn query() -> flusso_query::Search<User> {
        flusso_query::Search::new("users", "xxxxxx")
    }
}

// A query is a plain value — no client involved while building it.
let busy = User::query()
    .filter(User::email().eq("ada@example.com"))
    .filter(User::order_count().gte(5))
    .size(20);

// The client appears once, when it's time to run.
let client = Client::connect("https://localhost:9200")?;
let page = busy.send(&client).await?;
println!("{} matches", page.total);

Modules§

kind
Field-category markers for FlussoValue. Zero-size and uninhabited — they exist only as the K type parameter, so one type can be a valid value for several kinds (e.g. String is a kind::Keyword, kind::Text, and kind::Date value).

Structs§

Binary
A binary field — base64-encoded, not searchable. Only existence.
Bool
A boolean field.
Client
A connection to an OpenSearch cluster.
Date
A date/timestamp field. Bounds are ISO-8601 strings.
Geo
A geo_point field — distance, bounding-box, and polygon queries, plus sort-by-distance.
GeoPoint
A geographic point — latitude/longitude in degrees.
Hit
One search hit: the typed document plus its envelope metadata.
Json
An untyped object/json field. The escape hatch: existence, or a raw clause spliced in verbatim.
Keyword
An exact, aggregatable string field (keyword, enum, uuid).
MultiSearch
A typed query across every index of a FlussoMultiDocument union — the blended counterpart of Search, with the same clause builder and the same client-free shape.
Nested
A nested array of objects. E is the enclosing scope (where queries over this array land — Root at the top level, the parent element type when deeper); C is the child scope (the element type). Lifting a child query (Query<C>) through any/all produces a Query<E>.
NestedProjection
A request to shape one nested array in the results (via inner_hits).
Number
A numeric field. T is the Rust scalar; S is the scope (defaults to Root, so Number<i64> is a root-scope handle).
Object
An object sub-document — a group or a to-one (belongs_to/has_one) join. Objects are flattened, so their sub-fields are queried by their own scope-S dotted-path handles directly (Account::tier()); this handle is for the object itself. S is the enclosing scope (Root at the top level).
Query
A composable query clause in scope S.
Root
The default query scope — the document root. Root fields and flattened object / to-one-join sub-fields share it.
Search
A typed query against one index — a plain, client-free value.
SearchResponse
A page of search results.
Sort
A single sort key, produced by .asc() / .desc() on a sortable handle (or Geo::distance_sort). Scope-free.
Text
An analyzed full-text field (text, identifier). No exact eq.

Enums§

Error
Anything that can go wrong building a request, talking to OpenSearch, or decoding a response.
SortOrder
Sort direction.

Traits§

AsQuery
Anything that can become a query clause in scope S. A clause may be absent (into_query returns None) — that’s what makes an Option<Query<S>> a first-class optional filter.
FlussoDocument
A document type bound to a flusso-maintained index — the trait that #[derive(FlussoDocument)] implements.
FlussoMultiDocument
A union of FlussoDocument types searched together — one query, one blended result list, each hit decoded into the variant matching its index.
FlussoValue
A Rust type usable where a field of kind K is expected: as the field type in a #[derive(FlussoDocument)] struct, and (for kind::Keyword) as a query value on Keyword::eq/Keyword::in_.
MsearchBundle
A bundle of searches runnable in one Client::msearch request — implemented for tuples of &Search<T> up to arity 8, each slot with its own document type. You don’t implement this; you pass tuples.

Functions§

multi_match
A cross-field full-text query over several Text fields in the same scope.

Type Aliases§

Result
A Result whose error is this crate’s Error.