DotLucene: 뛰어난 full-text 검색 엔진


37 라인으로 Full-Text 검색 코드를 작성할 있을까? 글쎄, 나는 약간의 편법을 예정이고, 이를 위해 DotLucene 이용할 것이다. DotLucene Jakarta Lucene 검색 엔진을 George Aroush et al .NET으로 포팅 것이다. 기능은 대략 이러하다.

  • Win Form이나 console application ASP.NET에서 사용 가능하다.
  • 매우 좋은 성능을 낸다.
  • 검색 결과에 순위가 매겨져 있다.
  • 결과에 검색 쿼리가 강조 된다.
  • 구조적이거나 비구조적인 데이터를 검색한다.
  • 메타베이스 검색
  • 색인의 크기는 색인된 텍스트의 대략 30%이다.
  • 또한 완전하게 색인된 문서들을 저장할 있다.
  • 244 KB 짜리 단일 어셈블리에서 Pure managed .NET
  • 매우 친숙한 라이센스(Apache Software License 2.0).
  • 지역화가 가능하다(브라질어, 체코어, 중국어, 네덜란드어, 영어, 프랑스어, 일본어, 한국어 그리고 러시아어를 포함).
  • 확장 가능하다(소스코드가 포함되어 있다).

경고


라인 수를 너무 심각하게 따지지 말라. 여기에서는 핵심 기능을 37 라인의 코드를 넘기지 않고 구현하는 것을 보여줄 것이다. 하지만, 실제 애플리케이션에서는 많은 시간을 들여야 수도 있다.

 

데모 프로젝트


어떻게 동작하는 보여줄 간단한 데모 프로젝트를 빌드 것이다.

  • 색인 HTML 파일들은 특정 디텍토리 안에서 찾는다(하위 디렉토리 포함).
  • ASP.NET 애플리케이션을 통한 색인 검색
  • 검색 결과의 쿼리 단어를 강조

DotLucene 많은 잠재적인 가능성을 가지고 있다. 실제 애플리케이션에서는 이러한 기능들을 원할 것이다.

  • 디렉토리에 새로운 문서가 나타나면 이를 색인에 추가한다. 따라서 전체 색인을 재빌드 필요가 없다.
  • 다른 파일 타입을 포함한다. DotLucene 평문(plain text)으로 변환할 있는 어떠한 파일 타입이라도 색인 있다.

Microsoft Indexing Server 이용하지 않는가?


만약 Indexing Server 만족한다면, 문제없다. 하지만, DotLucene 많은 강점들을 가지고 있다.

  • DotLucene 100% managed code 단일 어셈블리이다. 이는 외부에 의존할 필요가 없음을 말한다.
  • shared hosting 이용하기 때문에, 미리 색인을 준비하였다면 퍼미션을 필요가 없다.
  • 데이터베이스나 등의 소스에서라도 어떠한 타입의 데이터라도 색인하여 사용할 있다. 때문에 평문을 indexer 제공해야 필요가 있다. 소스의 로딩과 파싱은 당신의 선택에 달려 있다.
  • 색인에 포함된 특정한 속성("fields") 있다. 이들 필드를 통해 검색할 있다.
  • 오픈 소스이다.
  • 쉽게 확장 가능하다.

1 라인: 색인 생성


다음의 코드는 새로운 색인을 생성하여 디스크에 저장한다. directory 색인이 저장될 디렉토리 경로이다.

 

IndexWriter writer =

   new IndexWriter(directory, new StandardAnalyzer(), true);


이번 예제에서는, scratch로부터 색인을 생성한다. 이는 필수가 아니며, 존재하는 색인을 열거나 문서를 추가할 있다. 게다가 존재하는 문서를 삭제하거나 새로운 버전을 추가하여 업데이트 있다.

 

2 – 12 라인: 문서 추가


HTML 문서에서 색인에 필드를 추가한다.

  • text 필드는 HTML 파일 (with stripped tags) 텍스트를 포함한다. 텍스트는 스스로 색인에 저장되지 않는다.
  • path 필드는 파일 경로를 포함한다. 여기에 지정된 색인에 전체가 색인되고 저장된다.

public void AddHtmlDocument(string path)

{

    Document doc = new Document();

 

    string rawText;

    using (StreamReader sr =

       new StreamReader(path, System.Text.Encoding.Default))

    {

        rawText = parseHtml(sr.ReadToEnd());

    }

   

    doc.Add(Field.UnStored("text", rawText));

    doc.Add(Field.Keyword("path", path));

    writer.AddDocument(doc);

}


13 – 14 라인: 색인의 최적화와 저장


문서를 추가한 후에 indexer 닫아야 한다. 최적화는 검색 성능을 향상시킨다.

 

writer.Optimize();

writer.Close();


15 라인: 검색을 위한 색인 열기


어떠한 검색이라도 실행하기 전에 색인을 열어야 한다. directory 색인이 저장된 디렉토리 경로이다.

 

IndexSearcher searcher = new IndexSearcher(directory);


16 – 27 라인: 검색

 

이제 쿼리를 파싱 있다 (text 검색을 위한 기본 필드이다).

 

Query query =

   QueryParser.Parse(q, "text", new StandardAnalyzer());

Hits hits = searcher.Search(query);


변수 hits 결과 문서들의 집합이다. 검색은 이를 통해 이루어 지고, 결과는 DataTable 저장된다.

 

DataTable dt = new DataTable();

dt.Columns.Add("path", typeof(string));

dt.Columns.Add("sample", typeof(string));

 

for (int i = 0; i < hits.Length(); i++)

{

    // get the document from index

    Document doc = hits.Doc(i);

 

    // get the document filename

    // we can''t get the text from the index

    //because we didn''t store it there

    DataRow row = dt.NewRow();

    row["path"] = doc.Get("path");

 

    dt.Rows.Add(row);

}


Lines 28 - 37: 쿼리 강조

 

highlighter 생성하자. 강조에는 굵게(<B>phrase</B>) 사용한다..

 

QueryHighlightExtractor highlighter =

  new QueryHighlightExtractor(query, new StandardAnalyzer(),

                         "<B>", "</B>");


결과를 fetch하는 동안, 오리지널 텍스트의 적절한 부분을 로드한다.

 

for (int i = 0; i < hits.Length(); i++)

{

    // ...

    string plainText;

    using (StreamReader sr =

      new StreamReader(doc.Get("filename"),

                  System.Text.Encoding.Default))

    {

        plainText = parseHtml(sr.ReadToEnd());

    }

    row["sample"] =

       highlighter.GetBestFragments(plainText, 80, 2, "...");

    // ...

}


리소스들

 

 

출처 : http://www.codeproject.com/aspnet/DotLuceneSearch.asp

+ Recent posts