pub struct Searcher<D: Directory + 'static> { /* private fields */ }Expand description
Searcher - provides search over loaded segments
For wasm/read-only use, create via Searcher::open().
For native use with Index, this is created via IndexReader.
Implementations§
Source§impl<D: Directory + 'static> Searcher<D>
impl<D: Directory + 'static> Searcher<D>
Sourcepub async fn open(
directory: Arc<D>,
schema: Arc<Schema>,
segment_ids: &[String],
term_cache_blocks: usize,
) -> Result<Self>
pub async fn open( directory: Arc<D>, schema: Arc<Schema>, segment_ids: &[String], term_cache_blocks: usize, ) -> Result<Self>
Create a Searcher directly from segment IDs
This is a simpler initialization path that doesn’t require SegmentManager. Use this for read-only access to pre-built indexes.
pub fn schema_arc(&self) -> Arc<Schema> ⓘ
Sourcepub fn segment_readers(&self) -> &[Arc<SegmentReader>]
pub fn segment_readers(&self) -> &[Arc<SegmentReader>]
Get segment readers
Sourcepub fn default_fields(&self) -> &[Field]
pub fn default_fields(&self) -> &[Field]
Get default fields for search
Sourcepub fn tokenizers(&self) -> &TokenizerRegistry
pub fn tokenizers(&self) -> &TokenizerRegistry
Get tokenizer registry
Sourcepub fn trained_centroids(&self) -> &FxHashMap<u32, Arc<CoarseCentroids>>
pub fn trained_centroids(&self) -> &FxHashMap<u32, Arc<CoarseCentroids>>
Get trained centroids
pub fn trained_binary_quantizers( &self, ) -> &FxHashMap<u32, Arc<BinaryCoarseQuantizer>>
Sourcepub fn global_stats(&self) -> &Arc<LazyGlobalStats> ⓘ
pub fn global_stats(&self) -> &Arc<LazyGlobalStats> ⓘ
Get lazy global statistics for cross-segment IDF computation
Sourcepub fn segment_map(&self) -> &FxHashMap<u128, usize>
pub fn segment_map(&self) -> &FxHashMap<u128, usize>
Get O(1) segment_id → index map (used by reranker)
Sourcepub fn num_segments(&self) -> usize
pub fn num_segments(&self) -> usize
Get number of segments
Sourcepub async fn doc(
&self,
segment_id: u128,
doc_id: u32,
) -> Result<Option<Document>>
pub async fn doc( &self, segment_id: u128, doc_id: u32, ) -> Result<Option<Document>>
Get a document by (segment_id, local_doc_id)
Sourcepub async fn search(
&self,
query: &dyn Query,
limit: usize,
) -> Result<Vec<SearchResult>>
pub async fn search( &self, query: &dyn Query, limit: usize, ) -> Result<Vec<SearchResult>>
Search across all segments and return aggregated results
Sourcepub async fn search_with_count(
&self,
query: &dyn Query,
limit: usize,
) -> Result<(Vec<SearchResult>, u32)>
pub async fn search_with_count( &self, query: &dyn Query, limit: usize, ) -> Result<(Vec<SearchResult>, u32)>
Search across all segments and return (results, total_seen) total_seen is the number of documents that were scored across all segments
Sourcepub async fn search_with_offset(
&self,
query: &dyn Query,
limit: usize,
offset: usize,
) -> Result<Vec<SearchResult>>
pub async fn search_with_offset( &self, query: &dyn Query, limit: usize, offset: usize, ) -> Result<Vec<SearchResult>>
Search with offset for pagination
Sourcepub async fn search_with_offset_and_count(
&self,
query: &dyn Query,
limit: usize,
offset: usize,
) -> Result<(Vec<SearchResult>, u32)>
pub async fn search_with_offset_and_count( &self, query: &dyn Query, limit: usize, offset: usize, ) -> Result<(Vec<SearchResult>, u32)>
Search with offset and return (results, total_seen)
Sourcepub async fn search_with_positions(
&self,
query: &dyn Query,
limit: usize,
) -> Result<(Vec<SearchResult>, u32)>
pub async fn search_with_positions( &self, query: &dyn Query, limit: usize, ) -> Result<(Vec<SearchResult>, u32)>
Search with positions (ordinal tracking) and return (results, total_seen)
Use this when you need per-ordinal scores for multi-valued fields.
Sourcepub async fn search_with_positions_budgeted(
&self,
query: &dyn Query,
limit: usize,
deadline: Option<Instant>,
) -> Result<(Vec<SearchResult>, u32, bool)>
pub async fn search_with_positions_budgeted( &self, query: &dyn Query, limit: usize, deadline: Option<Instant>, ) -> Result<(Vec<SearchResult>, u32, bool)>
search_with_positions under a wall-clock budget (anytime mode).
Returns (results, seen, truncated); truncated is set when an
executor stopped scoring at the deadline, in which case the results
are the best found so far rather than the exact top-k.
Sourcepub async fn search_with_count_budgeted(
&self,
query: &dyn Query,
limit: usize,
deadline: Option<Instant>,
) -> Result<(Vec<SearchResult>, u32, bool)>
pub async fn search_with_count_budgeted( &self, query: &dyn Query, limit: usize, deadline: Option<Instant>, ) -> Result<(Vec<SearchResult>, u32, bool)>
search_with_count under a wall-clock budget; see
Self::search_with_positions_budgeted.
Sourcepub async fn search_with_positions_budgeted_stats(
&self,
query: &dyn Query,
limit: usize,
deadline: Option<Instant>,
stats: Option<Arc<GlobalStats>>,
) -> Result<(Vec<SearchResult>, u32, bool)>
pub async fn search_with_positions_budgeted_stats( &self, query: &dyn Query, limit: usize, deadline: Option<Instant>, stats: Option<Arc<GlobalStats>>, ) -> Result<(Vec<SearchResult>, u32, bool)>
Self::search_with_positions_budgeted with externally supplied
text statistics (a broker’s cross-shard document frequencies); they
replace the searcher’s own segment-aggregated statistics.
Sourcepub async fn search_with_count_budgeted_stats(
&self,
query: &dyn Query,
limit: usize,
deadline: Option<Instant>,
stats: Option<Arc<GlobalStats>>,
) -> Result<(Vec<SearchResult>, u32, bool)>
pub async fn search_with_count_budgeted_stats( &self, query: &dyn Query, limit: usize, deadline: Option<Instant>, stats: Option<Arc<GlobalStats>>, ) -> Result<(Vec<SearchResult>, u32, bool)>
Self::search_with_count_budgeted with externally supplied text
statistics.
Sourcepub fn query_text_stats(
&self,
query: &dyn Query,
stats_override: Option<Arc<GlobalStats>>,
) -> Option<Arc<GlobalStats>>
pub fn query_text_stats( &self, query: &dyn Query, stats_override: Option<Arc<GlobalStats>>, ) -> Option<Arc<GlobalStats>>
Text statistics a query scores with: the caller’s override when
given, otherwise document frequencies, corpus sizes and average
lengths aggregated over every segment of this searcher (None for a
single segment, whose local statistics already are the whole).
Sourcepub fn search_with_offset_and_count_sync(
&self,
query: &dyn Query,
limit: usize,
offset: usize,
) -> Result<(Vec<SearchResult>, u32)>
pub fn search_with_offset_and_count_sync( &self, query: &dyn Query, limit: usize, offset: usize, ) -> Result<(Vec<SearchResult>, u32)>
Synchronous search across all segments using rayon for parallelism.
This is the async-free boundary — no tokio involvement from here down.
Sourcepub async fn search_fused(
&self,
queries: &[(&dyn Query, f32)],
fetch_limit: usize,
limit: usize,
method: FusionMethod,
combiner: MultiValueCombiner,
) -> Result<Vec<SearchResult>>
pub async fn search_fused( &self, queries: &[(&dyn Query, f32)], fetch_limit: usize, limit: usize, method: FusionMethod, combiner: MultiValueCombiner, ) -> Result<Vec<SearchResult>>
Hybrid search: run several queries independently and fuse their
ranked lists (union) into a single top-limit result.
Unlike Self::search_and_rerank — which can only re-score
documents the first-stage query already found — fusion keeps
documents found by any of the queries. Typical use is sparse
(BM25/SPLADE) + dense vector hybrid retrieval with
FusionMethod::Rrf { k: 60.0 }.
Fusion happens at chunk granularity: per-ordinal scores are
collected from each sub-query, fused per (doc, ordinal) key, then
combined into a doc score with combiner
(MultiValueCombiner::Max recommended — same-chunk corroboration
across verticals compounds, scattered noise does not). Fused results
carry per-chunk positions.
Each query is paired with a weight scaling its contribution.
fetch_limit is the per-query candidate depth. Request-facing adapters
default to at most crate::query::MAX_CANDIDATE_OVERSUBSCRIPTION times
the result window and never multiply an existing rerank pool again.
Sourcepub async fn search_fused_with_count(
&self,
queries: &[(&dyn Query, f32)],
fetch_limit: usize,
limit: usize,
method: FusionMethod,
combiner: MultiValueCombiner,
) -> Result<(Vec<SearchResult>, u32)>
pub async fn search_fused_with_count( &self, queries: &[(&dyn Query, f32)], fetch_limit: usize, limit: usize, method: FusionMethod, combiner: MultiValueCombiner, ) -> Result<(Vec<SearchResult>, u32)>
Fusion variant that also returns the aggregate number of documents scored by all sub-queries. This lets request-facing callers use the parallel fusion path without rerunning sub-queries for observability.
Sourcepub fn fuse_candidate_lists(
&self,
lists: &[(&[SearchResult], f32)],
method: FusionMethod,
combiner: MultiValueCombiner,
limit: usize,
) -> Result<Vec<SearchResult>>
pub fn fuse_candidate_lists( &self, lists: &[(&[SearchResult], f32)], method: FusionMethod, combiner: MultiValueCombiner, limit: usize, ) -> Result<Vec<SearchResult>>
Fuse retained nomination lists on this searcher’s shared CPU pool.
Sourcepub fn rrf_scores_for_hits(
&self,
lists: &[RrfRankedList<'_>],
selected: &[(u128, u32)],
k: f32,
combiner: MultiValueCombiner,
) -> Result<Vec<RrfScore>>
pub fn rrf_scores_for_hits( &self, lists: &[RrfRankedList<'_>], selected: &[(u128, u32)], k: f32, combiner: MultiValueCombiner, ) -> Result<Vec<RrfScore>>
Attribute organic RRF votes without repeating retrieval or changing L1.
Sourcepub async fn search_candidate_union(
&self,
queries: &[Arc<dyn Query>],
depth: usize,
stats: Arc<GlobalStats>,
) -> Result<(Vec<SearchResult>, u32)>
pub async fn search_candidate_union( &self, queries: &[Arc<dyn Query>], depth: usize, stats: Arc<GlobalStats>, ) -> Result<(Vec<SearchResult>, u32)>
Retrieve independent branches and retain the complete bounded document union. No rank fusion or cross-branch top-k runs before feature scoring.
Sourcepub async fn search_candidate_lists(
&self,
queries: &[Arc<dyn Query>],
depth: usize,
stats: Option<Arc<GlobalStats>>,
) -> Result<Vec<(Vec<SearchResult>, u32)>>
pub async fn search_candidate_lists( &self, queries: &[Arc<dyn Query>], depth: usize, stats: Option<Arc<GlobalStats>>, ) -> Result<Vec<(Vec<SearchResult>, u32)>>
Independent nominated lists for coordinator-side global fusion. This uses the same bounded parallel retrieval as candidate backfill.
pub fn merge_candidate_lists<T: Into<SearchResult> + Borrow<SearchResult>>( &self, lists: impl IntoIterator<Item = impl IntoIterator<Item = T>>, ) -> Result<Vec<SearchResult>>
Sourcepub async fn search_and_rerank(
&self,
query: &dyn Query,
l1_limit: usize,
final_limit: usize,
config: &RerankerConfig,
) -> Result<(Vec<SearchResult>, u32)>
pub async fn search_and_rerank( &self, query: &dyn Query, l1_limit: usize, final_limit: usize, config: &RerankerConfig, ) -> Result<(Vec<SearchResult>, u32)>
Two-stage search: L1 retrieval + L2 dense vector reranking
Runs the query to get l1_limit candidates, then reranks by exact
dense vector distance and returns the top final_limit results.
Sourcepub async fn query(
&self,
query_str: &str,
limit: usize,
) -> Result<SearchResponse>
pub async fn query( &self, query_str: &str, limit: usize, ) -> Result<SearchResponse>
Parse query string and search (convenience method)
Sourcepub async fn query_offset(
&self,
query_str: &str,
limit: usize,
offset: usize,
) -> Result<SearchResponse>
pub async fn query_offset( &self, query_str: &str, limit: usize, offset: usize, ) -> Result<SearchResponse>
Parse query string and search with offset (convenience method)
Sourcepub fn query_parser(&self) -> QueryLanguageParser
pub fn query_parser(&self) -> QueryLanguageParser
Get query parser for this searcher
Sourcepub async fn get_document(
&self,
address: &DocAddress,
) -> Result<Option<Document>>
pub async fn get_document( &self, address: &DocAddress, ) -> Result<Option<Document>>
Get a document by address (segment_id + local doc_id)
Sourcepub async fn get_document_with_fields(
&self,
address: &DocAddress,
fields: Option<&FxHashSet<u32>>,
) -> Result<Option<Document>>
pub async fn get_document_with_fields( &self, address: &DocAddress, fields: Option<&FxHashSet<u32>>, ) -> Result<Option<Document>>
Get a document by address, hydrating only the specified field IDs.
If fields is None, all fields are hydrated (including dense vectors).
If fields is Some(set), only dense vector fields in the set are read
from flat storage — skipping expensive mmap reads for unrequested vectors.
Source§impl<D: Directory + 'static> Searcher<D>
impl<D: Directory + 'static> Searcher<D>
Sourcepub async fn candidate_text_stats(
&self,
plan: &CandidateScoringPlan,
) -> Result<Arc<GlobalStats>>
pub async fn candidate_text_stats( &self, plan: &CandidateScoringPlan, ) -> Result<Arc<GlobalStats>>
Complete BM25 statistics over this immutable snapshot, including on native-async and WASM where the synchronous lazy cache is unavailable.
Sourcepub async fn score_candidates(
&self,
candidates: &[SearchResult],
plan: &CandidateScoringPlan,
stats: Option<Arc<GlobalStats>>,
) -> Result<Vec<ScoredCandidate>>
pub async fn score_candidates( &self, candidates: &[SearchResult], plan: &CandidateScoringPlan, stats: Option<Arc<GlobalStats>>, ) -> Result<Vec<ScoredCandidate>>
Score all requested documents against every named branch, including fields which did not nominate them. Addresses must belong to this snapshot; stale addresses and budget overflows fail explicitly.
Sourcepub async fn score_candidates_with_retrieved(
&self,
candidates: &[SearchResult],
plan: &CandidateScoringPlan,
stats: Option<Arc<GlobalStats>>,
retrieved: &[(usize, &[SearchResult])],
) -> Result<Vec<ScoredCandidate>>
pub async fn score_candidates_with_retrieved( &self, candidates: &[SearchResult], plan: &CandidateScoringPlan, stats: Option<Arc<GlobalStats>>, retrieved: &[(usize, &[SearchResult])], ) -> Result<Vec<ScoredCandidate>>
Preserve scores from named retrieval branches, then optionally probe
only missing logical cells. Branch indices refer to plan.features.
Sourcepub async fn score_candidates_with_retrieved_and_rrf(
&self,
candidates: &[SearchResult],
plan: &CandidateScoringPlan,
stats: Option<Arc<GlobalStats>>,
retrieved: &[(usize, &[SearchResult])],
rrf: Option<&[RrfScore]>,
) -> Result<Vec<ScoredCandidate>>
pub async fn score_candidates_with_retrieved_and_rrf( &self, candidates: &[SearchResult], plan: &CandidateScoringPlan, stats: Option<Arc<GlobalStats>>, retrieved: &[(usize, &[SearchResult])], rrf: Option<&[RrfScore]>, ) -> Result<Vec<ScoredCandidate>>
Supply organic RRF features to the same L1 scorer before any top-k.
Auto Trait Implementations§
impl<D> !RefUnwindSafe for Searcher<D>
impl<D> !UnwindSafe for Searcher<D>
impl<D> Freeze for Searcher<D>where
PhantomData<D>: Freeze,
impl<D> Send for Searcher<D>where
PhantomData<D>: Send,
impl<D> Sync for Searcher<D>where
PhantomData<D>: Sync,
impl<D> Unpin for Searcher<D>where
PhantomData<D>: Unpin,
impl<D> UnsafeUnpin for Searcher<D>where
PhantomData<D>: UnsafeUnpin,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> DropFlavorWrapper<T> for T
impl<T> DropFlavorWrapper<T> for T
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more