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