在開發SearchEasy Site SearchEngine(搜易站內搜索引擎)的時候,經常會遇到一些搜索引擎的常見功能如何實現的問題,比如實現相關度百分比顯示?如何實現在結果中搜索等等諸如此類常見的問題,本文總結我在開發SearchEasy Site SearchEngine(搜易站內搜索引擎)過程中遇到的問題,整理分享給需要的園友們:
問:Lucene.net的搜索結果的百分比相關度值是如何實現的?
答:
Hits result = searcher.Search(q);
float score = result.Score(n) ;//n為查詢結果文擋序號,返回的是一個<=1f的float的值,表示為百分比字符串:score.ToString("0%") ;
問:如何通過編程的方式改變Lucene.net的鎖文件存放的位置?
答:
Lucene.net的鎖文件默認是存放系統臨時文件夾,可以通過下面的語句來修改
System.Configuration.ConfigurationSettings.AppSettings.Add("Lucene.Net.lockDir", "your new lockDir") ;
通過FSDirectory.LOCK_DIR可以獲得鎖文件存放的位置(文件夾)
問:如何判斷某個索引庫被鎖定,如何強制解除鎖定?
答:
具體實現,可以參看Lucene.Net.Store.FSDirectory的Obtain()(判斷是否鎖定)方法和Release()方法(解除鎖定)
備注:還有一個IsLocked方法也可以參考下。
問:如何實現多個索引的聯合搜索 ?
答:
IndexSearcher[] searchers = new IndexSearcher[2];
searchers[0] = new IndexSearcher(dir1) ;
searchers[1] = new IndexSearcher(dir2) ;
MultiSearcher searcher = new MultiSearcher(searchers) ;//或ParallelMultiSearcher searcher = new ParallelMultiSearcher(searchers) ;
searcher.Search(query) ;
ParallelMultiSearcher與MultiSearcher的區別,前者為每一個索引單獨開一個線程,以多線程的方式同步搜索;后者是逐個依次搜索,然后合並;
所以ParallelMultiSearcher的搜索總用時是最慢的哪個索引的搜索用時,MultiSearcher則是搜索總用時等於所有索引搜索用時之和;
問:如何實現在結果中搜索 ?
答:
*方法一,使用CachingWrapperFilter。不能實現無限級的“在結果中搜索”:
QueryParser parser = new QueryParser("content", analyzer);
Query currentQuery = parser.Parse(currentKeyword) ;
Query oldQuery = parser.Parse(oldKeyword) ;
QueryFilter oldFilter = new QueryFilter(oldQuery) ;
CachingWrapperFilter filter = new CachingWrapperFilter(oldFilter) ;
IndexSearcher searcher = new IndexSearcher(indexDir);
Hits result = searcher.Search(currentQuery, filter) ;
*方法二,將多個查詢關鍵詞做AND的BooleanQuery或者直接構造查詢Sytax傳給QueryParser,都可以實現無限級的“在結果中搜索“。
問:BooleanQuery.maxClauseCount的含義 ?
答:
添加到BooleanQuery的最多的Query數,默認是1024。超過該值會拋出TooManyClauses異常,可以通過BooleanQuery.SetMaxClauseCount(int)設置新的值。
備注:含義解釋未明確。
問:如何判斷一個索引庫是否存在?
答:
string indexPath = "your indexPath" ; //索引所在目錄
if (System.IO.Directory.Exists(indexPath) && System.IO.File.Exists(Path.Combine(indexPath,"segments")
//存在
else
//不存在
當然有更直接的方法
if (Lucene.Net.Index.IndexReader.IndexExists(indexPath))
//存在
else
//不存在
Lucene.Net.Index.IndexReader.IndexExists方法內部的實現方式和上面的類似,當然直接用Lucene.Net.Index.IndexReader.IndexExists更可靠些。