Skip to main content

backbone_search/
traits.rs

1//! Search service traits
2#![allow(dead_code)]
3
4use async_trait::async_trait;
5use crate::{
6    SearchResult, SearchDocument, SearchQuery, SearchStats,
7    SearchBackend, SearchResults
8};
9use std::collections::HashMap;
10
11/// Generic search service trait
12#[async_trait]
13pub trait SearchService: Send + Sync {
14    /// Create search index
15    async fn create_index(&self, index_name: &str, config: Option<IndexConfig>) -> SearchResult<bool>;
16
17    /// Delete search index
18    async fn delete_index(&self, index_name: &str) -> SearchResult<bool>;
19
20    /// List all indices
21    async fn list_indices(&self) -> SearchResult<Vec<String>>;
22
23    /// Get index information
24    async fn get_index(&self, index_name: &str) -> SearchResult<Option<IndexInfo>>;
25
26    /// Check if index exists
27    async fn index_exists(&self, index_name: &str) -> SearchResult<bool>;
28
29    /// Index a single document
30    async fn index_document(&self, index_name: &str, document: SearchDocument) -> SearchResult<String>;
31
32    /// Index multiple documents
33    async fn index_documents(&self, index_name: &str, documents: Vec<SearchDocument>) -> SearchResult<Vec<IndexResult>>;
34
35    /// Update a document
36    async fn update_document(&self, index_name: &str, document_id: &str, updates: HashMap<String, serde_json::Value>) -> SearchResult<bool>;
37
38    /// Delete a document
39    async fn delete_document(&self, index_name: &str, document_id: &str) -> SearchResult<bool>;
40
41    /// Get document by ID
42    async fn get_document(&self, index_name: &str, document_id: &str) -> SearchResult<Option<SearchDocument>>;
43
44    /// Update document fields
45    async fn update_fields(&self, index_name: &str, document_id: &str, fields: HashMap<String, serde_json::Value>) -> SearchResult<bool>;
46
47    /// Search documents
48    async fn search(&self, index_name: &str, query: SearchQuery) -> SearchResult<SearchResults>;
49
50    /// Search across multiple indices
51    async fn search_multiple(&self, indices: Vec<String>, query: SearchQuery) -> SearchResult<SearchResults>;
52
53    /// Simple text search
54    async fn text_search(&self, index_name: &str, text: &str, limit: Option<usize>) -> SearchResult<SearchResults>;
55
56    /// Get search suggestions
57    async fn suggestions(&self, index_name: &str, text: &str, limit: usize) -> SearchResult<Vec<String>>;
58
59    /// Get search analytics
60    async fn get_analytics(&self, index_name: &str, time_range: TimeRange) -> SearchResult<SearchAnalytics>;
61
62    /// Get search statistics
63    async fn get_stats(&self, index_name: &str) -> SearchResult<SearchStats>;
64
65    /// Rebuild index
66    async fn rebuild_index(&self, index_name: &str, config: Option<IndexConfig>) -> SearchResult<bool>;
67
68    /// Validate search configuration
69    async fn validate_config(&self) -> SearchResult<bool>;
70
71    /// Test search connection
72    async fn test_connection(&self) -> SearchResult<bool>;
73
74    /// Get backend type
75    fn backend_type(&self) -> SearchBackend;
76
77    /// Optimize index for search performance
78    async fn optimize_index(&self, index_name: &str) -> SearchResult<bool>;
79
80    /// Get mapping for index
81    async fn get_mapping(&self, index_name: &str) -> SearchResult<IndexMapping>;
82
83    /// Update index mapping
84    async fn update_mapping(&self, index_name: &str, mapping: IndexMapping) -> SearchResult<bool>;
85
86    /// Bulk operation (index, update, delete)
87    async fn bulk_operation(&self, index_name: &str, operations: Vec<BulkOperation>) -> SearchResult<BulkResult>;
88}
89
90/// Search index configuration
91#[derive(Debug, Clone)]
92pub struct IndexConfig {
93    /// Number of primary shards
94    pub primary_shards: u32,
95
96    /// Number of replica shards
97    pub replica_shards: u32,
98
99    /// Index settings
100    pub settings: HashMap<String, serde_json::Value>,
101
102    /// Field mappings
103    pub mappings: IndexMapping,
104
105    /// Custom analyzers
106    pub analyzers: HashMap<String, Analyzer>,
107
108    /// Index aliases
109    pub aliases: Vec<String>,
110
111    /// Index template
112    pub template: Option<String>,
113}
114
115impl Default for IndexConfig {
116    fn default() -> Self {
117        Self {
118            primary_shards: 1,
119            replica_shards: 1,
120            settings: HashMap::new(),
121            mappings: IndexMapping::default(),
122            analyzers: HashMap::new(),
123            aliases: Vec::new(),
124            template: None,
125        }
126    }
127}
128
129/// Index information
130#[derive(Debug, Clone)]
131pub struct IndexInfo {
132    /// Index name
133    pub name: String,
134
135    /// Index status
136    pub status: IndexStatus,
137
138    /// Document count
139    pub document_count: u64,
140
141    /// Index size in bytes
142    pub size_bytes: u64,
143
144    /// Primary shards
145    pub primary_shards: u32,
146
147    /// Replica shards
148    pub replica_shards: u32,
149
150    /// Creation timestamp
151    pub created_at: chrono::DateTime<chrono::Utc>,
152
153    /// Last updated timestamp
154    pub updated_at: Option<chrono::DateTime<chrono::Utc>>,
155
156    /// Health status
157    pub health: IndexHealth,
158
159    /// Backend-specific info
160    pub backend_info: HashMap<String, serde_json::Value>,
161}
162
163/// Index status
164#[derive(Debug, Clone, Copy, PartialEq, Eq)]
165pub enum IndexStatus {
166    Creating,
167    Active,
168    Deleting,
169    Closed,
170    Error,
171}
172
173/// Index health
174#[derive(Debug, Clone, Copy, PartialEq, Eq)]
175pub enum IndexHealth {
176    Green,
177    Yellow,
178    Red,
179}
180
181/// Index mapping
182#[derive(Debug, Clone, Default)]
183pub struct IndexMapping {
184    /// Field mappings
185    pub properties: HashMap<String, FieldMapping>,
186
187    /// Dynamic mapping rules
188    pub dynamic: Option<DynamicMapping>,
189
190    /// Date formats
191    pub date_formats: Vec<String>,
192
193    /// Custom field types
194    pub custom_types: HashMap<String, serde_json::Value>,
195}
196
197/// Field mapping
198#[derive(Debug, Clone)]
199pub struct FieldMapping {
200    /// Field type
201    pub field_type: FieldType,
202
203    /// Whether field is indexed
204    pub indexed: bool,
205
206    /// Whether field is stored
207    pub stored: bool,
208
209    /// Whether field is analyzed
210    pub analyzed: bool,
211
212    /// Field analyzer
213    pub analyzer: Option<String>,
214
215    /// Field format
216    pub format: Option<String>,
217
218    /// Field boost
219    pub boost: Option<f32>,
220
221    /// Field properties
222    pub properties: HashMap<String, serde_json::Value>,
223}
224
225/// Field type
226#[derive(Debug, Clone, PartialEq, Eq)]
227pub enum FieldType {
228    Text,
229    Keyword,
230    Integer,
231    Long,
232    Float,
233    Double,
234    Boolean,
235    Date,
236    Object,
237    Array,
238    Binary,
239    GeoPoint,
240    GeoShape,
241    Ip,
242    Completion,
243    Nested,
244}
245
246/// Dynamic mapping
247#[derive(Debug, Clone, Copy, PartialEq, Eq)]
248pub enum DynamicMapping {
249    True,
250    False,
251    Strict,
252}
253
254/// Text analyzer
255#[derive(Debug, Clone)]
256pub struct Analyzer {
257    /// Tokenizer
258    pub tokenizer: String,
259
260    /// Character filters
261    pub char_filters: Vec<String>,
262
263    /// Token filters
264    pub token_filters: Vec<String>,
265
266    /// Analyzer type
267    pub analyzer_type: Option<String>,
268}
269
270/// Index operation result
271#[derive(Debug, Clone)]
272pub struct IndexResult {
273    /// Document ID
274    pub id: String,
275
276    /// Index name
277    pub index: String,
278
279    /// Operation status
280    pub success: bool,
281
282    /// Error message (if failed)
283    pub error: Option<String>,
284
285    /// Version number
286    pub version: Option<u64>,
287
288    /// Operation metadata
289    pub metadata: HashMap<String, serde_json::Value>,
290}
291
292/// Bulk operation
293#[derive(Debug, Clone)]
294pub struct BulkOperation {
295    /// Operation type
296    pub operation_type: BulkOperationType,
297
298    /// Document ID
299    pub id: String,
300
301    /// Document data (for index/update operations)
302    pub document: Option<SearchDocument>,
303
304    /// Updates (for update operations)
305    pub updates: Option<HashMap<String, serde_json::Value>>,
306
307    /// Routing value
308    pub routing: Option<String>,
309
310    /// Timestamp
311    pub timestamp: Option<chrono::DateTime<chrono::Utc>>,
312}
313
314/// Bulk operation type
315#[derive(Debug, Clone, Copy, PartialEq, Eq)]
316pub enum BulkOperationType {
317    Index,
318    Create,
319    Update,
320    Delete,
321}
322
323/// Bulk operation result
324#[derive(Debug, Clone)]
325pub struct BulkResult {
326    /// Total operations
327    pub total: u64,
328
329    /// Successful operations
330    pub successful: u64,
331
332    /// Failed operations
333    pub failed: u64,
334
335    /// Operation results
336    pub results: Vec<BulkOperationResult>,
337
338    /// Errors
339    pub errors: Vec<BulkError>,
340
341    /// Processing time in milliseconds
342    pub processing_time_ms: u64,
343}
344
345/// Bulk operation result
346#[derive(Debug, Clone)]
347pub struct BulkOperationResult {
348    /// Operation index
349    pub index: u64,
350
351    /// Operation type
352    pub operation_type: BulkOperationType,
353
354    /// Document ID
355    pub id: String,
356
357    /// Success status
358    pub success: bool,
359
360    /// Error details (if failed)
361    pub error: Option<BulkError>,
362
363    /// Version number
364    pub version: Option<u64>,
365
366    /// Result metadata
367    pub metadata: HashMap<String, serde_json::Value>,
368}
369
370/// Bulk error
371#[derive(Debug, Clone)]
372pub struct BulkError {
373    /// Error type
374    pub error_type: String,
375
376    /// Error reason
377    pub reason: String,
378
379    /// Error details
380    pub details: HashMap<String, serde_json::Value>,
381}
382
383/// Time range for analytics
384#[derive(Debug, Clone)]
385pub struct TimeRange {
386    /// Start time
387    pub start: chrono::DateTime<chrono::Utc>,
388
389    /// End time
390    pub end: chrono::DateTime<chrono::Utc>,
391
392    /// Time interval
393    pub interval: Option<TimeInterval>,
394}
395
396/// Time interval
397#[derive(Debug, Clone, Copy, PartialEq, Eq)]
398pub enum TimeInterval {
399    Minute,
400    Hour,
401    Day,
402    Week,
403    Month,
404    Year,
405}
406
407/// Search analytics
408#[derive(Debug, Clone)]
409pub struct SearchAnalytics {
410    /// Total number of searches
411    pub total_searches: u64,
412
413    /// Average query time in milliseconds
414    pub avg_query_time_ms: f64,
415
416    /// Popular search terms
417    pub popular_terms: Vec<SearchTerm>,
418
419    /// No-result searches
420    pub no_result_terms: Vec<SearchTerm>,
421
422    /// Search frequency by time
423    pub search_frequency: HashMap<String, u64>,
424
425    /// Performance metrics
426    pub performance_metrics: PerformanceMetrics,
427
428    /// User behavior analytics
429    pub user_behavior: UserBehavior,
430}
431
432/// Search term
433#[derive(Debug, Clone)]
434pub struct SearchTerm {
435    /// Term text
436    pub term: String,
437
438    /// Search count
439    pub count: u64,
440
441    /// Average result count
442    pub avg_results: f64,
443
444    /// Click-through rate
445    pub ctr: f64,
446}
447
448/// Performance metrics
449#[derive(Debug, Clone)]
450pub struct PerformanceMetrics {
451    /// Query time statistics
452    pub query_time_stats: QueryTimeStats,
453
454    /// Index size over time
455    pub index_size_trend: Vec<SizePoint>,
456
457    /// Document count over time
458    pub document_count_trend: Vec<CountPoint>,
459
460    /// Cache hit rate
461    pub cache_hit_rate: f64,
462}
463
464/// Query time statistics
465#[derive(Debug, Clone)]
466pub struct QueryTimeStats {
467    /// Minimum query time
468    pub min_ms: u64,
469
470    /// Maximum query time
471    pub max_ms: u64,
472
473    /// Average query time
474    pub avg_ms: f64,
475
476    /// 95th percentile query time
477    pub p95_ms: u64,
478
479    /// 99th percentile query time
480    pub p99_ms: u64,
481}
482
483/// Size point over time
484#[derive(Debug, Clone)]
485pub struct SizePoint {
486    /// Timestamp
487    pub timestamp: chrono::DateTime<chrono::Utc>,
488
489    /// Size in bytes
490    pub size_bytes: u64,
491}
492
493/// Count point over time
494#[derive(Debug, Clone)]
495pub struct CountPoint {
496    /// Timestamp
497    pub timestamp: chrono::DateTime<chrono::Utc>,
498
499    /// Count
500    pub count: u64,
501}
502
503/// User behavior analytics
504#[derive(Debug, Clone)]
505pub struct UserBehavior {
506    /// Average session duration
507    pub avg_session_duration: f64,
508
509    /// Average searches per session
510    pub avg_searches_per_session: f64,
511
512    /// Search result click-through rate
513    pub search_ctr: f64,
514
515    /// Filter usage statistics
516    pub filter_usage: HashMap<String, u64>,
517
518    /// Facet usage statistics
519    pub facet_usage: HashMap<String, u64>,
520}