use crate::models::sparse::bm25_embed_document;
use crate::models::sparse::bm25_embed_query;
use crate::models::sparse::stopwords::Stopwords;
use crate::registry;
use crate::registry::sparse::SparseDescriptor;
use crate::sparse::SparseEmbedding;
const ENGLISH_STOPWORDS: &str = include_str!("../models/sparse/english_stopwords.txt");
pub struct Bm25TextEmbedding {
stopwords: Stopwords,
descriptor: SparseDescriptor,
}
impl Bm25TextEmbedding {
pub fn builder() -> Bm25TextEmbeddingBuilder {
Bm25TextEmbeddingBuilder::new()
}
pub fn descriptor(&self) -> &SparseDescriptor {
&self.descriptor
}
pub fn embed<S: AsRef<str>>(&self, texts: &[S]) -> Vec<SparseEmbedding> {
self.passage_embed(texts)
}
pub fn passage_embed<S: AsRef<str>>(&self, texts: &[S]) -> Vec<SparseEmbedding> {
texts
.iter()
.map(|text| bm25_embed_document(text.as_ref(), &self.stopwords))
.collect()
}
pub fn query_embed<S: AsRef<str>>(&self, texts: &[S]) -> Vec<SparseEmbedding> {
texts
.iter()
.map(|text| bm25_embed_query(text.as_ref(), &self.stopwords))
.collect()
}
}
pub struct Bm25TextEmbeddingBuilder {
_private: (),
}
impl Bm25TextEmbeddingBuilder {
pub(crate) fn new() -> Self {
Self { _private: () }
}
pub fn build(self) -> Bm25TextEmbedding {
Bm25TextEmbedding {
stopwords: Stopwords::parse(ENGLISH_STOPWORDS),
descriptor: registry::sparse::lookup("Qdrant/bm25")
.expect("Qdrant/bm25 is a registered sparse entry"),
}
}
}
#[cfg(test)]
mod tests;