use crate::data::DataValue;
use crate::vector::core::vector::Vector;
use crate::vector::store::request::{
FieldSelector, QueryPayload, QueryVector, VectorScoreMode, VectorSearchParams,
VectorSearchQuery, VectorSearchRequest,
};
#[derive(Debug, Clone)]
pub struct VectorSearchRequestBuilder {
query_vectors: Vec<QueryVector>,
query_payloads: Vec<QueryPayload>,
params: VectorSearchParams,
}
impl Default for VectorSearchRequestBuilder {
fn default() -> Self {
Self::new()
}
}
impl VectorSearchRequestBuilder {
pub fn new() -> Self {
Self {
query_vectors: Vec::new(),
query_payloads: Vec::new(),
params: VectorSearchParams::default(),
}
}
pub fn add_vector(mut self, field: impl Into<String>, vector: Vec<f32>) -> Self {
self.query_vectors.push(QueryVector {
vector: Vector::new(vector),
weight: 1.0,
fields: Some(vec![field.into()]),
});
self
}
pub fn add_vector_with_weight(
mut self,
field: impl Into<String>,
vector: Vec<f32>,
weight: f32,
) -> Self {
self.query_vectors.push(QueryVector {
vector: Vector::new(vector),
weight,
fields: Some(vec![field.into()]),
});
self
}
pub fn add_payload(mut self, field: impl Into<String>, payload: DataValue) -> Self {
self.query_payloads.push(QueryPayload::new(field, payload));
self
}
pub fn add_bytes(
self,
field: impl Into<String>,
bytes: impl Into<Vec<u8>>,
mime: Option<impl Into<String>>,
) -> Self {
self.add_payload(
field,
DataValue::Bytes(bytes.into(), mime.map(|m| m.into())),
)
}
pub fn add_text(self, field: impl Into<String>, text: impl Into<String>) -> Self {
self.add_payload(field, DataValue::Text(text.into()))
}
pub fn fields(mut self, fields: Vec<String>) -> Self {
self.params.fields = Some(fields.into_iter().map(FieldSelector::Exact).collect());
self
}
pub fn field(mut self, field: impl Into<String>) -> Self {
let field = field.into();
if let Some(fields) = &mut self.params.fields {
fields.push(FieldSelector::Exact(field));
} else {
self.params.fields = Some(vec![FieldSelector::Exact(field)]);
}
self
}
pub fn limit(mut self, limit: usize) -> Self {
self.params.limit = limit;
self
}
pub fn score_mode(mut self, mode: VectorScoreMode) -> Self {
self.params.score_mode = mode;
self
}
pub fn overfetch(mut self, overfetch: f32) -> Self {
self.params.overfetch = overfetch;
self
}
pub fn min_score(mut self, min_score: f32) -> Self {
self.params.min_score = min_score;
self
}
pub fn build(self) -> VectorSearchRequest {
let query = if !self.query_vectors.is_empty() {
VectorSearchQuery::Vectors(self.query_vectors)
} else {
VectorSearchQuery::Payloads(self.query_payloads)
};
VectorSearchRequest {
query,
params: self.params,
}
}
}