use super::types::*;
use crate::ast::{FilterExpr, FormulaExpr, Value};
use alloc::boxed::Box;
use alloc::string::String;
use alloc::vec::Vec;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum QueryInput {
Text {
text: String,
model: Option<String>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
text_param: Option<String>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Vec::is_empty")
)]
options: Vec<(String, Value)>,
},
Image {
source: String,
model: Option<String>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Vec::is_empty")
)]
options: Vec<(String, Value)>,
},
Object {
object: Box<Value>,
model: Option<String>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Vec::is_empty")
)]
options: Vec<(String, Value)>,
},
Vector(VectorValue),
Point(PointId),
Param(
String,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
Option<alloc::boxed::Box<crate::error::Span>>,
),
PositionalParam(
usize,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
Option<alloc::boxed::Box<crate::error::Span>>,
),
}
impl QueryInput {
pub fn param(name: impl Into<String>) -> Self {
Self::Param(name.into(), None)
}
pub fn param_with_span(name: impl Into<String>, span: crate::error::Span) -> Self {
Self::Param(name.into(), Some(alloc::boxed::Box::new(span)))
}
pub fn positional_param(idx: usize) -> Self {
Self::PositionalParam(idx, None)
}
pub fn positional_param_with_span(idx: usize, span: crate::error::Span) -> Self {
Self::PositionalParam(idx, Some(alloc::boxed::Box::new(span)))
}
pub fn param_span(&self) -> Option<crate::error::Span> {
match self {
Self::Param(_, span) | Self::PositionalParam(_, span) => span.as_deref().copied(),
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MmrConfig {
pub diversity: f64,
pub candidates: u64,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ContextPair {
pub positive: QueryInput,
pub negative: QueryInput,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum RecommendStrategy {
AverageVector,
BestScore,
SumScores,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct FeedbackItem {
pub example: QueryInput,
pub score: f64,
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct FeedbackStrategy {
pub a: f64,
pub b: f64,
pub c: f64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum FusionMethod {
Rrf,
Dbsf,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum QueryCollection {
Explicit(String),
Inherited,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum PrefetchSource {
Cte(String),
Query(Box<QueryStmt>),
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct LookupSpec {
pub collection: String,
pub vector: Option<String>,
pub shard_key: Option<ShardKey>,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Prefetch {
pub source: PrefetchSource,
pub filter: Option<Box<FilterExpr>>,
pub score_threshold: Option<f64>,
pub lookup: Option<LookupSpec>,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum QueryExpr {
Points {
ids: Vec<PointId>,
},
Nearest {
input: QueryInput,
using: Option<VectorTarget>,
prefetch: Vec<Prefetch>,
mmr: Option<Box<MmrConfig>>,
},
Recommend {
positive: Vec<QueryInput>,
negative: Vec<QueryInput>,
strategy: Option<RecommendStrategy>,
using: Option<VectorTarget>,
prefetch: Vec<Prefetch>,
},
Context {
pairs: Vec<ContextPair>,
using: Option<VectorTarget>,
prefetch: Vec<Prefetch>,
},
Discover {
target: QueryInput,
context: Vec<ContextPair>,
using: Option<VectorTarget>,
prefetch: Vec<Prefetch>,
},
OrderBy {
field: String,
direction: OrderDirection,
start_from: Option<Value>,
},
SampleRandom,
Fusion {
method: FusionMethod,
prefetch: Vec<Prefetch>,
},
Formula {
expression: Box<FormulaExpr>,
defaults: Vec<(String, Value)>,
prefetch: Vec<Prefetch>,
},
RelevanceFeedback {
target: QueryInput,
feedback: Vec<FeedbackItem>,
strategy: FeedbackStrategy,
using: Option<VectorTarget>,
prefetch: Vec<Prefetch>,
},
Hybrid {
text: String,
model: Option<String>,
dense_vector: Option<String>,
sparse_vector: Option<String>,
fusion: FusionMethod,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
text_param: Option<String>,
},
Rerank {
input: QueryInput,
model: String,
using: Option<VectorTarget>,
prefetch: Vec<Prefetch>,
},
CrossRerank {
query: String,
model: String,
field: Option<String>,
prefetch: Vec<Prefetch>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
query_param: Option<String>,
},
}
#[derive(Debug, Clone, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct QuantizationSearchParams {
pub ignore: Option<bool>,
pub rescore: Option<bool>,
pub oversampling: Option<f64>,
}
#[derive(Debug, Clone, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SearchParams {
pub hnsw_ef: Option<u64>,
pub exact: Option<bool>,
pub acorn: Option<bool>,
pub max_selectivity: Option<f64>,
pub indexed_only: Option<bool>,
pub quantization: Option<QuantizationSearchParams>,
pub rrf_k: Option<u64>,
pub rrf_weights: Option<Vec<f64>>,
pub idf: Option<IdfParams>,
pub timeout: Option<u64>,
pub consistency: Option<ReadConsistency>,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct IdfParams {
pub corpus: Option<FilterExpr>,
}
#[derive(Debug, Clone, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct QueryOutput {
pub payload: Option<PayloadSelector>,
pub vectors: Option<VectorSelector>,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct GroupSpec {
pub field: String,
#[cfg_attr(feature = "serde", serde(skip))]
pub field_span: Option<crate::error::Span>,
pub size: Option<u64>,
pub lookup: Option<GroupLookup>,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct GroupLookup {
pub collection: String,
pub payload: Option<PayloadSelector>,
pub vectors: Option<VectorSelector>,
}
#[derive(Debug, Clone, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PageSpec {
pub limit: Option<u64>,
pub offset: Option<u64>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub limit_param: Option<String>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub offset_param: Option<String>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub limit_span: Option<crate::error::Span>,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub offset_span: Option<crate::error::Span>,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Cte {
pub name: String,
pub query: Box<QueryStmt>,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct QueryStmt {
pub ctes: Vec<Cte>,
pub collection: QueryCollection,
#[cfg_attr(feature = "serde", serde(skip))]
pub collection_span: Option<crate::error::Span>,
pub expression: QueryExpr,
pub filter: Option<Box<FilterExpr>>,
pub params: Option<SearchParams>,
pub score_threshold: Option<f64>,
pub group: Option<GroupSpec>,
pub output: QueryOutput,
pub page: PageSpec,
pub shard_key: Option<super::ShardKey>,
}