<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Rising Sun

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      148 隨筆 :: 0 文章 :: 22 評(píng)論 :: 0 Trackbacks

    2014年9月2日 #

         摘要: 看了網(wǎng)上的許多對(duì)于lucene 分詞解析的文章一知半解且代碼比較老舊,為透徹、系統(tǒng)、全面、深刻的了解分詞是怎么一個(gè)過(guò)程,通過(guò)自定義一個(gè)分詞器來(lái)分析理解。 其中分詞部分利用ICTCLAS4j接口實(shí)現(xiàn)。結(jié)構(gòu)如下所示:            要實(shí)現(xiàn)自定義的ICTCLAS4jAnalyzer必須繼承Analy...  閱讀全文
    posted @ 2015-01-07 10:11 brock 閱讀(1098) | 評(píng)論 (0)編輯 收藏

    Lucene Directory類(lèi)就像它的意思一樣“目錄”,如“目錄”不存在,第一次啟動(dòng)被創(chuàng)建,一旦文件被創(chuàng)建,它只能打開(kāi)閱讀,或刪除。允許讀取和寫(xiě)入隨機(jī)訪(fǎng)問(wèn)。Java I/O api 不能直接使用,只能通過(guò)這個(gè)API Directory的實(shí)現(xiàn)類(lèi)可以分為文件目錄,內(nèi)存目錄和目錄的代理類(lèi)及工具類(lèi)。具體如下圖所示:


    一:文件目錄

    SimpleFSDirectory:FSDirectory的簡(jiǎn)單實(shí)現(xiàn),并發(fā)能力有限,遇到多線(xiàn)程讀同一個(gè)文件時(shí)會(huì)遇到瓶頸,通常用NIOFSDirectoryMMapDirectory代替。

    NIOFSDirectory:通過(guò)java.nio's FileChannel實(shí)行定位讀取,支持多線(xiàn)程讀(默認(rèn)情況下是線(xiàn)程安全的)。該類(lèi)僅使用FileChannel進(jìn)行讀操作,寫(xiě)操作則是通過(guò)FSIndexOutput實(shí)現(xiàn)。

    注意:NIOFSDirectory 不適用于Windows系統(tǒng),另外如果一個(gè)訪(fǎng)問(wèn)該類(lèi)的線(xiàn)程,在IO阻塞時(shí)被interruptcancel,將會(huì)導(dǎo)致底層的文件描述符被關(guān)閉,后續(xù)的線(xiàn)程再次訪(fǎng)問(wèn)NIOFSDirectory時(shí)將會(huì)出現(xiàn)ClosedChannelException異常,此種情況應(yīng)用SimpleFSDirectory代替。

    MMapDirectory:通過(guò)內(nèi)存映射進(jìn)行讀,通過(guò)FSIndexOutput進(jìn)行寫(xiě)的FSDirectory實(shí)現(xiàn)類(lèi)。使用該類(lèi)時(shí)要保證用足夠的虛擬地址空間。另外當(dāng)通過(guò)IndexInputclose方法進(jìn)行關(guān)閉時(shí)并不會(huì)立即關(guān)閉底層的文件句柄,只有GC進(jìn)行資源回收時(shí)才會(huì)關(guān)閉。

     

    為了能適應(yīng)各個(gè)操作系統(tǒng)選擇最佳Directory方案,lucene 提供FSDirectory類(lèi)的靜態(tài)方法open()實(shí)現(xiàn)自適應(yīng)。

     public static FSDirectory open(File path, LockFactory lockFactory) throws IOException {

        if ((Constants.WINDOWS || Constants.SUN_OS || Constants.LINUX)

              && Constants.JRE_IS_64BIT && MMapDirectory.UNMAP_SUPPORTED) {

          return new MMapDirectory(path, lockFactory);

        } else if (Constants.WINDOWS) {

          return new SimpleFSDirectory(path, lockFactory);

        } else {

          return new NIOFSDirectory(path, lockFactory);

        }

      }

    二:內(nèi)存目錄

    RAMDirectory:常駐內(nèi)存的Directory實(shí)現(xiàn)方式。默認(rèn)通過(guò)SingleInstanceLockFactory(單實(shí)例鎖工廠)進(jìn)行鎖的實(shí)現(xiàn)。該類(lèi)不適合大量索引的情況另外也不適用于多線(xiàn)程的情況。 在索引數(shù)據(jù)量大的情況下建議使用MMapDirectory代替。RAMDirectoryDirectory抽象類(lèi)在使用內(nèi)存最為文件存儲(chǔ)的實(shí)現(xiàn)類(lèi),其主要是將所有的索引文件保存到內(nèi)存中。這樣可以提高效率。但是如果索引文件過(guò)大的話(huà),則會(huì)導(dǎo)致內(nèi)存不足,因此,小型的系統(tǒng)推薦使用,如果大型的,索引文件達(dá)到G級(jí)別上,推薦使用FSDirectory。

    NRTCachingDirectory:是對(duì)RAMDirectory的封裝,適用于近乎時(shí)時(shí)(near-real-time)操作的環(huán)境。

    三:Direcotry的代理類(lèi)及工具類(lèi)

    FileSwitchDirectory:文件切換的Directory實(shí)現(xiàn).針對(duì)lucene的不同的索引文件使用不同的Directory .借助FileSwitchDirectory整合不同的Directory實(shí)現(xiàn)類(lèi)的優(yōu)點(diǎn)于一身
    比如MMapDirectory,借助內(nèi)存映射文件方式提高性能,但又要減少內(nèi)存切換的可能 ,當(dāng)索引太大的時(shí)候,內(nèi)存映射也需要不斷地切換,這樣優(yōu)點(diǎn)也可能變?nèi)秉c(diǎn),而之前的NIOFSDirectory實(shí)現(xiàn)java NIO的方式提高高并發(fā)性能,但又因高并發(fā)也會(huì)導(dǎo)致IO過(guò)多的影響,所以這次可以借助FileSwitchDirectory發(fā)揮他們兩的優(yōu)點(diǎn)。

    RateLimitedDirectoryWrapper:通過(guò)IOContext來(lái)限制讀寫(xiě)速率的Directory封裝類(lèi)。

    CompoundFileDirectory:用于訪(fǎng)問(wèn)一個(gè)組合的數(shù)據(jù)流。僅適用于讀操作。對(duì)于同一段內(nèi)擴(kuò)展名不同但文件名相同的所有文件合并到一個(gè)統(tǒng)一的.cfs文件和一個(gè)對(duì)應(yīng)的.cfe文件內(nèi)。
    .cfs文件由Header,FileDataFileCount組成。.cfe文件由Header,FileCount,FileName,DataOffset,DataLength組成。.cfs文件中存儲(chǔ)著索引的概要信息及組合文件
    的數(shù)目(FileCount)。.cfe文件存儲(chǔ)文件目錄的條目?jī)?nèi)容,內(nèi)容中包括文件數(shù)據(jù)扇區(qū)的起始位置,文件的長(zhǎng)度及文件的名稱(chēng)。

    TrackingDirectoryWrapperDirectory的代理類(lèi)。用于記錄哪些文件被寫(xiě)入和刪除。

    四:Direcotry讀寫(xiě)對(duì)象的類(lèi)圖




     文章轉(zhuǎn)載過(guò)來(lái)的!

    posted @ 2015-01-07 10:09 brock 閱讀(273) | 評(píng)論 (0)編輯 收藏

        本機(jī)已經(jīng)安裝了jdk1.6,而比較早期的項(xiàng)目需要依賴(lài)jdk1.5,于是同時(shí)在本機(jī)安裝了jdk1.5和jdk1.6. 

     安裝jdk1.5前,執(zhí)行java -version得到

    java version "1.6.0_38"
    Java(TM) SE Runtime Environment (build 1.6.0_38-b05)
    Java HotSpot(TM) 64-Bit Server VM (build 20.13-b02, mixed mode)


    安裝完jdk1.5,并修改環(huán)境變量JAVA_HOME為D:\devSoftware\jdk1.5.再執(zhí)行 java -version時(shí),依然顯示:

    java version "1.6.0_38"
    Java(TM) SE Runtime Environment (build 1.6.0_38-b05)
    Java HotSpot(TM) 64-Bit Server VM (build 20.13-b02, mixed mode)


    看上去,新的環(huán)境變量JAVA_HOME=D:\devSoftware\jdk1.5并沒(méi)有生效。 在網(wǎng)上找了很多資料才發(fā)現(xiàn):

          在安裝JDK1.6時(shí)(本機(jī)先安裝jdk1.6再安裝的jdk1.5),自動(dòng)將java.exe、javaw.exe、javaws.exe三個(gè)可執(zhí)行文件復(fù)制到了C:\Windows\System32目錄,由于這個(gè)目錄在WINDOWS環(huán)境變量中的優(yōu)先級(jí)高于JAVA_HOME設(shè)置的環(huán)境變量?jī)?yōu)先級(jí)


    解決方案:將java.exe,javaw.exe,javaws.exe刪除即可。開(kāi)啟新的命令行窗口,再執(zhí)行java -version時(shí),就得到了期望中的結(jié)果

    java version "1.5.0_17"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_17-b04)
    Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_17-b04, mixed mode)


    posted @ 2015-01-06 11:45 brock 閱讀(7029) | 評(píng)論 (0)編輯 收藏

    在學(xué)lucene 之初看了許多書(shū),都是走馬觀花,沒(méi)有項(xiàng)目的驅(qū)動(dòng)下,來(lái)一個(gè)用例demo感覺(jué)也不是很難,“我會(huì)了”這是我的第一感覺(jué)。

             2013年底公司接到一個(gè)項(xiàng)目用到lucene,這是我第一次正真接觸Lucene,代碼比較老3.6版本,不適合新項(xiàng)目的需求(空間查詢(xún))。于是下載了最新版本 4.51,有帶“空間查詢(xún)”模塊。各大搜索引擎都沒(méi)有找到像樣例子,于是想到了lucene svn trunk目錄測(cè)試用例中找到了測(cè)試?yán)?,開(kāi)始了一段lucene之旅。

     

    寫(xiě)數(shù)據(jù),創(chuàng)建IndexWriter,通過(guò)它的構(gòu)造函數(shù)需要一個(gè)索引目錄(Diectory)和索引寫(xiě)入配置項(xiàng)(InderWriterConfig,直接上代碼:

    //設(shè)置寫(xiě)入目錄(好幾種呵呵)

    Directory d=FSDirectory.open(new File("D:/luceneTest"));

    //設(shè)置分詞 StandardAnalyzer(會(huì)把句子中的字單個(gè)分詞)

    Analyzer analyzer= new StandardAnalyzer(Version.LUCENE_45);

    //設(shè)置索引寫(xiě)入配置

    IndexWriterConfig config=new IndexWriterConfig(Version.LUCENE_45,analyzer);

    //設(shè)置創(chuàng)建模式

    //config.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);

    IndexWriter indexwriter= new IndexWriter(d,config);

     

        上面四行代碼就創(chuàng)建好了indexwriter,下面把數(shù)據(jù)填入就好了,寫(xiě)入有多種方式如下圖:


             addDocment 舉例代碼如下:

    Document doc=new Document(); 

            doc.add(new StringField("id", "1", Store.YES));

            doc.add(new StringField("name", "brockhong", Store.YES));

            doc.add(new TextField("content", "lucene 文檔第一次寫(xiě)看著給分吧", Store.YES)); 

    //寫(xiě)入數(shù)據(jù)

    indexwriter.addDocument(doc);

    //提交

    indexwriter.commit();

    Luke 工具查看Text列,這是標(biāo)準(zhǔn)分詞惹的禍哦!寫(xiě)入成功。


             讀數(shù)據(jù)查詢(xún),創(chuàng)建 IndexSearcher 構(gòu)造函數(shù)設(shè)置indexReader ,輸入查詢(xún)條件,上面content字段數(shù)據(jù)設(shè)置了分詞,所以必須通過(guò)查詢(xún)解析類(lèi)QueryParser設(shè)定分詞字段、版本、分詞模式,并通過(guò)parse方法得到查詢(xún)條件。代碼如下:       

     //讀數(shù)據(jù)

     //創(chuàng)建 indexReader 這個(gè)已過(guò)時(shí) IndexReader.open(d),里面的代碼一樣可能為了兼容老版本

     IndexReader indexReader = DirectoryReader.open(d);

     IndexSearcher indexSearcher = new IndexSearcher(indexReader);

    //查詢(xún) 設(shè)置分詞字段

    QueryParser queryParser = new QueryParser(Version.LUCENE_45, "content",

                       new StandardAnalyzer(Version.LUCENE_45));

     //or 關(guān)系 “給”、“分”

             queryParser.setDefaultOperator(QueryParser.OR_OPERATOR);

    Query query = queryParser.parse("給分");

     

    TopDocs results = indexSearcher.search(query, 100);

    int numTotalHits = results.totalHits;

    System.out.println(" " + numTotalHits + " 完全匹配的文檔");

    ScoreDoc[] hits = results.scoreDocs;

    for (int i = 0; i < hits.length; i++) {

                  Document document = indexSearcher.doc(hits[i].doc);

                  System.out.println("content:" + document.get("content"));

    }


    pasting
    posted @ 2014-12-31 17:07 brock 閱讀(332) | 評(píng)論 (0)編輯 收藏

    http://blog.csdn.net/ablipan/article/details/8198692

    使用SAXReader的read(File file)方法時(shí),如果xml文件異常會(huì)導(dǎo)致文件被服務(wù)器占用不能移動(dòng)文件,建議不使用read(File file)方法而使用read(FileInputStream fis)等流的方式讀取文件,異常時(shí)關(guān)閉流,這樣就不會(huì)造成流未關(guān)閉,文件被鎖的現(xiàn)象了。(在服務(wù)器中運(yùn)行時(shí)會(huì)鎖住文件,main方法卻不會(huì))。


    1、以下方式xml文件異常時(shí)會(huì)導(dǎo)致文件被鎖

    1.                    Document document = null;  
    2. File file = new File(xmlFilePath);  
    3. SAXReader saxReader = new SAXReader();  
    4. try  
    5. {  
    6.     document = saxReader.read(file);  
    7. } catch (DocumentException e)  
    8. {  
    9.     logger.error("將文件[" + xmlFilePath + "]轉(zhuǎn)換成Document異常", e);  
    10. }  


    2、以下方式xml文件異常時(shí)不會(huì)鎖文件(也可以使用其他的流來(lái)讀文件)

    1.                 Document document = null;  
    2. FileInputStream fis = null;  
    3. try  
    4. {  
    5.     fis = new FileInputStream(xmlFilePath);  
    6.     SAXReader reader = new SAXReader();  
    7.     document = reader.read(fis);  
    8. }   
    9. catch (Exception e)  
    10. {  
    11.     logger.error("將文件[" + xmlFilePath + "]轉(zhuǎn)換成Document異常", e);  
    12. }   
    13. finally  
    14. {  
    15.     if(fis != null)  
    16.     {  
    17.         try  
    18.         {  
    19.             fis.close();  
    20.         } catch (IOException e)  
    21.         {  
    22.             logger.error("將文件[" + xmlFilePath + "]轉(zhuǎn)換成Document,輸入流關(guān)閉異常", e);  
    23.         }  
    24.     }  
    25. }  
    posted @ 2014-09-02 14:00 brock 閱讀(485) | 評(píng)論 (0)編輯 收藏

    主站蜘蛛池模板: 国产免费黄色大片| 最近中文字幕大全中文字幕免费 | 91亚洲国产成人精品下载| 国产一级a毛一级a看免费视频| 国产亚洲精久久久久久无码AV| 成人国产网站v片免费观看| 亚洲国产精品13p| eeuss草民免费| 亚洲AV无码成人网站久久精品大 | 亚洲日本久久久午夜精品| 无码人妻精品中文字幕免费东京热| 在线电影你懂的亚洲| 又粗又大又黑又长的免费视频| 亚洲视频在线不卡| 免费观看一级毛片| 国产精品极品美女自在线观看免费 | 久久亚洲AV午夜福利精品一区| 免费观看男人吊女人视频| 亚洲高清无在码在线无弹窗| 希望影院高清免费观看视频| 亚洲欧美aⅴ在线资源| 亚洲成人高清在线| 国内精品一级毛片免费看| 亚洲成a人片在线观看中文!!!| 夜夜爽免费888视频| 草久免费在线观看网站| 久久亚洲精品中文字幕| 女人张开腿等男人桶免费视频| 无码免费又爽又高潮喷水的视频 | 100部毛片免费全部播放完整| 亚洲综合一区国产精品| 亚洲国产精品自在拍在线播放| 在线人成免费视频69国产| 亚洲一区二区三区91| 午夜亚洲国产成人不卡在线| 国内永久免费crm系统z在线| 亚洲大片免费观看| 亚洲AV无码一区二区三区国产| 日韩精品无码专区免费播放| 亚洲精品无码久久久久APP| 亚洲人成人无码网www电影首页 |