2016-02-15 3 views
0

J'utilise lucene.net pour rechercher les détails de la facture du produit. totalement dans ce 500k (document) records & 6 zones ajoutées aux documents créés.lucene.net lent lors de la recherche sur seulement 500k enregistrements

J'utilise lucene.net version 3.0.3.0.

public DataSet Search(string criterion, string term) 
{ 

string indexPath = System.Configuration.ConfigurationManager.AppSettings["LuceneIndexPathBillSearch"]; 
      Lucene.Net.Store.Directory directory = FSDirectory.Open(new DirectoryInfo(indexPath)); 
      Analyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30); 

      IndexReader indexReader = IndexReader.Open(directory, true); 
      Searcher searcher = new IndexSearcher(indexReader); 
      var queryParser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, criterion, analyzer); 

      queryParser.AllowLeadingWildcard = true; 

      var query = queryParser.Parse(term.ToLower() + "*"); 
      var sort = new Sort(new SortField(term, SortField.STRING, false)); 

      TopDocs resultDocs = searcher.Search(query, null, indexReader.MaxDoc, sort); 
      var topDocs = resultDocs.ScoreDocs; 

      DataSet Product= new DataSet(); 
      DataTable dt = new DataTable(); 
      dt.Columns.Add("BillId"); 
      dt.Columns.Add("BillNo"); 
      dt.Columns.Add("BillDate"); 
      dt.Columns.Add("BillUniqueNo"); 
      dt.Columns.Add("ProductName"); 
      dt.Columns.Add("ProductCode"); 
      dt.Columns.Add("Status"); 
      dt.Columns.Add("IsServiceOrder"); 
      DataRow row = null; 
      foreach (var hit in topDocs) 
      { 
       var documentFromSerach = searcher.Doc(hit.Doc); 
       row = dt.NewRow(); 
       row["BillId"] = documentFromSerach.Get("BillId"); 
       row["BillNo"] = documentFromSerach.Get("BillNo"); 
       row["BillDate"] = documentFromSerach.Get("BillDate"); 
       row["BillUniqueNo"] = documentFromSerach.Get("BillUniqueNo"); 
       row["ProductName"] = documentFromSerach.Get("ProductName"); 
       row["ProductCode"] = documentFromSerach.Get("ProductCode"); 
       row["status"] = documentFromSerach.Get("status"); 
       row["IsServiceOrder"] = documentFromSerach.Get("IsServiceOrder"); 
       dt.Rows.Add(row); 
      } 
      Product.Tables.Add(dt); 

      return Product; 
    } 

Qu'est-ce que je fais mal ici? pourquoi il faut 10 à 15 secondes pour chercher du texte à partir de l'index créé?

Répondre

0

Le problème est probablement que vous créez un IndexReader pour chaque requête. Lucene passe probablement du temps à mettre en cache des valeurs de termes (entre autres choses) ce qui vous coûte du temps.

Ceci est l'équivalent de l'arrêt et du démarrage d'un serveur de base de données pour chaque requête.

Si votre index est "stable" alors maintenez simplement sur l'instance du chercheur.

Si ce n'est pas le cas, vous devez effectuer les mises à jour que vous souhaitez voir apparaître. Puis gardez et instance de l'IndexWriter. Faites toutes les mises à jour via ça (c'est threadsafe). Ensuite, créez votre recherche avec searcher = new IndexSearcher(writer.GetReader()). Cela garantira que le lecteur/chercheur est toujours à jour.

Conclusion ... ne créez/ne recréez pas beaucoup d'instances de IW, IR, IS dans votre application. Gardez une instance unique et faites tout le travail à travers cela.

Il y a beaucoup plus de nuances à cela pour perf/latence, etc.