前言:目前本身在作使用Lucene.net和PanGu分詞實現全文檢索的工做,不過本身是把別人作好的項目進行遷移。由於項目總體要遷移到ASP.NET Core 2.0版本,而Lucene使用的版本是3.6.0 ,PanGu分詞也是對應Lucene3.6.0版本的。不過好在Lucene.net 已經有了Core 2.0版本(4.8.0 bate版),而PanGu分詞,目前有人正在作,貌似已經作完,只是尚未測試~,Lucene升級的改變我都會加粗表示。html
Lucene.net 4.8.0 git
https://github.com/apache/lucenenetgithub
PanGu分詞(能夠直接使用的)apache
https://github.com/SilentCC/Lucene.Net.Analysis.PanGu緩存
JIEba分詞(能夠直接使用的)安全
https://github.com/SilentCC/JIEba-netcore2.0函數
Lucene.net 4.8.0 和以前的Lucene.net 3.6.0 改動仍是至關多的,這裏對本身開發過程遇到的問題,作一個記錄吧,但願能夠幫到和我同樣須要升級Lucene.net的人。我也是第一次接觸Lucene ,也但願能夠幫助初學Lucene的同窗。測試
IndexWriter 是用來建立和維護索引的。IndexWriter的建立:在Lucene4.8.0中,建立IndexWriter對象,須要用到IndexWriterConfig 參數,IndexWriterConfig用來設置一些IndexWriter的屬性:優化
IndexWriterConfig _indexWriterConfig = new IndexWriterConfig(Lucene.Net.Util.LuceneVersion.LUCENE_48,analyze) IndexWriter _indexWriter = new IndexWriter(dir,_indexWriterConfig)
上面的代碼建立了一個基本的IndexWriter對象,每一個基本IndexWriter都必須有兩個必要的屬性:1.操做的索引目錄 dir ;2. 分詞器 analyze .這裏要注意,IndexWriter的分詞器和IndexSearch的分詞器應該是相同的,不然將會影響搜索結果。spa
咱們經過IndexWriterConfig 能夠設置IndexWriter的屬性,已達到咱們但願構建索引的需求,這裏舉一些屬性,這些屬性能夠影響到IndexWriter寫入索引的速度:
IndexWriterConfig.setRAMBufferSizeMB(double); IndexWriterConfig.setMaxBufferedDocs(int); IndexWriterConfig.setMergePolicy(MergePolicy)
setRAMBufferSizeMB() 是設置,當IndexWriter添加的文檔的大小超過RAMBufferSizeMB ,IndexWriter就會把在內存中的操做,寫入到硬盤中。具體一點:IndexWriter在執行AddDocuments(寫入文檔),DeleteDocuments(刪除文檔),UpdateDocuments(更新文檔),這些操做的時候,這些操做都會先緩衝到內存中,也就是說執行完這些函數,其實儲存的索引目錄下是沒有任何改變的,當AddDocuments的容量超過上述的屬性的時候,這些操做纔會具體執行到儲存索引的硬盤當中。默認的DEFAULT_RAM_BUFFER_SIZE_MB 是16MB.
setMaxBufferedDocs() 是設置,當IndexWriter添加的文檔數量超過MaxBufferedDocs的時候,IndexWriter就會把內存中寫入的文檔,寫到硬盤中,並生成一個新的索引文件segment。關於Lucene的索引結構會在下面說到。
setMergePolicy 是設置索引合併的策略,MergePolicy中有一個參數DEFAULT_MAX_CFS_SEGMENT_SIZE 表示索引中最多有多少個segment文件。
上面提到了三個IndexWriterConfig的三個屬性。咱們知道,IndexWriter是當緩存中的容量達到必定的限制條件以後,纔開始將緩存中的操做寫入到硬盤中,事實上,若是咱們把限制條件定的值越大,索引的速度是越快的。顯而易見,若是設置RAMBufferSizeMB和MAXBufferedDocu越大,IndexWriter 寫入硬盤的次數就越少,而寫索引的時間耗費大多在對硬盤的操做之上。
IndexWriter寫入索引以後,在索引目錄裏會有不少segment文件。segment文件數量達到MergeFactor (設置合併因子)的時候,IndexWriter會將這些segment文件合併,造成一個新的segment文件,相似於壓縮。而在索引目錄中,若是segment文件越多,則搜索的速度會下降,segement文件越少,搜索的速度也就越快。因此當咱們設置MergeFactor的值越大的時候,搜索的速度就會越快,而合併segement的速度則會下降,也即索引的速度會下降。
這是,一個索引目錄下的索引文件。結構是這樣的:
上面的圖片中,只有一個段,_v6.fdt ;_v6.fdx ....... 都屬於_v6 segment中的內容。而segments_5u 和segments.gen 是段的元數據文件,也即它們保存了段的屬性信息。
上面的是正向信息,還有反向信息就不詳細說了。
在Lucene中IndexWriter.Optimize 用來優化索引,而在Lucene4.8.0中Optimize 已經改名爲ForceMerge,爲的是少讓你使用。IndexWriter的優化實際上就是把Segment文件進行合併,你能夠輸入參數,ForceMerge(segments) 表示,合併到索引目錄裏最多有segments個段文件。而當參數越小的時候,也即合併的文件越多的時候,消耗的時間和空間就越大。很顯然,合併是爲了讓咱們的搜索速度變的更快。
在優化的過程當中,須要當前索引容量兩倍的空間,好比你如今的索引大小是40個G,在優化過程當中,索引的大小會增長到80多個G,而後再合併直到最後只有30多個G。當你的索引更新不是特別頻繁的時候,能夠優化一下,若是更新特別頻繁,那麼調用ForceMerge就會效率很低,這個時候,咱們能夠設置上面提到過的MergeFactor來,讓索引中segments文件少一些。
1.IndexWriter在操做一個索引的時候會建立一個鎖定文件,Writer.lock 。若是有另外一個IndexWriter要打開這個目錄,將會報錯。
2.IndexWriter實例是徹底線程安全的,多個線程能夠同時調用它的任何方法.