You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
implSearchEngine{pubfnoptimize_index(&self) -> Result<()>{// Fusionner les segments pour améliorer les performancesletmut writer = self.index.writer(50_000_000)?;
writer.merge_segments()?;
writer.commit()?;Ok(())}pubfnsearch_fast(&self,query:&str,limit:usize) -> Result<Vec<SearchResult>>{// Utiliser un reader réutilisable (pool de readers)let reader = self.index.reader()?;let searcher = reader.searcher();// Parser la requête une seule foislet query_parser = QueryParser::for_index(&self.index,vec![self.title_field,self.body_field],);let query = query_parser.parse_query(query)?;// Limiter le nombre de résultatslet top_docs = searcher.search(&query,&TopDocs::with_limit(limit.min(100)))?;// ...}}
Cache des résultats
use std::collections::HashMap;use std::time::{Duration,Instant};pubstructCachedSearchEngine{engine:SearchEngine,cache:HashMap<String,(Vec<SearchResult>,Instant)>,cache_ttl:Duration,}implCachedSearchEngine{pubfnnew(engine:SearchEngine) -> Self{Self{
engine,cache:HashMap::new(),cache_ttl:Duration::from_secs(60),}}pubfnsearch(&mutself,query:&str,limit:usize) -> Result<Vec<SearchResult>>{let cache_key = format!("{}:{}", query, limit);// Vérifier le cacheifletSome((results, cached_at)) = self.cache.get(&cache_key){if cached_at.elapsed() < self.cache_ttl{returnOk(results.clone());}}// Recherche réellelet results = self.engine.search(query, limit)?;// Mettre en cacheself.cache.insert(cache_key,(results.clone(),Instant::now()));// Nettoyer le cache expiréself.cache.retain(|_,(_, cached_at)| cached_at.elapsed() < self.cache_ttl);Ok(results)}}
Indexation asynchrone
use tokio::sync::mpsc;pubstructAsyncIndexer{engine:Arc<SearchEngine>,tx: mpsc::UnboundedSender<IndexCommand>,}implAsyncIndexer{pubfnnew(engine:Arc<SearchEngine>) -> Self{let(tx,mut rx) = mpsc::unbounded_channel();let engine_clone = Arc::clone(&engine);
tokio::spawn(asyncmove{whileletSome(cmd) = rx.recv().await{match cmd {IndexCommand::Index{ id, title, body } => {
engine_clone.index_document(&id,&title,&body).ok();}IndexCommand::Delete{ id } => {
engine_clone.delete_document(&id).ok();}IndexCommand::Rebuild => {
engine_clone.rebuild_index().ok();}}}});Self{ engine, tx }}pubfnqueue_index(&self,id:String,title:String,body:String){self.tx.send(IndexCommand::Index{ id, title, body }).ok();}}
Résumé
Optimisation : Fusionner les segments régulièrement
Cache : Mettre en cache les résultats fréquents
Asynchrone : Indexation non bloquante
Limites : Limiter le nombre de résultats pour la performance