2008-11-26 19 views
10

Asp.net 3.5 ve Lucene.Net kullanan bir .NET uygulaması üzerinde çalışıyorum Bir asp.net datagrid Lucene.Net tarafından verilen arama sonuçları gösteriyorum. Bu aspx sayfası için Paging (her sayfada 10 kayıt) uygulaması gerekiyor.Lucene.net kullanarak çağrı

Bunu Lucene.Net kullanarak nasıl yapabilirim?

cevap

23

İşte Lucene.Net ile belirli bir sayfa ile eşleşen basit bir liste oluşturmanın bir yoludur. Bu ASP.Net özgü değil.

int first = 0, last = 9; // TODO: Set first and last to correct values according to page number and size 
Searcher searcher = new IndexSearcher(YourIndexFolder); 
Query query = BuildQuery(); // TODO: Implement BuildQuery 
Hits hits = searcher.Search(query); 
List<Document> results = new List<Document>(); 
for (int i = first; i <= last && i < hits.Length(); i++) 
    results.Add(hits.Doc(i)); 

// results now contains a page of documents matching the query 

Temel olarak Hits koleksiyonu çok hafiftir. Bu listeyi alma maliyeti minimumdur. Sayfanızı oluşturmak için hits.Doc (i) öğesini çağırarak gerekli Dokümanları başlatmanız yeterlidir.

+1

Memcache veya başka bir şey kullanarak arama terimine yazılan bellek deposunda bir şey kullanmanızı öneririm. Bu şekilde, isteme gereği duymazsınız, ancak bunun gerçekten performansı artırıp artırmadığını araştırın. – bleevo

+0

Burada insanların eksik olduğu gibi hissediyorum. Bence burada nokta Lucene sonuçlarını ASP.NET datagrid ile iyi çalışan bir biçime dönüştürmek. ASP.NET datagrid, .NET ADO veri kümeleriyle iyi çalışacak şekilde tasarlanmıştır (kullanımı için başka yollar olsa da). Cevabım Lucene nesnelerini ADO.NET nesnelerine dönüştürmenin bir yolunu gösteriyor. DataGrid'in özelliklerini göz ardı ederseniz, sorumu yanıtlamadığını düşünüyorum. –

+0

Datagrid, bir Liste ile mükemmel şekilde çalışır. Sadece Belge nesnelerinde yer alan bilgilerden listeyi oluşturun ve bunu DataBind'e ızgaraya ekleyin. –

-8

Yaptığım şey isabet boyunca yinelemek ve db'de geçici bir tabloya eklemek. Daha sonra normal bir SQL sorgusunu çalıştırabilirim - bu tabloyu diğer tablolarla da bir araya getiriyorum - ve grid'e istediği DataSet/DataView'ı veriyorum.

Yalnızca bir SQL toplu iş kullanıyorum çünkü insert'leri ve sorguyu ONE TRIP'de db'ye yaptığımı unutmayın.

void Page_Load(Object sender, EventArgs e) 
{ 

    dbutil = new DbUtil(); 
    security = new Security(); 
    security.check_security(dbutil, HttpContext.Current, Security.ANY_USER_OK); 

    Lucene.Net.Search.Query query = null; 

    try 
    { 
     if (string.IsNullOrEmpty(Request["query"])) 
     { 
      throw new Exception("You forgot to enter something to search for..."); 
     } 

     query = MyLucene.parser.Parse(Request["query"]); 

    } 
    catch (Exception e3) 
    { 
     display_exception(e3); 
    } 


    Lucene.Net.Highlight.QueryScorer scorer = new Lucene.Net.Highlight.QueryScorer(query); 
    Lucene.Net.Highlight.Highlighter highlighter = new Lucene.Net.Highlight.Highlighter(MyLucene.formatter, scorer); 
    highlighter.SetTextFragmenter(MyLucene.fragmenter); // new Lucene.Net.Highlight.SimpleFragmenter(400)); 

    StringBuilder sb = new StringBuilder(); 
    string guid = Guid.NewGuid().ToString().Replace("-", ""); 
    Dictionary<string, int> dict_already_seen_ids = new Dictionary<string, int>(); 

    sb.Append(@" 
create table #$GUID 
(
temp_bg_id int, 
temp_bp_id int, 
temp_score float, 
temp_text nvarchar(3000) 
) 
    "); 

    lock (MyLucene.my_lock) 
    { 

     Lucene.Net.Search.Hits hits = null; 
     try 
     { 
      hits = MyLucene.search(query); 
     } 
     catch (Exception e2) 
     { 
      display_exception(e2); 
     } 

     // insert the search results into a temp table which we will join with what's in the database 
     for (int i = 0; i < hits.Length(); i++) 
     { 
      if (dict_already_seen_ids.Count < 100) 
      { 
       Lucene.Net.Documents.Document doc = hits.Doc(i); 
       string bg_id = doc.Get("bg_id"); 
       if (!dict_already_seen_ids.ContainsKey(bg_id)) 
       { 
        dict_already_seen_ids[bg_id] = 1; 
        sb.Append("insert into #"); 
        sb.Append(guid); 
        sb.Append(" values("); 
        sb.Append(bg_id); 
        sb.Append(","); 
        sb.Append(doc.Get("bp_id")); 
        sb.Append(","); 
        //sb.Append(Convert.ToString((hits.Score(i)))); 
        sb.Append(Convert.ToString((hits.Score(i))).Replace(",", ".")); // Somebody said this fixes a bug. Localization issue? 
        sb.Append(",N'"); 

        string raw_text = Server.HtmlEncode(doc.Get("raw_text")); 
        Lucene.Net.Analysis.TokenStream stream = MyLucene.anal.TokenStream("", new System.IO.StringReader(raw_text)); 
        string highlighted_text = highlighter.GetBestFragments(stream, raw_text, 1, "...").Replace("'", "''"); 
        if (highlighted_text == "") // someties the highlighter fails to emit text... 
        { 
         highlighted_text = raw_text.Replace("'","''"); 
        } 
        if (highlighted_text.Length > 3000) 
        { 
         highlighted_text = highlighted_text.Substring(0,3000); 
        } 
        sb.Append(highlighted_text); 
        sb.Append("'"); 
        sb.Append(")\n"); 
       } 
      } 
      else 
      { 
       break; 
      } 
     } 
     //searcher.Close(); 
    } 
+1

Bu uygulamayı vazgeçiririm. Birçok hareketli parçaya giden yol. Ayrıca, bir dizin arama türü için DB çarpmak amacı yener. –

+0

@David - Ayrıntılar: My db sıkça değişen sütunlara sahip veriler (hatalar, biletler, sorunlar) içerir. Ya bu sütunlar değiştiğinde db AND Lucene dizinini güncelleştirir, VEYA SADECE db'yi güncellerim. Sadece db'yi güncellemeyi seçtim. Başka bir ayrıntı: Uygulamamın sonuçları görüntüleyen kısmı zaten vardı ve bir .NET DataSet/DataView nesnesini girdi olarak bekliyordu. Bu yüzden sonuçları bir DataSet/DataView'e çevirmek istedim. OP, sonuçları bir DataSet/DataView girişi olarak isteyen bir datagrid'de görüntülemek ister. Sadece reddetme. Daha iyi bir altneratif öner. –

+0

Sunulan çözüm, lucene ile nasıl çağrı yapılacağı sorusunu yanıtlıyor. Sonuçların bir ızgaraya bağlanması daha sonra kolay olacaktır (diğer yorumunuza cevabım konusuna bakın). –