#![allow(dead_code)]
use async_trait::async_trait;
use crate::{
SearchResult, SearchDocument, SearchQuery, SearchStats,
SearchBackend, SearchResults
};
use std::collections::HashMap;
#[async_trait]
pub trait SearchService: Send + Sync {
async fn create_index(&self, index_name: &str, config: Option<IndexConfig>) -> SearchResult<bool>;
async fn delete_index(&self, index_name: &str) -> SearchResult<bool>;
async fn list_indices(&self) -> SearchResult<Vec<String>>;
async fn get_index(&self, index_name: &str) -> SearchResult<Option<IndexInfo>>;
async fn index_exists(&self, index_name: &str) -> SearchResult<bool>;
async fn index_document(&self, index_name: &str, document: SearchDocument) -> SearchResult<String>;
async fn index_documents(&self, index_name: &str, documents: Vec<SearchDocument>) -> SearchResult<Vec<IndexResult>>;
async fn update_document(&self, index_name: &str, document_id: &str, updates: HashMap<String, serde_json::Value>) -> SearchResult<bool>;
async fn delete_document(&self, index_name: &str, document_id: &str) -> SearchResult<bool>;
async fn get_document(&self, index_name: &str, document_id: &str) -> SearchResult<Option<SearchDocument>>;
async fn update_fields(&self, index_name: &str, document_id: &str, fields: HashMap<String, serde_json::Value>) -> SearchResult<bool>;
async fn search(&self, index_name: &str, query: SearchQuery) -> SearchResult<SearchResults>;
async fn search_multiple(&self, indices: Vec<String>, query: SearchQuery) -> SearchResult<SearchResults>;
async fn text_search(&self, index_name: &str, text: &str, limit: Option<usize>) -> SearchResult<SearchResults>;
async fn suggestions(&self, index_name: &str, text: &str, limit: usize) -> SearchResult<Vec<String>>;
async fn get_analytics(&self, index_name: &str, time_range: TimeRange) -> SearchResult<SearchAnalytics>;
async fn get_stats(&self, index_name: &str) -> SearchResult<SearchStats>;
async fn rebuild_index(&self, index_name: &str, config: Option<IndexConfig>) -> SearchResult<bool>;
async fn validate_config(&self) -> SearchResult<bool>;
async fn test_connection(&self) -> SearchResult<bool>;
fn backend_type(&self) -> SearchBackend;
async fn optimize_index(&self, index_name: &str) -> SearchResult<bool>;
async fn get_mapping(&self, index_name: &str) -> SearchResult<IndexMapping>;
async fn update_mapping(&self, index_name: &str, mapping: IndexMapping) -> SearchResult<bool>;
async fn bulk_operation(&self, index_name: &str, operations: Vec<BulkOperation>) -> SearchResult<BulkResult>;
}
#[derive(Debug, Clone)]
pub struct IndexConfig {
pub primary_shards: u32,
pub replica_shards: u32,
pub settings: HashMap<String, serde_json::Value>,
pub mappings: IndexMapping,
pub analyzers: HashMap<String, Analyzer>,
pub aliases: Vec<String>,
pub template: Option<String>,
}
impl Default for IndexConfig {
fn default() -> Self {
Self {
primary_shards: 1,
replica_shards: 1,
settings: HashMap::new(),
mappings: IndexMapping::default(),
analyzers: HashMap::new(),
aliases: Vec::new(),
template: None,
}
}
}
#[derive(Debug, Clone)]
pub struct IndexInfo {
pub name: String,
pub status: IndexStatus,
pub document_count: u64,
pub size_bytes: u64,
pub primary_shards: u32,
pub replica_shards: u32,
pub created_at: chrono::DateTime<chrono::Utc>,
pub updated_at: Option<chrono::DateTime<chrono::Utc>>,
pub health: IndexHealth,
pub backend_info: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IndexStatus {
Creating,
Active,
Deleting,
Closed,
Error,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IndexHealth {
Green,
Yellow,
Red,
}
#[derive(Debug, Clone, Default)]
pub struct IndexMapping {
pub properties: HashMap<String, FieldMapping>,
pub dynamic: Option<DynamicMapping>,
pub date_formats: Vec<String>,
pub custom_types: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone)]
pub struct FieldMapping {
pub field_type: FieldType,
pub indexed: bool,
pub stored: bool,
pub analyzed: bool,
pub analyzer: Option<String>,
pub format: Option<String>,
pub boost: Option<f32>,
pub properties: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum FieldType {
Text,
Keyword,
Integer,
Long,
Float,
Double,
Boolean,
Date,
Object,
Array,
Binary,
GeoPoint,
GeoShape,
Ip,
Completion,
Nested,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DynamicMapping {
True,
False,
Strict,
}
#[derive(Debug, Clone)]
pub struct Analyzer {
pub tokenizer: String,
pub char_filters: Vec<String>,
pub token_filters: Vec<String>,
pub analyzer_type: Option<String>,
}
#[derive(Debug, Clone)]
pub struct IndexResult {
pub id: String,
pub index: String,
pub success: bool,
pub error: Option<String>,
pub version: Option<u64>,
pub metadata: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone)]
pub struct BulkOperation {
pub operation_type: BulkOperationType,
pub id: String,
pub document: Option<SearchDocument>,
pub updates: Option<HashMap<String, serde_json::Value>>,
pub routing: Option<String>,
pub timestamp: Option<chrono::DateTime<chrono::Utc>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BulkOperationType {
Index,
Create,
Update,
Delete,
}
#[derive(Debug, Clone)]
pub struct BulkResult {
pub total: u64,
pub successful: u64,
pub failed: u64,
pub results: Vec<BulkOperationResult>,
pub errors: Vec<BulkError>,
pub processing_time_ms: u64,
}
#[derive(Debug, Clone)]
pub struct BulkOperationResult {
pub index: u64,
pub operation_type: BulkOperationType,
pub id: String,
pub success: bool,
pub error: Option<BulkError>,
pub version: Option<u64>,
pub metadata: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone)]
pub struct BulkError {
pub error_type: String,
pub reason: String,
pub details: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone)]
pub struct TimeRange {
pub start: chrono::DateTime<chrono::Utc>,
pub end: chrono::DateTime<chrono::Utc>,
pub interval: Option<TimeInterval>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TimeInterval {
Minute,
Hour,
Day,
Week,
Month,
Year,
}
#[derive(Debug, Clone)]
pub struct SearchAnalytics {
pub total_searches: u64,
pub avg_query_time_ms: f64,
pub popular_terms: Vec<SearchTerm>,
pub no_result_terms: Vec<SearchTerm>,
pub search_frequency: HashMap<String, u64>,
pub performance_metrics: PerformanceMetrics,
pub user_behavior: UserBehavior,
}
#[derive(Debug, Clone)]
pub struct SearchTerm {
pub term: String,
pub count: u64,
pub avg_results: f64,
pub ctr: f64,
}
#[derive(Debug, Clone)]
pub struct PerformanceMetrics {
pub query_time_stats: QueryTimeStats,
pub index_size_trend: Vec<SizePoint>,
pub document_count_trend: Vec<CountPoint>,
pub cache_hit_rate: f64,
}
#[derive(Debug, Clone)]
pub struct QueryTimeStats {
pub min_ms: u64,
pub max_ms: u64,
pub avg_ms: f64,
pub p95_ms: u64,
pub p99_ms: u64,
}
#[derive(Debug, Clone)]
pub struct SizePoint {
pub timestamp: chrono::DateTime<chrono::Utc>,
pub size_bytes: u64,
}
#[derive(Debug, Clone)]
pub struct CountPoint {
pub timestamp: chrono::DateTime<chrono::Utc>,
pub count: u64,
}
#[derive(Debug, Clone)]
pub struct UserBehavior {
pub avg_session_duration: f64,
pub avg_searches_per_session: f64,
pub search_ctr: f64,
pub filter_usage: HashMap<String, u64>,
pub facet_usage: HashMap<String, u64>,
}