Skip to main content

reddb_server/storage/unified/dsl/
mod.rs

1//! Query DSL for Multi-Modal Queries
2//!
3//! Provides a fluent, chainable API for querying across Tables, Graphs, and Vectors
4//! in the Unified Storage Layer. Designed for maximum developer experience (DevX).
5//!
6//! # Design Principles
7//!
8//! 1. **Chainable**: Every method returns `self` for fluent chaining
9//! 2. **Type-Safe**: Compile-time checks for query structure
10//! 3. **Expressive**: Read like natural language
11//! 4. **Multi-Modal**: Seamlessly combine vector, graph, and table operations
12//!
13//! # Examples
14//!
15//! ```ignore
16//! use reddb::storage::dsl::*;
17//!
18//! // Vector similarity + metadata filter
19//! let results = Q::similar_to(&embedding, 10)
20//!     .in_collection("vulnerabilities")
21//!     .where_("severity").equals("critical")
22//!     .where_("cvss").greater_than(8.0)
23//!     .execute(&store)?;
24//!
25//! // Graph traversal + vector ranking
26//! let paths = Q::from_node("web-server-1")
27//!     .traverse("CONNECTS_TO")
28//!     .depth(3)
29//!     .ranked_by(&attack_vector_embedding)
30//!     .execute(&store)?;
31//!
32//! // Combined: find similar CVEs, expand to affected hosts
33//! let context = Q::similar_to(&cve_embedding, 5)
34//!     .expand_via(RefType::VectorToNode)
35//!     .expand_via(RefType::NodeToRow)
36//!     .with_weights(vector: 0.6, graph: 0.3, table: 0.1)
37//!     .execute(&store)?;
38//! ```
39
40mod builders;
41mod cross_modal;
42mod execution;
43mod filters;
44mod helpers;
45mod types;
46
47#[cfg(test)]
48mod tests;
49
50// Re-exports
51pub use builders::TextSearchBuilder;
52pub use builders::{
53    CrossModalWeights, GraphPatternDsl, GraphQueryBuilder, GraphStartPoint, HybridQueryBuilder,
54    JoinPhase, JoinStep, KvQueryBuilder, NodePatternDsl, QueryWeights, RefQueryBuilder,
55    ScanQueryBuilder, SortOrder, TableQueryBuilder, ThreeWayJoinBuilder, TraversalDirection,
56    TraversalStep, VectorQueryBuilder,
57};
58pub use filters::{Filter, FilterAcceptor, FilterOp, FilterValue, WhereClause};
59pub use helpers::{apply_filters, cosine_similarity};
60pub(crate) use helpers::{calculate_entity_similarity, extract_searchable_text};
61pub use types::{MatchComponents, QueryResult, ScoredMatch};
62
63use super::entity::{EntityId, RefType};
64
65// ============================================================================
66// Query Builder Entry Point
67// ============================================================================
68
69/// Query builder entry point. Start all queries with `Q::`.
70///
71/// # Examples
72///
73/// ```ignore
74/// // Vector similarity search
75/// Q::similar_to(&embedding, 10)
76///
77/// // Start from a graph node
78/// Q::from_node("node-label")
79///
80/// // Filter table rows
81/// Q::table("hosts").where_("status").equals("active")
82///
83/// // Full collection scan
84/// Q::all_in("vulnerabilities")
85/// ```
86pub struct Q;
87
88impl Q {
89    /// Start a vector similarity query
90    pub fn similar_to(vector: &[f32], k: usize) -> VectorQueryBuilder {
91        VectorQueryBuilder::new(vector.to_vec(), k)
92    }
93
94    /// Start a query from a specific graph node
95    pub fn from_node(label: impl Into<String>) -> GraphQueryBuilder {
96        GraphQueryBuilder::from_node(label)
97    }
98
99    /// Start a query from a specific entity by ID
100    pub fn from_id(id: EntityId) -> GraphQueryBuilder {
101        GraphQueryBuilder::from_id(id)
102    }
103
104    /// Query a specific table/collection
105    pub fn table(name: impl Into<String>) -> TableQueryBuilder {
106        TableQueryBuilder::new(name)
107    }
108
109    /// Shorthand for collection query
110    pub fn collection(name: impl Into<String>) -> TableQueryBuilder {
111        TableQueryBuilder::new(name)
112    }
113
114    /// Query all entities in a collection
115    pub fn all_in(collection: impl Into<String>) -> ScanQueryBuilder {
116        ScanQueryBuilder::new(collection)
117    }
118
119    /// Find entities by cross-reference
120    pub fn refs_from(id: EntityId, ref_type: RefType) -> RefQueryBuilder {
121        RefQueryBuilder::new(id, ref_type)
122    }
123
124    /// Text search across all indexed content
125    pub fn text_search(query: impl Into<String>) -> TextSearchBuilder {
126        TextSearchBuilder::new(query)
127    }
128
129    /// Query documents in a collection
130    ///
131    /// Documents are stored as enriched table rows, so this is a convenience
132    /// alias that delegates to `TableQueryBuilder`. The flattened top-level
133    /// document fields support path-based filtering through the table query DSL.
134    ///
135    /// # Example
136    /// ```ignore
137    /// let results = Q::document("articles")
138    ///     .where_("title").equals("Hello World")
139    ///     .limit(10)
140    ///     .execute(&store)?;
141    /// ```
142    pub fn document(collection: impl Into<String>) -> TableQueryBuilder {
143        TableQueryBuilder::new(collection)
144    }
145
146    /// Key-Value operations on a collection
147    ///
148    /// # Examples
149    /// ```ignore
150    /// // Get a value
151    /// let result = Q::kv("config").get("theme").execute(&store)?;
152    ///
153    /// // Set a value (upsert)
154    /// let result = Q::kv("config").set("theme", Value::text("dark")).execute(&store)?;
155    ///
156    /// // Delete a key
157    /// let result = Q::kv("config").delete("theme").execute(&store)?;
158    ///
159    /// // List all KV pairs
160    /// let result = Q::kv("config").list().execute(&store)?;
161    /// ```
162    pub fn kv(collection: impl Into<String>) -> KvQueryBuilder {
163        KvQueryBuilder::new(collection)
164    }
165
166    /// Hybrid query combining multiple modes
167    pub fn hybrid() -> HybridQueryBuilder {
168        HybridQueryBuilder::new()
169    }
170
171    /// Three-way cross-modal JOIN
172    ///
173    /// Efficiently chains queries across Vector → Graph → Table (or any order).
174    ///
175    /// # Example
176    /// ```ignore
177    /// // Find CVEs similar to vector, traverse to affected hosts, get host records
178    /// let results = Q::cross_modal()
179    ///     .start_vector(&cve_embedding, 10)
180    ///     .traverse("AFFECTS", 2)
181    ///     .join_table("hosts")
182    ///     .execute(&store)?;
183    /// ```
184    pub fn cross_modal() -> ThreeWayJoinBuilder {
185        ThreeWayJoinBuilder::new()
186    }
187}