hermes_core/query/
traits.rs1use std::future::Future;
6use std::pin::Pin;
7
8use crate::segment::SegmentReader;
9use crate::{DocId, Result, Score};
10
11#[derive(Debug, Clone, Copy)]
13pub struct Bm25Params {
14 pub k1: f32,
16 pub b: f32,
18}
19
20impl Default for Bm25Params {
21 fn default() -> Self {
22 Self { k1: 1.2, b: 0.75 }
23 }
24}
25
26#[cfg(not(target_arch = "wasm32"))]
28pub type ScorerFuture<'a> = Pin<Box<dyn Future<Output = Result<Box<dyn Scorer + 'a>>> + Send + 'a>>;
29#[cfg(target_arch = "wasm32")]
30pub type ScorerFuture<'a> = Pin<Box<dyn Future<Output = Result<Box<dyn Scorer + 'a>>> + 'a>>;
31
32#[cfg(not(target_arch = "wasm32"))]
34pub type CountFuture<'a> = Pin<Box<dyn Future<Output = Result<u32>> + Send + 'a>>;
35#[cfg(target_arch = "wasm32")]
36pub type CountFuture<'a> = Pin<Box<dyn Future<Output = Result<u32>> + 'a>>;
37
38#[cfg(not(target_arch = "wasm32"))]
40pub type DocPredicate<'a> = Box<dyn Fn(DocId) -> bool + Send + Sync + 'a>;
41#[cfg(target_arch = "wasm32")]
42pub type DocPredicate<'a> = Box<dyn Fn(DocId) -> bool + 'a>;
43
44#[derive(Debug, Clone)]
46pub struct TermQueryInfo {
47 pub field: crate::dsl::Field,
49 pub term: Vec<u8>,
51}
52
53#[derive(Debug, Clone, Copy)]
55pub struct SparseTermQueryInfo {
56 pub field: crate::dsl::Field,
58 pub dim_id: u32,
60 pub weight: f32,
62 pub heap_factor: f32,
64 pub combiner: super::MultiValueCombiner,
66 pub over_fetch_factor: f32,
69}
70
71pub type MatchedPositions = Vec<(u32, Vec<super::ScoredPosition>)>;
74
75macro_rules! define_query_traits {
76 ($($send_bounds:tt)*) => {
77 pub trait Query: std::fmt::Display + $($send_bounds)* {
83 fn scorer<'a>(
91 &self,
92 reader: &'a SegmentReader,
93 limit: usize,
94 ) -> ScorerFuture<'a>;
95
96 fn count_estimate<'a>(&self, reader: &'a SegmentReader) -> CountFuture<'a>;
98
99 #[cfg(feature = "sync")]
104 fn scorer_sync<'a>(
105 &self,
106 reader: &'a SegmentReader,
107 limit: usize,
108 ) -> Result<Box<dyn Scorer + 'a>> {
109 let _ = (reader, limit);
110 Err(crate::error::Error::Query(
111 "sync scorer not supported for this query type".into(),
112 ))
113 }
114
115 fn as_term_query_info(&self) -> Option<TermQueryInfo> {
119 None
120 }
121
122 fn as_sparse_term_query_info(&self) -> Option<SparseTermQueryInfo> {
125 None
126 }
127
128 fn as_sparse_term_queries(&self) -> Option<Vec<SparseTermQueryInfo>> {
134 None
135 }
136
137 fn is_filter(&self) -> bool {
140 false
141 }
142
143 fn as_doc_predicate<'a>(
146 &self,
147 _reader: &'a SegmentReader,
148 ) -> Option<DocPredicate<'a>> {
149 None
150 }
151 }
152
153 pub trait Scorer: super::docset::DocSet + $($send_bounds)* {
155 fn score(&self) -> Score;
157
158 fn matched_positions(&self) -> Option<MatchedPositions> {
161 None
162 }
163 }
164 };
165}
166
167#[cfg(not(target_arch = "wasm32"))]
168define_query_traits!(Send + Sync);
169
170#[cfg(target_arch = "wasm32")]
171define_query_traits!();
172
173impl Query for Box<dyn Query> {
174 fn scorer<'a>(&self, reader: &'a SegmentReader, limit: usize) -> ScorerFuture<'a> {
175 (**self).scorer(reader, limit)
176 }
177
178 fn count_estimate<'a>(&self, reader: &'a SegmentReader) -> CountFuture<'a> {
179 (**self).count_estimate(reader)
180 }
181
182 fn as_term_query_info(&self) -> Option<TermQueryInfo> {
183 (**self).as_term_query_info()
184 }
185
186 fn as_sparse_term_query_info(&self) -> Option<SparseTermQueryInfo> {
187 (**self).as_sparse_term_query_info()
188 }
189
190 fn as_sparse_term_queries(&self) -> Option<Vec<SparseTermQueryInfo>> {
191 (**self).as_sparse_term_queries()
192 }
193
194 fn is_filter(&self) -> bool {
195 (**self).is_filter()
196 }
197
198 fn as_doc_predicate<'a>(&self, reader: &'a SegmentReader) -> Option<DocPredicate<'a>> {
199 (**self).as_doc_predicate(reader)
200 }
201
202 #[cfg(feature = "sync")]
203 fn scorer_sync<'a>(
204 &self,
205 reader: &'a SegmentReader,
206 limit: usize,
207 ) -> Result<Box<dyn Scorer + 'a>> {
208 (**self).scorer_sync(reader, limit)
209 }
210}
211
212pub struct EmptyScorer;
214
215impl super::docset::DocSet for EmptyScorer {
216 fn doc(&self) -> DocId {
217 crate::structures::TERMINATED
218 }
219
220 fn advance(&mut self) -> DocId {
221 crate::structures::TERMINATED
222 }
223
224 fn seek(&mut self, _target: DocId) -> DocId {
225 crate::structures::TERMINATED
226 }
227
228 fn size_hint(&self) -> u32 {
229 0
230 }
231}
232
233impl Scorer for EmptyScorer {
234 fn score(&self) -> Score {
235 0.0
236 }
237}