2008-11-26 2 views
10

Asp.net 3.5 및 Lucene.Net을 사용하는 .Net 응용 프로그램에서 작업하고 있습니다. asp.net DataGrid에서 Lucene.Net에 의해 주어진 검색 결과를 보여주고 있습니다. 이 aspx 페이지에 대해 페이징 (각 페이지에 10 개 레코드)을 구현해야합니다.Lucene.net을 사용하여 페이징

Lucene.Net을 사용하여 어떻게 완료합니까?

답변

23

다음은 Lucene.Net을 사용하여 특정 페이지와 일치하는 간단한 목록을 작성하는 방법입니다. 이것은 ASP.Net과 관련이 없습니다.

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 

기본적으로 조회수 수집은 매우 가볍습니다. 이 목록을 가져 오는 데 드는 비용은 최소한입니다. hits.Doc (i)를 호출하여 필요한 문서를 인스턴스화하면 페이지를 작성할 수 있습니다.

+1

나는 Memcache 또는 메모리 자체가 검색어 자체에 입력 된 다른 것을 사용하는 것이 좋습니다. 그렇게하면 쿼리 할 필요가 없지만 실제로 성능이 향상되는지 조사 할 필요가 있습니다. – bleevo

+0

사람들이 여기에 요점을 놓치고있는 것처럼 느껴집니다. 여기에서 요점은 Lucene 결과를 ASP.NET DataGrid와 잘 작동하는 형식으로 변환하는 방법이라고 생각합니다. ASP.NET 데이터 격자는 .NET ADO 데이터 집합과 잘 작동하도록 설계되었습니다 (다른 방법도 있습니다). 내 대답은 Lucene 개체에서 ADO.NET 개체로 변환하는 방법을 보여줍니다. DataGrid의 특성을 무시하는 경우 질문에 답변하지 않는 것 같습니다. –

+0

DataGrid는 List 과 완벽하게 작동합니다. Document 객체 및 Data에 포함 된 정보에서 목록을 그리드에 연결하면됩니다. –

-8

내가하는 일은 히트 곡을 반복하고 db의 임시 테이블에 삽입하는 것입니다. 그런 다음 임시 테이블을 다른 테이블과 조인하여 일반 SQL 쿼리를 실행할 수 있습니다. 그리드에 원하는 DataSet/DataView를 지정합니다.

하나의 SQL 배치 만 사용하기 때문에 삽입 및 쿼리를 db로 수행한다는 것에주의하십시오.

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

나는이 관행을 권장하지 않을 것이다. 많은 움직이는 부분으로가는 길. 또한 인덱스 검색을 위해 DB를 두드리는 것은 목적을 상실합니다. –

+0

@David - 세부 정보 : 내 db에는 자주 변경되는 열의 데이터 (버그, 티켓, 문제)가 포함되어 있습니다. 어느 쪽이든지 DB와 CLEN 인덱스가 갱신 될 때마다, 또는 DB 만 업데이트합니다. 나는 오직 DB 만 업데이트하기로했다. 또 다른 세부 사항 : 결과를 표시하는 응용 프로그램의 일부가 이미 존재하고 .NET DataSet/DataView 객체가 입력으로 예상됩니다. 그래서 결과를 DataSet/DataView로 변환하고 싶었습니다. OP는 DataSet/DataView를 입력으로 원하는 DataGrid에 결과를 표시하려고합니다. 부정하지 말라. 더 나은 대안을 제안하십시오. –

+0

내가 제시 한 해결책은 lucene으로 페이징하는 방법에 대한 질문에 대답합니다. 결과를 그리드에 바인딩하는 것은 쉽습니다 (다른 의견에 대한 회신 참조). –