nodedb_types/text_search.rs
1//! Text search parameter types shared across the NodeDb trait boundary.
2//!
3//! These are the user-facing knobs for full-text search queries. The
4//! implementation (BM25 scoring, BMW pruning, fuzzy matching) lives in
5//! `nodedb-fts`. These types are in `nodedb-types` so both `nodedb-client`
6//! (trait definition) and all implementations can use them without pulling
7//! in the full FTS engine as a dependency.
8
9use serde::{Deserialize, Serialize};
10
11/// Boolean query mode for full-text search.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
13pub enum QueryMode {
14 /// Any query term can match (union). Most permissive — best recall.
15 #[default]
16 Or,
17 /// All query terms must match (intersection). More precise — best precision.
18 And,
19}
20
21/// BM25 ranking parameters.
22///
23/// Controls how term frequency and document length affect scoring.
24/// The defaults (`k1 = 1.2`, `b = 0.75`) are standard Okapi BM25 values
25/// that work well across most corpora.
26#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
27pub struct Bm25Params {
28 /// Term frequency saturation factor.
29 /// Higher values give more weight to repeated terms. Range: 0.5–3.0.
30 /// Default: 1.2.
31 pub k1: f32,
32 /// Length normalization factor.
33 /// `0.0` = no length normalization, `1.0` = full normalization.
34 /// Default: 0.75.
35 pub b: f32,
36}
37
38impl Default for Bm25Params {
39 fn default() -> Self {
40 Self { k1: 1.2, b: 0.75 }
41 }
42}
43
44/// Per-query parameters for full-text search.
45///
46/// These are the knobs that vary per-query. BM25 scoring parameters (`k1`, `b`)
47/// are corpus-level settings configured at collection creation time — they depend
48/// on document characteristics (length, vocabulary), not on individual queries.
49///
50/// Pass [`TextSearchParams::default()`] for standard OR-mode non-fuzzy search.
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct TextSearchParams {
53 /// Boolean query mode: `Or` (any term) or `And` (all terms).
54 /// Default: `Or`.
55 pub mode: QueryMode,
56 /// Enable fuzzy (Levenshtein distance) matching for approximate lookup.
57 /// Fuzzy hits are scored with a discount relative to exact matches.
58 /// Default: `false`.
59 pub fuzzy: bool,
60}
61
62impl Default for TextSearchParams {
63 fn default() -> Self {
64 Self {
65 mode: QueryMode::Or,
66 fuzzy: false,
67 }
68 }
69}