1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct Document {
7 #[serde(skip_serializing_if = "Option::is_none")]
8 pub _id: Option<String>,
9 #[serde(flatten)]
10 pub fields: HashMap<String, FieldValue>,
11}
12
13impl Document {
14 pub fn new() -> Self {
16 Self {
17 _id: None,
18 fields: HashMap::new(),
19 }
20 }
21
22 pub fn with_id(id: impl Into<String>) -> Self {
24 Self {
25 _id: Some(id.into()),
26 fields: HashMap::new(),
27 }
28 }
29
30 pub fn with_field(mut self, key: impl Into<String>, value: impl Into<FieldValue>) -> Self {
32 self.fields.insert(key.into(), value.into());
33 self
34 }
35
36 pub fn with_vector(mut self, key: impl Into<String>, vector: Vec<f32>) -> Self {
38 self.fields.insert(key.into(), FieldValue::Vector(vector));
39 self
40 }
41
42 pub fn get_field(&self, key: &str) -> Option<&FieldValue> {
44 self.fields.get(key)
45 }
46
47 pub fn get_vector(&self, key: &str) -> Option<&Vec<f32>> {
49 if let Some(FieldValue::Vector(vector)) = self.fields.get(key) {
50 Some(vector)
51 } else {
52 None
53 }
54 }
55}
56
57impl Default for Document {
58 fn default() -> Self {
59 Self::new()
60 }
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
65#[serde(untagged)]
66pub enum FieldValue {
67 String(String),
68 Integer(i64),
69 Float(f64),
70 Boolean(bool),
71 Vector(Vec<f32>),
72 StringArray(Vec<String>),
73 IntegerArray(Vec<i64>),
74 FloatArray(Vec<f64>),
75}
76
77impl From<String> for FieldValue {
78 fn from(value: String) -> Self {
79 FieldValue::String(value)
80 }
81}
82
83impl From<&str> for FieldValue {
84 fn from(value: &str) -> Self {
85 FieldValue::String(value.to_string())
86 }
87}
88
89impl From<i32> for FieldValue {
90 fn from(value: i32) -> Self {
91 FieldValue::Integer(value as i64)
92 }
93}
94
95impl From<i64> for FieldValue {
96 fn from(value: i64) -> Self {
97 FieldValue::Integer(value)
98 }
99}
100
101impl From<f32> for FieldValue {
102 fn from(value: f32) -> Self {
103 FieldValue::Float(value as f64)
104 }
105}
106
107impl From<f64> for FieldValue {
108 fn from(value: f64) -> Self {
109 FieldValue::Float(value)
110 }
111}
112
113impl From<bool> for FieldValue {
114 fn from(value: bool) -> Self {
115 FieldValue::Boolean(value)
116 }
117}
118
119impl From<Vec<f32>> for FieldValue {
120 fn from(value: Vec<f32>) -> Self {
121 FieldValue::Vector(value)
122 }
123}
124
125impl From<Vec<String>> for FieldValue {
126 fn from(value: Vec<String>) -> Self {
127 FieldValue::StringArray(value)
128 }
129}
130
131impl From<Vec<i64>> for FieldValue {
132 fn from(value: Vec<i64>) -> Self {
133 FieldValue::IntegerArray(value)
134 }
135}
136
137impl From<Vec<f64>> for FieldValue {
138 fn from(value: Vec<f64>) -> Self {
139 FieldValue::FloatArray(value)
140 }
141}
142
143#[derive(Debug, Clone, Serialize, Deserialize)]
145pub struct VectorField {
146 pub field: String,
147 pub feature: Vec<f32>,
148 #[serde(skip_serializing_if = "Option::is_none")]
149 pub min_score: Option<f64>,
150 #[serde(skip_serializing_if = "Option::is_none")]
151 pub max_score: Option<f64>,
152}
153
154impl VectorField {
155 pub fn new(field: impl Into<String>, feature: Vec<f32>) -> Self {
157 Self {
158 field: field.into(),
159 feature,
160 min_score: None,
161 max_score: None,
162 }
163 }
164
165 pub fn with_min_score(mut self, min_score: f64) -> Self {
167 self.min_score = Some(min_score);
168 self
169 }
170
171 pub fn with_max_score(mut self, max_score: f64) -> Self {
173 self.max_score = Some(max_score);
174 self
175 }
176}
177
178#[derive(Debug, Clone, Serialize, Deserialize)]
180pub struct FilterCondition {
181 pub field: String,
182 pub operator: FilterOperator,
183 pub value: serde_json::Value,
184}
185
186#[derive(Debug, Clone, Serialize, Deserialize)]
188#[serde(rename_all = "UPPERCASE")]
189pub enum FilterOperator {
190 #[serde(rename = ">")]
191 GreaterThan,
192 #[serde(rename = ">=")]
193 GreaterThanOrEqual,
194 #[serde(rename = "<")]
195 LessThan,
196 #[serde(rename = "<=")]
197 LessThanOrEqual,
198 #[serde(rename = "IN")]
199 In,
200 #[serde(rename = "NOT IN")]
201 NotIn,
202}
203
204#[derive(Debug, Clone, Serialize, Deserialize)]
206pub struct Filter {
207 pub operator: String, pub conditions: Vec<FilterCondition>,
209}
210
211impl Filter {
212 pub fn and(conditions: Vec<FilterCondition>) -> Self {
214 Self {
215 operator: "AND".to_string(),
216 conditions,
217 }
218 }
219
220 pub fn with_condition(mut self, condition: FilterCondition) -> Self {
222 self.conditions.push(condition);
223 self
224 }
225}
226
227#[derive(Debug, Clone, Serialize, Deserialize)]
229pub struct IndexParams {
230 #[serde(skip_serializing_if = "Option::is_none")]
231 pub metric_type: Option<String>,
232 #[serde(skip_serializing_if = "Option::is_none")]
233 pub ef_search: Option<i32>,
234 #[serde(skip_serializing_if = "Option::is_none")]
235 pub nprobe: Option<i32>,
236 #[serde(skip_serializing_if = "Option::is_none")]
237 pub parallel_on_queries: Option<i32>,
238}
239
240impl IndexParams {
241 pub fn new() -> Self {
243 Self {
244 metric_type: None,
245 ef_search: None,
246 nprobe: None,
247 parallel_on_queries: None,
248 }
249 }
250
251 pub fn with_metric_type(mut self, metric_type: impl Into<String>) -> Self {
253 self.metric_type = Some(metric_type.into());
254 self
255 }
256
257 pub fn with_ef_search(mut self, ef_search: i32) -> Self {
259 self.ef_search = Some(ef_search);
260 self
261 }
262
263 pub fn with_nprobe(mut self, nprobe: i32) -> Self {
265 self.nprobe = Some(nprobe);
266 self
267 }
268}
269
270impl Default for IndexParams {
271 fn default() -> Self {
272 Self::new()
273 }
274}
275
276#[derive(Debug, Clone, Serialize, Deserialize)]
278pub struct Ranker {
279 #[serde(rename = "type")]
280 pub ranker_type: String,
281 pub params: Vec<f64>,
282}
283
284impl Ranker {
285 pub fn weighted_ranker(weights: Vec<f64>) -> Self {
287 Self {
288 ranker_type: "WeightedRanker".to_string(),
289 params: weights,
290 }
291 }
292}
293
294#[derive(Debug, Clone, Serialize, Deserialize)]
296pub struct UpsertRequest {
297 pub db_name: String,
298 pub space_name: String,
299 pub documents: Vec<Document>,
300}
301
302#[derive(Debug, Clone, Serialize, Deserialize)]
304pub struct UpsertResponse {
305 pub total: i32,
306 pub document_ids: Vec<DocumentId>,
307}
308
309#[derive(Debug, Clone, Serialize, Deserialize)]
311pub struct DocumentId {
312 pub _id: String,
313}
314
315#[derive(Debug, Clone, Serialize, Deserialize)]
317pub struct QueryRequest {
318 pub db_name: String,
319 pub space_name: String,
320 #[serde(skip_serializing_if = "Option::is_none")]
321 pub document_ids: Option<Vec<String>>,
322 #[serde(skip_serializing_if = "Option::is_none")]
323 pub partition_id: Option<i32>,
324 #[serde(skip_serializing_if = "Option::is_none")]
325 pub filters: Option<Filter>,
326 #[serde(skip_serializing_if = "Option::is_none")]
327 pub fields: Option<Vec<String>>,
328 #[serde(skip_serializing_if = "Option::is_none")]
329 pub vector_value: Option<bool>,
330 #[serde(skip_serializing_if = "Option::is_none")]
331 pub limit: Option<i32>,
332}
333
334#[derive(Debug, Clone, Serialize, Deserialize)]
336pub struct SearchRequest {
337 pub db_name: String,
338 pub space_name: String,
339 pub vectors: Vec<VectorField>,
340 #[serde(skip_serializing_if = "Option::is_none")]
341 pub filters: Option<Filter>,
342 #[serde(skip_serializing_if = "Option::is_none")]
343 pub index_params: Option<IndexParams>,
344 #[serde(skip_serializing_if = "Option::is_none")]
345 pub ranker: Option<Ranker>,
346 #[serde(skip_serializing_if = "Option::is_none")]
347 pub is_brute_search: Option<i32>,
348 #[serde(skip_serializing_if = "Option::is_none")]
349 pub vector_value: Option<bool>,
350 #[serde(skip_serializing_if = "Option::is_none")]
351 pub load_balance: Option<String>,
352 #[serde(skip_serializing_if = "Option::is_none")]
353 pub limit: Option<i32>,
354}
355
356#[derive(Debug, Clone, Serialize, Deserialize)]
358pub struct SearchResponse {
359 pub documents: Vec<Vec<SearchResult>>,
360}
361
362#[derive(Debug, Clone, Serialize, Deserialize)]
364pub struct SearchResult {
365 pub _id: String,
366 pub _score: f64,
367 #[serde(flatten)]
368 pub fields: HashMap<String, serde_json::Value>,
369}
370
371#[derive(Debug, Clone, Serialize, Deserialize)]
373pub struct DeleteRequest {
374 pub db_name: String,
375 pub space_name: String,
376 #[serde(skip_serializing_if = "Option::is_none")]
377 pub document_ids: Option<Vec<String>>,
378 #[serde(skip_serializing_if = "Option::is_none")]
379 pub filters: Option<Filter>,
380 #[serde(skip_serializing_if = "Option::is_none")]
381 pub limit: Option<i32>,
382}
383
384#[derive(Debug, Clone, Serialize, Deserialize)]
386pub struct DeleteResponse {
387 pub total: i32,
388 pub document_ids: Vec<String>,
389}
390
391#[derive(Debug, Clone, Serialize, Deserialize)]
395pub struct CreateDatabaseRequest {
396 pub name: String,
397 #[serde(skip_serializing_if = "Option::is_none")]
398 pub description: Option<String>,
399}
400
401#[derive(Debug, Clone, Serialize, Deserialize)]
403pub struct DatabaseInfo {
404 pub name: String,
405 #[serde(skip_serializing_if = "Option::is_none")]
406 pub description: Option<String>,
407 #[serde(skip_serializing_if = "Option::is_none")]
408 pub space_count: Option<i32>,
409 #[serde(skip_serializing_if = "Option::is_none")]
410 pub document_count: Option<i64>,
411}
412
413#[derive(Debug, Clone, Serialize, Deserialize)]
415pub struct ListDatabasesResponse {
416 pub databases: Vec<DatabaseInfo>,
417}
418
419#[derive(Debug, Clone, Serialize, Deserialize)]
421pub struct DatabaseResponse {
422 pub code: i32,
423 pub msg: String,
424 #[serde(skip_serializing_if = "Option::is_none")]
425 pub data: Option<serde_json::Value>,
426}
427
428#[derive(Debug, Clone, Serialize, Deserialize)]
432#[serde(rename_all = "lowercase")]
433pub enum FieldType {
434 String,
435 Integer,
436 Float,
437 Double,
438 Boolean,
439 Vector,
440 Array,
441 Date,
442 Geo,
443}
444
445#[derive(Debug, Clone, Serialize, Deserialize)]
447pub struct VectorFieldConfig {
448 pub dimension: usize,
449 #[serde(skip_serializing_if = "Option::is_none")]
450 pub model_id: Option<String>,
451 #[serde(skip_serializing_if = "Option::is_none")]
452 pub format: Option<String>,
453}
454
455#[derive(Debug, Clone, Serialize, Deserialize)]
457pub struct ArrayFieldConfig {
458 pub element_type: FieldType,
459 #[serde(skip_serializing_if = "Option::is_none")]
460 pub max_length: Option<usize>,
461}
462
463#[derive(Debug, Clone, Serialize, Deserialize)]
465pub struct FieldDefinition {
466 #[serde(rename = "type")]
467 pub field_type: FieldType,
468 #[serde(skip_serializing_if = "Option::is_none")]
469 pub dimension: Option<usize>,
470 #[serde(skip_serializing_if = "Option::is_none")]
471 pub model_id: Option<String>,
472 #[serde(skip_serializing_if = "Option::is_none")]
473 pub format: Option<String>,
474 #[serde(skip_serializing_if = "Option::is_none")]
475 pub element_type: Option<FieldType>,
476 #[serde(skip_serializing_if = "Option::is_none")]
477 pub max_length: Option<usize>,
478 #[serde(skip_serializing_if = "Option::is_none")]
479 pub index: Option<bool>,
480 #[serde(skip_serializing_if = "Option::is_none")]
481 pub store: Option<bool>,
482}
483
484#[derive(Debug, Clone, Serialize, Deserialize)]
486pub struct IndexConfig {
487 #[serde(rename = "type")]
488 pub index_type: String,
489 #[serde(skip_serializing_if = "Option::is_none")]
490 pub nlist: Option<i32>,
491 #[serde(skip_serializing_if = "Option::is_none")]
492 pub m: Option<i32>,
493 #[serde(skip_serializing_if = "Option::is_none")]
494 pub ef_construction: Option<i32>,
495 #[serde(skip_serializing_if = "Option::is_none")]
496 pub ef_search: Option<i32>,
497 #[serde(skip_serializing_if = "Option::is_none")]
498 pub metric_type: Option<String>,
499 #[serde(skip_serializing_if = "Option::is_none")]
500 pub nprobe: Option<i32>,
501 #[serde(skip_serializing_if = "Option::is_none")]
502 pub parallel_on_queries: Option<i32>,
503}
504
505#[derive(Debug, Clone, Serialize, Deserialize)]
507pub struct CreateSpaceRequest {
508 pub name: String,
509 pub fields: HashMap<String, FieldDefinition>,
510 #[serde(skip_serializing_if = "Option::is_none")]
511 pub index: Option<IndexConfig>,
512 #[serde(skip_serializing_if = "Option::is_none")]
513 pub partition_num: Option<i32>,
514 #[serde(skip_serializing_if = "Option::is_none")]
515 pub replica_num: Option<i32>,
516 #[serde(skip_serializing_if = "Option::is_none")]
517 pub description: Option<String>,
518}
519
520#[derive(Debug, Clone, Serialize, Deserialize)]
522pub struct SpaceInfo {
523 pub name: String,
524 #[serde(skip_serializing_if = "Option::is_none")]
525 pub description: Option<String>,
526 pub fields: HashMap<String, FieldDefinition>,
527 #[serde(skip_serializing_if = "Option::is_none")]
528 pub index: Option<IndexConfig>,
529 #[serde(skip_serializing_if = "Option::is_none")]
530 pub partition_num: Option<i32>,
531 #[serde(skip_serializing_if = "Option::is_none")]
532 pub replica_num: Option<i32>,
533 #[serde(skip_serializing_if = "Option::is_none")]
534 pub document_count: Option<i64>,
535 #[serde(skip_serializing_if = "Option::is_none")]
536 pub status: Option<String>,
537}
538
539#[derive(Debug, Clone, Serialize, Deserialize)]
541pub struct ListSpacesResponse {
542 pub spaces: Vec<SpaceInfo>,
543}
544
545#[derive(Debug, Clone, Serialize, Deserialize)]
547pub struct SpaceResponse {
548 pub code: i32,
549 pub msg: String,
550 #[serde(skip_serializing_if = "Option::is_none")]
551 pub data: Option<serde_json::Value>,
552}
553
554#[derive(Debug, Clone, Serialize, Deserialize)]
556pub struct SpaceStats {
557 pub name: String,
558 #[serde(skip_serializing_if = "Option::is_none")]
559 pub document_count: Option<i64>,
560 #[serde(skip_serializing_if = "Option::is_none")]
561 pub index_size: Option<i64>,
562 #[serde(skip_serializing_if = "Option::is_none")]
563 pub storage_size: Option<i64>,
564 #[serde(skip_serializing_if = "Option::is_none")]
565 pub partition_stats: Option<Vec<PartitionStats>>,
566}
567
568#[derive(Debug, Clone, Serialize, Deserialize)]
570pub struct PartitionStats {
571 pub partition_id: i32,
572 #[serde(skip_serializing_if = "Option::is_none")]
573 pub document_count: Option<i64>,
574 #[serde(skip_serializing_if = "Option::is_none")]
575 pub index_size: Option<i64>,
576 #[serde(skip_serializing_if = "Option::is_none")]
577 pub storage_size: Option<i64>,
578}
579
580#[derive(Debug, Clone, Serialize, Deserialize)]
584#[serde(rename_all = "PascalCase")]
585pub enum PrivilegeType {
586 WriteOnly,
587 ReadOnly,
588 WriteRead,
589}
590
591#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
593#[serde(rename_all = "PascalCase")]
594pub enum ResourceType {
595 ResourceAll,
596 ResourceCluster,
597 ResourceServer,
598 ResourcePartition,
599 ResourceDB,
600 ResourceSpace,
601 ResourceDocument,
602 ResourceIndex,
603 ResourceAlias,
604 ResourceUser,
605 ResourceRole,
606 ResourceConfig,
607 ResourceCache,
608}
609
610pub type Privileges = HashMap<ResourceType, PrivilegeType>;
612
613#[derive(Debug, Clone, Serialize, Deserialize)]
615#[serde(rename_all = "PascalCase")]
616pub enum Operator {
617 Grant,
618 Revoke,
619}
620
621#[derive(Debug, Clone, Serialize, Deserialize)]
623pub struct CreateRoleRequest {
624 pub name: String,
625 pub privileges: Privileges,
626}
627
628#[derive(Debug, Clone, Serialize, Deserialize)]
630pub struct ModifyRoleRequest {
631 pub name: String,
632 pub operator: Operator,
633 pub privileges: Privileges,
634}
635
636#[derive(Debug, Clone, Serialize, Deserialize)]
638pub struct RoleInfo {
639 pub name: String,
640 pub privileges: Privileges,
641}
642
643#[derive(Debug, Clone, Serialize, Deserialize)]
645pub struct ListRolesResponse {
646 pub roles: Vec<RoleInfo>,
647}
648
649#[derive(Debug, Clone, Serialize, Deserialize)]
651pub struct CreateUserRequest {
652 pub name: String,
653 pub password: String,
654 pub role_name: String,
655}
656
657#[derive(Debug, Clone, Serialize, Deserialize)]
659pub struct ModifyUserRequest {
660 pub name: String,
661 #[serde(skip_serializing_if = "Option::is_none")]
662 pub role_name: Option<String>,
663 #[serde(skip_serializing_if = "Option::is_none")]
664 pub password: Option<String>,
665 #[serde(skip_serializing_if = "Option::is_none")]
666 pub old_password: Option<String>,
667}
668
669#[derive(Debug, Clone, Serialize, Deserialize)]
671pub struct UserInfo {
672 pub name: String,
673 pub role_name: String,
674}
675
676#[derive(Debug, Clone, Serialize, Deserialize)]
678pub struct ListUsersResponse {
679 pub users: Vec<UserInfo>,
680}
681
682#[derive(Debug, Clone, Serialize, Deserialize)]
684pub struct AuthResponse {
685 pub code: i32,
686 pub msg: String,
687 #[serde(skip_serializing_if = "Option::is_none")]
688 pub data: Option<serde_json::Value>,
689}
690
691#[derive(Debug, Clone)]
693pub struct AuthConfig {
694 pub username: String,
695 pub password: String,
696 pub role_name: Option<String>,
697}
698
699#[derive(Debug, Clone, Serialize, Deserialize)]
701pub struct LoginResponse {
702 pub code: i32,
703 pub msg: String,
704 #[serde(skip_serializing_if = "Option::is_none")]
705 pub data: Option<serde_json::Value>,
706 #[serde(skip_serializing_if = "Option::is_none")]
707 pub token: Option<String>,
708}