Lucene.NET 을 사용 하여 사이트 내 검색 실현
10661 단어 Lucene.NET역 내 검색
Lucene 은 apache 소프트웨어 재단 의 오픈 소스 코드 의 전체 텍스트 검색엔진 도구 패키지 로 전체 텍스트 검색엔진 의 구조 로 완전한 검색 엔진 과 색인 엔진,일부 텍스트 분석 엔진 을 제공 합 니 다.Lucene 의 목적 은 소프트웨어 개발 자 에 게 간단 하고 사용 하기 쉬 운 도 구 를 제공 하여 목표 시스템 에서 전문 검색 기능 을 편리 하 게 실현 하거나 이 를 바탕 으로 완전한 전문 검색엔진 을 구축 하 는 것 이다.Lucene.Net 은.NET 버 전의 Lucene 이다.
여기 서 최신 Lucene.NET 까지다운로드 하 다.
색인 생 성,색인 업데이트,색인 삭제
검색
색인 추가,업데이트,삭제
using System;
using Lucene.Net.Store;
using Lucene.Net.Index;
using Lucene.Net.Analysis.PanGu;
using Lucene.Net.Documents;
namespace BLL
{
class IndexHelper
{
/// <summary>
///
/// </summary>
static Common.LogHelper logger = new Common.LogHelper(typeof(SearchBLL));
/// <summary>
/// ,
/// </summary>
static string indexPath = Common.ConfigurationHelper.AppSettingMapPath("IndexPath");
/// <summary>
///
/// </summary>
/// <param name="item"> </param>
public static void CreateIndex(Model.HelperModel.IndexFileHelper item)
{
try
{
//
FSDirectory directory = FSDirectory.Open(new System.IO.DirectoryInfo(indexPath), new NativeFSLockFactory());
//
bool isUpdate = IndexReader.IndexExists(directory);
if (isUpdate)
{
// ( ),
if (IndexWriter.IsLocked(directory))
{
//
IndexWriter.Unlock(directory);
}
}
// IndexWriter ,
IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED);
// title
string title = item.FileTitle;
//
string body = item.FileContent;
// , number=i ,
// ,
writer.DeleteDocuments(new Term("id", item.FileName));
// Document
Document document = new Document();
// ANALYZED
// id
document.Add(new Field("id", item.FileName, Field.Store.YES, Field.Index.NOT_ANALYZED));
// title
document.Add(new Field("title", title, Field.Store.YES, Field.Index.NOT_ANALYZED));
// body
document.Add(new Field("body", body, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS));
// url
document.Add(new Field("url", item.FilePath, Field.Store.YES, Field.Index.NOT_ANALYZED));
//
writer.AddDocument(document);
//
writer.Close();
// Close,
directory.Close();
//
logger.Debug(String.Format(" {0} ",item.FileName));
}
catch (SystemException ex)
{
//
logger.Error(ex);
throw;
}
catch (Exception ex)
{
//
logger.Error(ex);
throw;
}
}
/// <summary>
/// id
/// </summary>
/// <param name="guid"> id</param>
public static void DeleteIndex(string guid)
{
try
{
////
FSDirectory directory = FSDirectory.Open(new System.IO.DirectoryInfo(indexPath), new NativeFSLockFactory());
//
bool isUpdate = IndexReader.IndexExists(directory);
if (isUpdate)
{
// ( ),
if (IndexWriter.IsLocked(directory))
{
IndexWriter.Unlock(directory);
}
}
IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED);
//
writer.DeleteDocuments(new Term("id", guid));
writer.Close();
directory.Close();// Close,
logger.Debug(String.Format(" {0} ", guid));
}
catch (Exception ex)
{
//
logger.Error(ex);
//
throw;
}
}
}
}
검색
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.PanGu;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Model.HelperModel;
using System;
using System.Collections.Generic;
namespace BLL
{
public static class SearchBLL
{
// , , logger static
/// <summary>
///
/// </summary>
static Common.LogHelper logger = new Common.LogHelper(typeof(SearchBLL));
/// <summary>
///
/// </summary>
static string indexPath = Common.ConfigurationHelper.AppSettingMapPath("IndexPath");
/// <summary>
///
/// </summary>
/// <param name="keywords"> </param>
/// <returns> </returns>
public static List<SearchResult> Search(string keywords)
{
try
{
//
FSDirectory directory = FSDirectory.Open(new System.IO.DirectoryInfo(indexPath), new NoLockFactory());
// IndexReader
IndexReader reader = IndexReader.Open(directory, true);
// IndexSearcher
IndexSearcher searcher = new IndexSearcher(reader);
// PhraseQuery
PhraseQuery query = new PhraseQuery();
//
foreach (string word in SplitWord(keywords))
{
//
query.Add(new Term("body", word));
}
// 100
query.SetSlop(100);
TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true);
//
searcher.Search(query, null, collector);
// ScoreDoc
ScoreDoc[] docs = collector.TopDocs(0, collector.GetTotalHits()).scoreDocs;
// list
List<SearchResult> listResult = new List<SearchResult>();
for (int i = 0; i < docs.Length; i++)
{
// ( , Lucene .net )
// id, Document, Doc
//
int docId = docs[i].doc;
// id Document
Document doc = searcher.Doc(docId);
string number = doc.Get("id");
string title = doc.Get("title");
string body = doc.Get("body");
string url = doc.Get("url");
//
SearchResult result = new SearchResult();
result.Number = number;
result.Title = title;
result.BodyPreview = Preview(body, keywords);
result.Url = url;
//
listResult.Add(result);
}
if (listResult.Count == 0)
{
return null;
}
else
{
return listResult;
}
}
catch (SystemException ex)
{
logger.Error(ex);
return null;
}
catch (Exception ex)
{
logger.Error(ex);
return null;
}
}
/// <summary>
///
/// </summary>
/// <param name="body"> </param>
/// <param name="keyword"> </param>
/// <returns></returns>
private static string Preview(string body, string keyword)
{
// HTMLFormatter,
PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("<font color=\"red\">", "</font>");
// Highlighter , HTMLFormatter Semgent
PanGu.HighLight.Highlighter highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new PanGu.Segment());
//
highlighter.FragmentSize = 100;
//
string bodyPreview = highlighter.GetBestFragment(keyword, body);
return bodyPreview;
}
/// <summary>
/// ,
/// </summary>
/// <param name="str"> </param>
/// <returns> </returns>
private static string[] SplitWord(string str)
{
List<string> list = new List<string>();
Analyzer analyzer = new PanGuAnalyzer();
TokenStream tokenStream = analyzer.TokenStream("", new System.IO.StringReader(str));
Lucene.Net.Analysis.Token token = null;
while ((token = tokenStream.Next()) != null)
{
list.Add(token.TermText());
}
return list.ToArray();
}
}
}
SearchResult 모델
namespace Model.HelperModel
{
public class SearchResult
{
public string Number { get; set; }
public string Title { get; set; }
public string BodyPreview { get; set; }
public string Url { get; set; }
}
}
이상 에서 말 한 것 이 바로 본문의 전체 내용 이 니 여러분 들 이 좋아 하 시 기 를 바 랍 니 다.