velesdb_core/collection/vector_collection/crud.rs
1//! CRUD and index-mutation operations for `VectorCollection`.
2
3use crate::error::Result;
4use crate::point::Point;
5
6use super::VectorCollection;
7
8impl VectorCollection {
9 /// Bulk insert optimized for high-throughput import.
10 ///
11 /// # Errors
12 ///
13 /// Returns an error if any point has a mismatched dimension.
14 pub fn upsert_bulk(&self, points: &[Point]) -> Result<usize> {
15 self.inner.upsert_bulk(points)
16 }
17
18 /// Bulk insert from contiguous flat slices (zero-copy from numpy / FFI).
19 ///
20 /// Accepts a flat `f32` slice of shape `(n, dimension)` in row-major order
21 /// plus a matching `u64` ID slice of length `n`. Avoids per-row `Vec<f32>`
22 /// allocation, saving ~293 MB for 100K vectors at 768D.
23 ///
24 /// # Errors
25 ///
26 /// - Returns [`crate::error::Error::InvalidVector`] if `vectors.len() != ids.len() * dimension`.
27 /// - Returns [`crate::error::Error::DimensionMismatch`] if `dimension` mismatches the collection.
28 pub fn upsert_bulk_from_raw(
29 &self,
30 vectors: &[f32],
31 ids: &[u64],
32 dimension: usize,
33 payloads: Option<&[Option<serde_json::Value>]>,
34 ) -> Result<usize> {
35 self.inner
36 .upsert_bulk_from_raw(vectors, ids, dimension, payloads)
37 }
38
39 /// Inserts or updates points in the collection.
40 ///
41 /// # Errors
42 ///
43 /// - Returns an error if any point's dimension does not match the collection.
44 /// - Returns an error if storage operations fail.
45 ///
46 /// # Examples
47 ///
48 /// ```rust,no_run
49 /// # use velesdb_core::{VectorCollection, DistanceMetric, Point, StorageMode};
50 /// # use serde_json::json;
51 /// # let coll = VectorCollection::create("./data/v".into(), "v", 128, DistanceMetric::Cosine, StorageMode::Full)?;
52 /// coll.upsert(vec![
53 /// Point::new(1, vec![0.1; 128], Some(json!({"title": "Hello"}))),
54 /// Point::new(2, vec![0.2; 128], None),
55 /// ])?;
56 /// # Ok::<(), velesdb_core::Error>(())
57 /// ```
58 pub fn upsert(&self, points: impl IntoIterator<Item = Point>) -> Result<()> {
59 self.inner.upsert(points)
60 }
61
62 /// Retrieves points by IDs, returning `None` for missing entries.
63 ///
64 /// # Examples
65 ///
66 /// ```rust,no_run
67 /// # use velesdb_core::{VectorCollection, DistanceMetric, StorageMode};
68 /// # let coll = VectorCollection::create("./data/v".into(), "v", 128, DistanceMetric::Cosine, StorageMode::Full)?;
69 /// let points = coll.get(&[1, 2, 3]);
70 /// for (id, maybe_point) in [1, 2, 3].iter().zip(&points) {
71 /// if let Some(p) = maybe_point {
72 /// println!("Found point {id} with payload {:?}", p.payload);
73 /// }
74 /// }
75 /// # Ok::<(), velesdb_core::Error>(())
76 /// ```
77 #[must_use]
78 pub fn get(&self, ids: &[u64]) -> Vec<Option<Point>> {
79 self.inner.get(ids)
80 }
81
82 /// Deletes points by IDs.
83 ///
84 /// Missing IDs are silently ignored.
85 ///
86 /// # Errors
87 ///
88 /// - Returns an error if storage operations fail.
89 ///
90 /// # Examples
91 ///
92 /// ```rust,no_run
93 /// # use velesdb_core::{VectorCollection, DistanceMetric, StorageMode};
94 /// # let coll = VectorCollection::create("./data/v".into(), "v", 128, DistanceMetric::Cosine, StorageMode::Full)?;
95 /// coll.delete(&[1, 2, 3])?;
96 /// # Ok::<(), velesdb_core::Error>(())
97 /// ```
98 pub fn delete(&self, ids: &[u64]) -> Result<()> {
99 self.inner.delete(ids)
100 }
101
102 /// Inserts or updates metadata-only points (no vectors).
103 ///
104 /// # Errors
105 ///
106 /// - Returns an error if storage operations fail.
107 pub fn upsert_metadata(
108 &self,
109 points: impl IntoIterator<Item = crate::point::Point>,
110 ) -> Result<()> {
111 self.inner.upsert_metadata(points)
112 }
113
114 /// Creates a secondary metadata index on a payload field.
115 ///
116 /// # Errors
117 ///
118 /// - Returns an error if the index already exists or storage fails.
119 pub fn create_index(&self, field: &str) -> Result<()> {
120 self.inner.create_index(field)
121 }
122
123 /// Creates a property index for O(1) equality lookups.
124 ///
125 /// # Errors
126 ///
127 /// - Returns an error if the index already exists or storage fails.
128 pub fn create_property_index(&self, label: &str, property: &str) -> Result<()> {
129 self.inner.create_property_index(label, property)
130 }
131
132 /// Creates a range index for O(log n) range queries.
133 ///
134 /// # Errors
135 ///
136 /// - Returns an error if the index already exists or storage fails.
137 pub fn create_range_index(&self, label: &str, property: &str) -> Result<()> {
138 self.inner.create_range_index(label, property)
139 }
140
141 /// Drops an index, returning `true` if an index was removed.
142 ///
143 /// # Errors
144 ///
145 /// - Returns an error if the drop operation fails.
146 pub fn drop_index(&self, label: &str, property: &str) -> Result<bool> {
147 self.inner.drop_index(label, property)
148 }
149
150 /// Adds a graph edge to the collection.
151 ///
152 /// # Errors
153 ///
154 /// Returns an error if the edge cannot be stored.
155 pub fn add_edge(&self, edge: crate::collection::GraphEdge) -> Result<()> {
156 self.inner.add_edge(edge)
157 }
158}