mod aggregation;
mod bm25;
pub mod explain;
pub mod feedback;
mod fuzzy;
mod hybrid;
mod metadata;
pub mod mmr;
mod rerank;
pub mod result_cache;
pub mod semantic_cache;
pub mod utility;
#[cfg(feature = "neural-rerank")]
pub mod neural_rerank;
pub use aggregation::*;
pub use bm25::*;
pub use explain::*;
pub use fuzzy::*;
pub use hybrid::*;
pub use metadata::*;
pub use mmr::*;
pub use rerank::*;
pub use result_cache::*;
use crate::types::SearchStrategy;
pub fn select_search_strategy(query: &str) -> SearchStrategy {
let query = query.trim();
let word_count = query.split_whitespace().count();
let has_quotes = query.contains('"');
let has_operators = query.contains(':')
|| query.contains(" AND ")
|| query.contains(" OR ")
|| query.contains(" NOT ");
let has_special = query.contains('*') || query.contains('?');
if has_quotes || has_operators || has_special {
return SearchStrategy::KeywordOnly;
}
if word_count <= 2 {
return SearchStrategy::KeywordOnly;
}
if word_count >= 8 {
return SearchStrategy::SemanticOnly;
}
SearchStrategy::Hybrid
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum DedupeStrategy {
#[default]
ById,
ByContentHash,
}
#[derive(Debug, Clone)]
pub struct SearchConfig {
pub short_threshold: usize,
pub long_threshold: usize,
pub min_score: f32,
pub keyword_weight: f32,
pub semantic_weight: f32,
pub rrf_k: f32,
pub project_context_boost: f32,
pub project_context_path: Option<String>,
pub dedupe_strategy: DedupeStrategy,
}
impl Default for SearchConfig {
fn default() -> Self {
Self {
short_threshold: 2,
long_threshold: 8,
min_score: 0.1,
keyword_weight: 0.4,
semantic_weight: 0.6,
rrf_k: 60.0,
project_context_boost: 0.2,
project_context_path: None,
dedupe_strategy: DedupeStrategy::default(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_strategy_selection() {
assert_eq!(select_search_strategy("auth"), SearchStrategy::KeywordOnly);
assert_eq!(
select_search_strategy("jwt token"),
SearchStrategy::KeywordOnly
);
assert_eq!(
select_search_strategy("\"exact phrase\""),
SearchStrategy::KeywordOnly
);
assert_eq!(
select_search_strategy("auth AND jwt"),
SearchStrategy::KeywordOnly
);
assert_eq!(
select_search_strategy("how does authentication work"),
SearchStrategy::Hybrid
);
assert_eq!(
select_search_strategy(
"explain the authentication flow with jwt tokens and refresh mechanism"
),
SearchStrategy::SemanticOnly
);
}
}