use std::sync::Arc;
use crate::storage::query::unified::ExecutionError;
use super::super::super::entity::RefType;
use super::super::super::store::UnifiedStore;
use super::super::execution::execute_hybrid_query;
use super::super::filters::{Filter, FilterAcceptor, WhereClause};
use super::super::types::QueryResult;
#[derive(Debug, Clone)]
pub struct HybridQueryBuilder {
pub(crate) vector_query: Option<(Vec<f32>, usize)>,
pub(crate) graph_pattern: Option<GraphPatternDsl>,
pub(crate) filters: Vec<Filter>,
pub(crate) collections: Option<Vec<String>>,
pub(crate) weights: QueryWeights,
pub(crate) min_score: f32,
pub(crate) limit: Option<usize>,
pub(crate) expand_refs: Option<RefType>,
}
#[derive(Debug, Clone)]
pub struct GraphPatternDsl {
pub node_label: Option<String>,
pub node_type: Option<String>,
pub edge_labels: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct QueryWeights {
pub vector: f32,
pub graph: f32,
pub filter: f32,
}
impl Default for QueryWeights {
fn default() -> Self {
Self {
vector: 0.5,
graph: 0.3,
filter: 0.2,
}
}
}
impl HybridQueryBuilder {
pub fn new() -> Self {
Self {
vector_query: None,
graph_pattern: None,
filters: Vec::new(),
collections: None,
weights: QueryWeights::default(),
min_score: 0.1,
limit: None,
expand_refs: None,
}
}
pub fn similar_to(mut self, vector: &[f32], k: usize) -> Self {
self.vector_query = Some((vector.to_vec(), k));
self
}
pub fn matching_nodes(mut self, label: impl Into<String>) -> Self {
self.graph_pattern = Some(GraphPatternDsl {
node_label: Some(label.into()),
node_type: None,
edge_labels: Vec::new(),
});
self
}
pub fn in_collection(mut self, name: impl Into<String>) -> Self {
self.collections
.get_or_insert_with(Vec::new)
.push(name.into());
self
}
pub fn where_(self, field: impl Into<String>) -> WhereClause<Self> {
WhereClause::new(self, field.into())
}
pub fn with_weights(mut self, vector: f32, graph: f32, filter: f32) -> Self {
self.weights = QueryWeights {
vector,
graph,
filter,
};
self
}
pub fn min_score(mut self, score: f32) -> Self {
self.min_score = score;
self
}
pub fn limit(mut self, n: usize) -> Self {
self.limit = Some(n);
self
}
pub fn expand_via(mut self, ref_type: RefType) -> Self {
self.expand_refs = Some(ref_type);
self
}
pub fn execute(self, store: &Arc<UnifiedStore>) -> Result<QueryResult, ExecutionError> {
execute_hybrid_query(self, store)
}
}
impl Default for HybridQueryBuilder {
fn default() -> Self {
Self::new()
}
}
impl FilterAcceptor for HybridQueryBuilder {
fn add_filter(&mut self, filter: Filter) {
self.filters.push(filter);
}
}