1use crate::lexical::query::Query;
2use crate::lexical::search::searcher::LexicalSearchRequest;
3use crate::vector::store::request::VectorSearchRequest;
4
5pub struct SearchRequest {
7 pub lexical_search_request: Option<LexicalSearchRequest>,
9
10 pub vector_search_request: Option<VectorSearchRequest>,
12
13 pub limit: usize,
15
16 pub offset: usize,
18
19 pub fusion_algorithm: Option<FusionAlgorithm>,
21
22 pub filter_query: Option<Box<dyn Query>>,
25}
26
27#[derive(Debug, Clone, Copy)]
29pub enum FusionAlgorithm {
30 RRF {
33 k: f64,
35 },
36
37 WeightedSum {
40 lexical_weight: f32,
42 vector_weight: f32,
44 },
45}
46
47impl Default for SearchRequest {
48 fn default() -> Self {
49 Self {
50 lexical_search_request: None,
51 vector_search_request: None,
52 limit: 10,
53 offset: 0,
54 fusion_algorithm: None,
55 filter_query: None,
56 }
57 }
58}
59
60pub struct SearchRequestBuilder {
61 request: SearchRequest,
62}
63
64impl Default for SearchRequestBuilder {
65 fn default() -> Self {
66 Self::new()
67 }
68}
69
70impl SearchRequestBuilder {
71 pub fn new() -> Self {
72 Self {
73 request: SearchRequest::default(),
74 }
75 }
76
77 pub fn lexical_search_request(mut self, request: LexicalSearchRequest) -> Self {
79 self.request.lexical_search_request = Some(request);
80 self
81 }
82
83 pub fn vector_search_request(mut self, request: VectorSearchRequest) -> Self {
85 self.request.vector_search_request = Some(request);
86 self
87 }
88
89 pub fn limit(mut self, limit: usize) -> Self {
90 self.request.limit = limit;
91 self
92 }
93
94 pub fn offset(mut self, offset: usize) -> Self {
95 self.request.offset = offset;
96 self
97 }
98
99 pub fn fusion_algorithm(mut self, fusion: FusionAlgorithm) -> Self {
100 let fusion = match fusion {
102 FusionAlgorithm::WeightedSum {
103 lexical_weight,
104 vector_weight,
105 } => FusionAlgorithm::WeightedSum {
106 lexical_weight: lexical_weight.clamp(0.0, 1.0),
107 vector_weight: vector_weight.clamp(0.0, 1.0),
108 },
109 other => other,
110 };
111 self.request.fusion_algorithm = Some(fusion);
112 self
113 }
114
115 pub fn filter_query(mut self, query: Box<dyn Query>) -> Self {
116 self.request.filter_query = Some(query);
117 self
118 }
119
120 pub fn add_field_boost(mut self, field: impl Into<String>, boost: f32) -> Self {
125 if let Some(ref mut lex) = self.request.lexical_search_request {
126 lex.field_boosts.insert(field.into(), boost);
127 }
128 self
129 }
130
131 pub fn build(self) -> SearchRequest {
132 self.request
133 }
134}
135
136#[derive(Debug, Clone)]
137pub struct SearchResult {
138 pub id: String,
140 pub score: f32,
141 pub document: Option<crate::data::Document>,
142}