lucene4.7 分页(五)
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
? 我們先來(lái)看下下面的問(wèn)題,現(xiàn)在我們的索引里有2億多的數(shù)據(jù),那么現(xiàn)在的需求是,把索引里的全部數(shù)據(jù),讀取然后寫入txt文本里,對(duì)于這么一個(gè)量級(jí)的數(shù)據(jù),顯然是不可能一下子全部讀取完的,那得要多大的內(nèi)存才能夠支持下來(lái),是一個(gè)很恐怖的內(nèi)存量,所以就引入散仙今天要給大家介紹的一個(gè)功能,Lucene的分頁(yè)技術(shù)。?
在介紹分頁(yè)之前,我們先來(lái)看看上面的那個(gè)需求,不用分頁(yè)的解決辦法,?
其實(shí)在lucene里面,每一個(gè)索引都會(huì)對(duì)應(yīng)一個(gè)不重復(fù)的docid,而這一點(diǎn)跟Oralce數(shù)據(jù)庫(kù)的偽列rownum一樣,恰恰正是由于這個(gè)docid的存在,所以讓lucene在海量數(shù)據(jù)檢索時(shí)從而擁有更好的性能,我們都知道Oracle數(shù)據(jù)庫(kù)在分頁(yè)時(shí),使用的就是偽列進(jìn)行分頁(yè),那么我的lucene也是一樣,既然有一個(gè)docid的存在,那么上面的需求就很簡(jiǎn)單了。?
方法一:依次根據(jù)每個(gè)docid獲取文檔然后寫入txt中,這樣的以來(lái),就避免了內(nèi)存不足的缺點(diǎn),但是這樣單條讀取的話,速度上可能會(huì)慢一點(diǎn),但能滿足需求無(wú)可厚非。偽代碼如下
Lucene的分頁(yè),總的來(lái)說(shuō)有兩種形式,總結(jié)如下圖表格。(如果存在不合適之處,歡迎指正!)
| 編號(hào) | 方式 | 優(yōu)點(diǎn) | 缺點(diǎn) |
| 1 | 在ScoresDocs里進(jìn)行分頁(yè) | 無(wú)需再次查詢索引,速度很快 | 在海量數(shù)據(jù)時(shí),會(huì)內(nèi)存溢出 |
| 2 | 利用SearchAfter,再次查詢分頁(yè) | 適合大批量數(shù)據(jù)的分頁(yè) | 再次查詢,速度相對(duì)慢一點(diǎn),但可以利用緩存彌補(bǔ) |
在我們了解這2中分頁(yè)技術(shù)的優(yōu)缺點(diǎn)之后,我們?cè)賮?lái)探討下上面那個(gè)讀2億數(shù)據(jù)存入txt文本里,在這里,SocreDocs不適合這種場(chǎng)景,當(dāng)然如果你內(nèi)存足夠大的話,可以嘗試下,通用分頁(yè)分批讀取的方式,可以提升我們的寫入效率,效果是比單條單條讀取的速度是要快很多的。雖然ScoresDocs的分頁(yè)方式在本需求上不適合,但是作為示例,下面散仙給出使用ScoreDocs進(jìn)行分頁(yè)的代碼:
????try{directory=FSDirectory.open(new?File(indexReadPath));//打開索引文件夾IndexReader??reader=DirectoryReader.open(directory);//讀取目錄IndexSearcher?search=new?IndexSearcher(reader);//初始化查詢組件TopDocs?all=search.search(new?MatchAllDocsQuery(),?50000);int?offset=0;//起始位置int?pageSize=30;//分頁(yè)的條數(shù)int?total=30;//結(jié)束條數(shù)int?z=0;while(z<=50){//總分頁(yè)數(shù)System.out.println("==============================");pageScoreDocs(offset,total,search,?all.scoreDocs);//調(diào)用分頁(yè)打印offset=(z*pageSize+pageSize);//下一頁(yè)的位置增量z++;//分頁(yè)數(shù)+1;total=offset+pageSize;//下一次的結(jié)束分頁(yè)量}reader.close();//關(guān)閉資源directory.close();//關(guān)閉連接}catch(Exception?e){e.printStackTrace();} public?void?pageScoreDocs(int?offset,int?total,IndexSearcher?searcher,ScoreDoc[]?doc)?throws?Exception{//System.out.println("offset:"+offset+"===>"+total);for(int?i=offset;i<total;i++){//System.out.println("i"+i+"==>"+doc.length);if(i>doc.length-1){//當(dāng)分頁(yè)的長(zhǎng)度數(shù)大于總數(shù)就停止break;}else{Document?dosc=searcher.doc(doc[i].doc);System.out.println(dosc.get("name"));}}
最后我們來(lái)看下使用SearcherAfter進(jìn)行分頁(yè)的方式,代碼如下:
至此,我們已經(jīng)了解了lucene中的分頁(yè)技術(shù),至于,我們?cè)陧?xiàng)目中該如何使用,都要根據(jù)我們的實(shí)際情況處理,因?yàn)榉猪?yè)技術(shù)常常會(huì)跟其他的,排序,過(guò)濾,評(píng)分等一些技術(shù)結(jié)合使用。
轉(zhuǎn)載于:https://my.oschina.net/MrMichael/blog/220782
總結(jié)
以上是生活随笔為你收集整理的lucene4.7 分页(五)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Android之jdbc的学习
- 下一篇: xcode 5 使用 XCTest 做单