use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SparseVector {
pub indices: Vec<usize>,
pub values: Vec<f32>,
}
impl SparseVector {
pub fn new(indices: Vec<usize>, values: Vec<f32>) -> Result<Self, String> {
if indices.len() != values.len() {
return Err("Indices and values must have the same length".to_string());
}
if indices.is_empty() {
return Err("Sparse vector cannot be empty".to_string());
}
for &idx in &indices {
if idx == usize::MAX {
return Err("Indices must be valid".to_string());
}
}
for &val in &values {
if val.is_nan() || val.is_infinite() {
return Err("Values must be finite numbers".to_string());
}
}
Ok(Self { indices, values })
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HybridSearchRequest {
pub collection: String,
pub query: String,
pub query_sparse: Option<SparseVector>,
#[serde(default = "default_alpha")]
pub alpha: f32,
#[serde(default = "default_algorithm")]
pub algorithm: HybridScoringAlgorithm,
#[serde(default = "default_dense_k")]
pub dense_k: usize,
#[serde(default = "default_sparse_k")]
pub sparse_k: usize,
#[serde(default = "default_final_k")]
pub final_k: usize,
}
fn default_alpha() -> f32 {
0.7
}
fn default_algorithm() -> HybridScoringAlgorithm {
HybridScoringAlgorithm::ReciprocalRankFusion
}
fn default_dense_k() -> usize {
20
}
fn default_sparse_k() -> usize {
20
}
fn default_final_k() -> usize {
10
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum HybridScoringAlgorithm {
#[serde(rename = "rrf")]
ReciprocalRankFusion,
#[serde(rename = "weighted")]
WeightedCombination,
#[serde(rename = "alpha")]
AlphaBlending,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HybridSearchResult {
pub id: String,
pub score: f32,
pub vector: Option<Vec<f32>>,
pub payload: Option<HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HybridSearchResponse {
pub results: Vec<HybridSearchResult>,
pub query: String,
pub query_sparse: Option<SparseVectorResponse>,
pub alpha: f32,
pub algorithm: String,
pub duration_ms: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SparseVectorResponse {
pub indices: Vec<usize>,
pub values: Vec<f32>,
}