Skip to main content

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}