Asp.net MVC4系统的全文检索功能使用的是Lucene.Net组件。Lucene.Net是一个信息检索的函数库(Library),利用它你可以为你的应用加上索引和搜索的功能.你也可以把它理解为一个将索引,搜索功能封装的很好的一套简单易用的API.利用这套API你可以做很多有关搜索的事情,而且很方便.
Lucene.net多条件查询搜索
1.利用 MultiFieldQueryParser
DateTime startTime = DateTime.Now;
//检索
BooleanQuery currentQuery = new BooleanQuery();
Query postKeywordQuery = null;
if (!string.IsNullOrEmpty(query.KeyWord))
{
query.KeyWord = StringUtilsForLucene.LuceneKeywordsScrubber(query.KeyWord);
string[] searchFieldsForKeyword = new string[] { PushMessagesIndexDocument.MsgTitle, PushMessagesIndexDocument.MsgContent };
//多字段多域搜索
MultiFieldQueryParser keywordParser = new MultiFieldQueryParser(searchFieldsForKeyword, GetChineseAnalyzerOfUnTokenized());
keywordParser.SetLowercaseExpandedTerms(true);
keywordParser.SetDefaultOperator(QueryParser.OR_OPERATOR);
string keyWordsOfSplit = SplitKeywordsBySpace(query.KeyWord);
postKeywordQuery = keywordParser.Parse(keyWordsOfSplit);
currentQuery.Add(postKeywordQuery, BooleanClause.Occur.MUST);
}
//排序
IndexSearcher searcher = new IndexSearcher(this.PhysicalIndexDirectory);
Hits hits;
if (query.SortBy != PushMessagesFullTextQuerySortBy.Relevance)
{
Sort sort = new Sort(PushMessagesIndexDocument.SendTime, true);
if (query.SortBy == PushMessagesFullTextQuerySortBy.SendTime)
sort = new Sort(PushMessagesIndexDocument.SendTime, true);
hits = searcher.Search(currentQuery, sort);
}
else
hits = searcher.Search(currentQuery);
SearchResultDataSet<PushMessages> pds = new SearchResultDataSet<PushMessages>();
int pageLowerBound = (query.PageIndex - 1) * query.PageSize;
int pageUpperBound = pageLowerBound + query.PageSize;
if (pageUpperBound > hits.Length())
pageUpperBound = hits.Length();
KTDictSeg.HighLight.Highlighter highlighter = null;
if (!string.IsNullOrEmpty(query.KeyWord))
{
highlighter = new KTDictSeg.HighLight.Highlighter(new KTDictSeg.HighLight.SimpleHTMLFormatter("<font color=\"#c60a00\">", "</font>"), new Lucene.Net.Analysis.KTDictSeg.KTDictSegTokenizer());
highlighter.FragmentSize = 100;
}
for (int i = pageLowerBound; i < pageUpperBound; i++)
{
PushMessages item = ConvertDocumentToEntity(hits.Doc(i));
#region 搜索结果高亮显示
if (!string.IsNullOrEmpty(query.KeyWord))
{
string bestName = null;
if (!string.IsNullOrEmpty(item.MsgTitle) && item.MsgTitle.Length > MaxNumFragmentsRequired)
bestName = highlighter.GetBestFragment(query.KeyWord, item.MsgTitle);
if (!string.IsNullOrEmpty(bestName))
item.MsgTitle = bestName;
else
item.MsgTitle = HtmlUtils.TrimHtml(item.MsgTitle, 100);
string bestDesc = null;
if (!string.IsNullOrEmpty(item.MsgContent) && item.MsgContent.Length > MaxNumFragmentsRequired)
bestDesc = highlighter.GetBestFragment(query.KeyWord, item.MsgContent);
if (!string.IsNullOrEmpty(bestDesc))
item.MsgContent = bestDesc;
}
#endregion
pds.Records.Add(item);
}
searcher.Close();
pds.TotalRecords = hits.Length();
DateTime endTime = DateTime.Now;
pds.SearchDuration = (endTime.Ticks - startTime.Ticks) / 1E7f;
pds.PageIndex = query.PageIndex;
pds.PageSize = query.PageSize;
经过搜索测试,两者的结果是一样的,但是有个疑问的是,MultiFieldQueryParser.parse方法,传入的查询关键词数组,字段数组,occur数组,长度要一致,这个经过测试了几次,确实是这样子,可以查一个词,但是字段和occur要长度一致,大概是要进行一一匹配起来,这个可以做多个测试进行猜想,MultiFieldQueryParser应该是封装了BooleanQuery,使其代码更简洁,更容易操作。