標籤:ack max logs thread 需要 oid unlock arch 通過
1 public sealed class SearchIndexManager 2 { 3 private static readonly SearchIndexManager searchManager=new SearchIndexManager(); 4 private SearchIndexManager() 5 { 6 7 } 8 public static SearchIndexManager GetSingleSearchManager() 9 {10 return searchManager;11 }12 private Queue<SearchContent> indexQueue = new Queue<SearchContent>();13 /// <summary>14 /// 添加索引15 /// </summary>16 public void AddIndex(SearchContent indexContent)17 {18 indexContent .IndexType =CreateIndexEnum .Add;19 indexQueue.Enqueue(indexContent);20 }21 /// <summary>22 /// 刪除索引23 /// </summary>24 /// <param name="indexContent"></param>25 public void DeleteIndex(SearchContent indexContent)26 {27 indexContent .IndexType =CreateIndexEnum .Delete;28 indexQueue .Enqueue (indexContent);29 }30 //沒輸入一條資料就添加相應的索引,為瞭解決鎖的問題,使用隊列的方式,向隊列中添加資料,接下來就是從隊列中取出資料,添加到lucen的索引庫中31 public void StartIndexThread()32 {33 Thread thread = new Thread(new ThreadStart(CreateIndex));34 thread.IsBackground = true;35 thread.Start();36 }37 public void CreateIndex()38 {39 while (true)40 {41 if (indexQueue.Count > 0)42 {43 //建立索引44 //將建立的分詞內容放在該目錄下45 string indexPath = @"D:\LuceneDir";46 //為Lucent.net指定索引檔案(開啟索引目錄) FS指的是就是FileSystem47 FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NativeFSLockFactory());48 //IndexReader:對索引進行讀取的類。該語句的作用:判斷索引庫檔案夾是否存在以及索引特徵檔案是否存在。49 bool isUpdate = IndexReader.IndexExists(directory);50 if (isUpdate)51 {52 //同時只能有一段代碼對索引庫進行寫操作。當使用IndexWriter開啟directory時會自動對索引庫檔案上鎖。53 //如果索引目錄被鎖定(比如索引過程中程式異常退出),則首先解鎖(提示一下:如果我現在正在寫著已經加鎖了,但是還沒有寫完,這時候又來一個請求,那麼不就解鎖了嗎?這個問題後面會解決)54 if (IndexWriter.IsLocked(directory))55 {56 IndexWriter.Unlock(directory);57 }58 }59 //向索引庫中寫索引。這時在這裡加鎖。同時指定分詞演算法是Apsara Distributed File System分詞60 //通過writer會將索引寫到我們制定的檔案夾目錄下61 IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED);62 63 //從隊列中取出資料64 SearchContent search= indexQueue.Dequeue();65 //我們需要添加到Lucene.net索引庫的檔案66 Document document = new Document();//表示一篇文檔。67 //Field.Store.YES:表示是否儲存原值。只有當Field.Store.YES在後面才能用doc.Get("number")取出值來.Field.Index. NOT_ANALYZED:不進行分詞儲存68 //因為不會進行覆蓋,所以需要將以前的打上刪除標誌,否則將會出現多個重複的69 writer.DeleteDocuments(new Term("id", search.ID.ToString()));70 71 if (search.IndexType == CreateIndexEnum.Delete)72 {73 continue;74 }75 document.Add(new Field("id", search.ID.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));76 77 //Field.Index. ANALYZED:進行分詞儲存:也就是要進行全文的欄位要設定分詞 儲存(因為要進行模糊查詢)78 79 //Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS:不僅儲存分詞還儲存分詞的距離。80 81 document.Add(new Field("title", search.Title, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS));82 document.Add(new Field("content", search.Content , Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS));83 writer.AddDocument(document);84 85 writer.Close();//會自動解鎖。86 directory.Close();//不要忘了Close,否則索引結果搜不到87 }88 else89 {90 Thread.Sleep(5000);91 }92 }93 }
Lucene.net之解決鎖的問題