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

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

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

    kingpub

    海內(nèi)存知己,博客若比鄰

     

    lucene簡單例子

    lucene的組成結(jié)構(gòu):對于外部應(yīng)用來說索引模塊(index)和檢索模塊(search)是主要的外部應(yīng)用入口

    org.apache.Lucene.search/ 搜索入口
    org.apache.Lucene.index/ 索引入口
    org.apache.Lucene.analysis/ 語言分析器
    org.apache.Lucene.queryParser/ 查詢分析器
    org.apache.Lucene.document/ 存儲結(jié)構(gòu)
    org.apache.Lucene.store/? 底層IO/存儲結(jié)構(gòu)
    org.apache.Lucene.util/ 一些公用的數(shù)據(jù)結(jié)構(gòu)

    簡單的例子演示一下Lucene的使用方法:

    索引過程:從命令行讀取文件名(多個),將文件分路徑(path字段)和內(nèi)容(body字段)2個字段進行存儲,并對內(nèi)容進行全文索引:索引的單位是Document對象,每個Document對象包含多個字段Field對象,針對不同的字段屬性和數(shù)據(jù)輸出的需求,對字段還可以選擇不同的索引/存儲字段規(guī)則,列表如下:

    方法 切詞 索引 存儲 用途
    Field.Text(String name, String value) Yes Yes Yes 切分詞索引并存儲,比如:標(biāo)題,內(nèi)容字段
    Field.Text(String name, Reader value) Yes Yes No 切分詞索引不存儲,比如:META信息,
    不用于返回顯示,但需要進行檢索內(nèi)容
    Field.Keyword(String name, String value) No Yes Yes 不切分索引并存儲,比如:日期字段
    Field.UnIndexed(String name, String value) No No Yes 不索引,只存儲,比如:文件路徑
    Field.UnStored(String name, String value) Yes Yes No 只全文索引,不存儲
    public class IndexFiles { 
    //使用方法:: IndexFiles [索引輸出目錄] [索引的文件列表] ...
    public static void main(String[] args) throws Exception {
    String indexPath = args[0];
    IndexWriter writer;
    //用指定的語言分析器構(gòu)造一個新的寫索引器(第3個參數(shù)表示是否為追加索引)
    writer = new IndexWriter(indexPath, new SimpleAnalyzer(), false);

    for (int i=1; i System.out.println("Indexing file " + args[i]);
    InputStream is = new FileInputStream(args[i]);

    //構(gòu)造包含2個字段Field的Document對象
    //一個是路徑path字段,不索引,只存儲
    //一個是內(nèi)容body字段,進行全文索引,并存儲
    Document doc = new Document();
    doc.add(Field.UnIndexed("path", args[i]));
    doc.add(Field.Text("body", (Reader) new InputStreamReader(is)));
    //將文檔寫入索引
    writer.addDocument(doc);
    is.close();
    };
    //關(guān)閉寫索引器
    writer.close();
    }
    }
    具體的子類只需要提供一個返回getName()方法的實現(xiàn),當(dāng)在Spring上下文中定義MessageProcessor接口時,該方法返回接口特定實現(xiàn)的bean名字。子類也可以提供自己的MessageConverter,使用不同的策略填充MessageData。以下是MessageProcessor的一個簡單實現(xiàn):
    public class SimpleMessageProcessor implements MessageProcessor {  private Log log = LogFactory.getLog(getClass());  public Object process( MessageData messageData) {    log.info(messageData);    return null;  }}

      最后,具體的MDB看起來如下所示。注意,我們使用Xdoclet注釋來聲明部署描述符的元數(shù)據(jù):

    /** * SimpleMdb *  * .bean  *   name="org.javatx.mdb.SimpleMdb"  *   type="MDB" *   destination-type="javax.jms.Queue"  *   transaction-type="Bean" *  * .pool  *   initial-beans-in-free-pool= *                ""  *   max-beans-in-free-pool= *                "" *  * .message-driven  *   connection-factory-jndi-name= *                  "-e" *   destination-jndi-name= *                  "-e" *   jms-polling-interval-seconds= *                  "" *    * .env-entry *   name="BeanFactoryPath"  *   value="applicationContext.xml" */public class SimpleMdb extends MessageDataDrivenBean {  protected String getName() {    return "simpleProcessor";  }  }

      在上述代碼中,BeanFactoryPath的env-entry被Spring的EJB類用來定位應(yīng)用程序上下文。應(yīng)用程序上下文中應(yīng)該有simpleProcessor bean的聲明,這個bean會處理所有的處理邏輯,以及非功能性的需求,比如:事務(wù)、防止消息的重復(fù)處理以及可選的跟蹤和性能監(jiān)控。

      顯然,將所有非功能方面移到通知中,并利用包裝了MessageProcessor實際實現(xiàn)的ProxyFactoryBean來定義攔截器鏈是很有意義的。定義可能如下所示:

      圖1中的順序圖說明了消息處理過程以及支持該服務(wù)質(zhì)量模型所需的advisor堆棧:


    圖 1.處理傳入消息的advisor堆棧(單擊圖像查看大圖)

      實現(xiàn)消息攔截器

      現(xiàn)在我們來仔細看一下mdbTransactionInterceptor和mdbDuplicateHandlingAdvisor,它們使用上述方法提供了保證服務(wù)質(zhì)量所需的功能。

      mdbTransactionAdvisor是利用標(biāo)準的Spring TransactionInterceptor以及process()方法的PROPAGATION_REQUIRES_NEW事務(wù)屬性定義的。

    PROPAGATION_REQUIRES_NEW,timeout_300      

      在WebLogic Server中,可以將Spring包裝器用作服務(wù)器JNDI中javax.transaction.UserTransaction所公開的平臺事務(wù)管理器,并定義應(yīng)用程序上下文如下:

      鏈中的下一個通知是mdbDuplicateHandlingAdvisor。因為它還要將一些獨有鍵保存到數(shù)據(jù)庫表中,所以需要一個數(shù)據(jù)源:

    更通用的輸入輸出接口

    雖然lucene沒有定義一個確定的輸入文檔格式,但越來越多的人想到使用一個標(biāo)準的中間格式作為Lucene的數(shù)據(jù)導(dǎo)入接口,然后其他數(shù)據(jù),比如PDF只需要通過解析器轉(zhuǎn)換成標(biāo)準的中間格式就可以進行數(shù)據(jù)索引了。這個中間格式主要以XML為主,類似實現(xiàn)已經(jīng)不下4,5個:

    數(shù)據(jù)源: WORD       PDF     HTML    DB       other
    \ | | | /
    XML中間格式
    |
    Lucene INDEX

    目前還沒有針對MSWord文檔的解析器,因為Word文檔和基于ASCII的RTF文檔不同,需要使用COM對象機制解析。這個是我在Google上查的相關(guān)資料:http://www.intrinsyc.com/products/enterprise_applications.asp
    另外一個辦法就是把Word文檔轉(zhuǎn)換成text:http://www.winfield.demon.nl/index.html


    索引過程優(yōu)化

    索引一般分2種情況,一種是小批量的索引擴展,一種是大批量的索引重建。在索引過程中,并不是每次新的DOC加入進去索引都重新進行一次索引文件的寫入操作(文件I/O是一件非常消耗資源的事情)。

    Lucene先在內(nèi)存中進行索引操作,并根據(jù)一定的批量進行文件的寫入。這個批次的間隔越大,文件的寫入次數(shù)越少,但占用內(nèi)存會很多。反之占用內(nèi)存少,但文件IO操作頻繁,索引速度會很慢。在IndexWriter中有一個MERGE_FACTOR參數(shù)可以幫助你在構(gòu)造索引器后根據(jù)應(yīng)用環(huán)境的情況充分利用內(nèi)存減少文件的操作。根據(jù)我的使用經(jīng)驗:缺省Indexer是每20條記錄索引后寫入一次,每將MERGE_FACTOR增加50倍,索引速度可以提高1倍左右。

    搜索過程優(yōu)化

    lucene支持內(nèi)存索引:這樣的搜索比基于文件的I/O有數(shù)量級的速度提升。
    http://www.onjava.com/lpt/a/3273
    而盡可能減少IndexSearcher的創(chuàng)建和對搜索結(jié)果的前臺的緩存也是必要的。

    Lucene面向全文檢索的優(yōu)化在于首次索引檢索后,并不把所有的記錄(Document)具體內(nèi)容讀取出來,而起只將所有結(jié)果中匹配度最高的頭100條結(jié)果(TopDocs)的ID放到結(jié)果集緩存中并返回,這里可以比較一下數(shù)據(jù)庫檢索:如果是一個10,000條的數(shù)據(jù)庫檢索結(jié)果集,數(shù)據(jù)庫是一定要把所有記錄內(nèi)容都取得以后再開始返回給應(yīng)用結(jié)果集的。所以即使檢索匹配總數(shù)很多,Lucene的結(jié)果集占用的內(nèi)存空間也不會很多。對于一般的模糊檢索應(yīng)用是用不到這么多的結(jié)果的,頭100條已經(jīng)可以滿足90%以上的檢索需求。

    如果首批緩存結(jié)果數(shù)用完后還要讀取更后面的結(jié)果時Searcher會再次檢索并生成一個上次的搜索緩存數(shù)大1倍的緩存,并再重新向后抓取。所以如果構(gòu)造一個Searcher去查1-120條結(jié)果,Searcher其實是進行了2次搜索過程:頭100條取完后,緩存結(jié)果用完,Searcher重新檢索再構(gòu)造一個200條的結(jié)果緩存,依此類推,400條緩存,800條緩存。由于每次Searcher對象消失后,這些緩存也訪問那不到了,你有可能想將結(jié)果記錄緩存下來,緩存數(shù)盡量保證在100以下以充分利用首次的結(jié)果緩存,不讓Lucene浪費多次檢索,而且可以分級進行結(jié)果緩存。

    Lucene的另外一個特點是在收集結(jié)果的過程中將匹配度低的結(jié)果自動過濾掉了。這也是和數(shù)據(jù)庫應(yīng)用需要將搜索的結(jié)果全部返回不同之處。

    我的一些嘗試

    • 支持中文的Tokenizer:這里有2個版本,一個是通過JavaCC生成的,對CJK部分按一個字符一個TOKEN索引,另外一個是從SimpleTokenizer改寫的,對英文支持數(shù)字和字母TOKEN,對中文按迭代索引。
    • 基于XML數(shù)據(jù)源的索引器:XMLIndexer,因此所有數(shù)據(jù)源只要能夠按照DTD轉(zhuǎn)換成指定的XML,就可以用XMLIndxer進行索引了。
    • 根據(jù)某個字段排序:按記錄索引順序排序結(jié)果的搜索器:IndexOrderSearcher,因此如果需要讓搜索結(jié)果根據(jù)某個字段排序,可以讓數(shù)據(jù)源先按某個字段排好序(比如:PriceField),這樣索引后,然后在利用這個按記錄的ID順序檢索的搜索器,結(jié)果就是相當(dāng)于是那個字段排序的結(jié)果了。

    從Lucene學(xué)到更多

    Luene的確是一個面對對象設(shè)計的典范

    • 所有的問題都通過一個額外抽象層來方便以后的擴展和重用:你可以通過重新實現(xiàn)來達到自己的目的,而對其他模塊而不需要;
    • 簡單的應(yīng)用入口Searcher, Indexer,并調(diào)用底層一系列組件協(xié)同的完成搜索任務(wù);
    • 所有的對象的任務(wù)都非常專一:比如搜索過程:QueryParser分析將查詢語句轉(zhuǎn)換成一系列的精確查詢的組合(Query),通過底層的索引讀取結(jié)構(gòu)IndexReader進行索引的讀取,并用相應(yīng)的打分器給搜索結(jié)果進行打分/排序等。所有的功能模塊原子化程度非常高,因此可以通過重新實現(xiàn)而不需要修改其他模塊。?
    • 除了靈活的應(yīng)用接口設(shè)計,Lucene還提供了一些適合大多數(shù)應(yīng)用的語言分析器實現(xiàn)(SimpleAnalyser,StandardAnalyser),這也是新用戶能夠很快上手的重要原因之一。

    這些優(yōu)點都是非常值得在以后的開發(fā)中學(xué)習(xí)借鑒的。作為一個通用工具包,Lunece的確給予了需要將全文檢索功能嵌入到應(yīng)用中的開發(fā)者很多的便利。

    此外,通過對Lucene的學(xué)習(xí)和使用,我也更深刻地理解了為什么很多數(shù)據(jù)庫優(yōu)化設(shè)計中要求,比如:

    • 盡可能對字段進行索引來提高查詢速度,但過多的索引會對數(shù)據(jù)庫表的更新操作變慢,而對結(jié)果過多的排序條件,實際上往往也是性能的殺手之一。
    • 很多商業(yè)數(shù)據(jù)庫對大批量的數(shù)據(jù)插入操作會提供一些優(yōu)化參數(shù),這個作用和索引器的merge_factor的作用是類似的,
    • 20%/80%原則:查的結(jié)果多并不等于質(zhì)量好,尤其對于返回結(jié)果集很大,如何優(yōu)化這頭幾十條結(jié)果的質(zhì)量往往才是最重要的。
    • 盡可能讓應(yīng)用從數(shù)據(jù)庫中獲得比較小的結(jié)果集,因為即使對于大型數(shù)據(jù)庫,對結(jié)果集的隨機訪問也是一個非常消耗資源的

    posted on 2006-07-23 19:01 xiaofeng 閱讀(1160) 評論(0)  編輯  收藏 所屬分類: weblucene

    導(dǎo)航

    統(tǒng)計

    常用鏈接

    留言簿(2)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    收藏夾

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 久久精品国产亚洲精品| 成人免费午夜视频| 亚洲中文久久精品无码ww16| 国产精品亚洲片在线花蝴蝶| 日本最新免费不卡二区在线| 亚洲日本中文字幕天天更新| 热久久精品免费视频| 亚洲精品自偷自拍无码| 国产成人在线观看免费网站| 亚洲AV成人片无码网站| 四虎永久成人免费| 2022国内精品免费福利视频| 亚洲国产精品无码专区在线观看 | 亚洲精品无码久久毛片波多野吉衣| 丁香花在线观看免费观看图片 | 久久精品国产亚洲| 亚洲精品视频免费在线观看| 亚洲Av无码一区二区二三区| 在线观看免费宅男视频| 美女免费视频一区二区| 亚洲中文字幕不卡无码| 最近在线2018视频免费观看| 亚洲中文无码mv| 亚洲AV无码一区二三区| 成人无码WWW免费视频| 亚洲成人免费网址| 免费无码又爽又刺激高潮的视频| 男男gay做爽爽免费视频| 在线观看亚洲av每日更新| 99久久国产免费-99久久国产免费| 亚洲91精品麻豆国产系列在线| 全免费一级午夜毛片| 巨胸喷奶水www永久免费| 亚洲人成电影福利在线播放| 嫩草影院在线免费观看| av午夜福利一片免费看久久| 亚洲专区中文字幕| 亚洲中文字幕伊人久久无码| 18禁黄网站禁片免费观看不卡| 亚洲AV永久无码天堂影院| 国产亚洲av片在线观看16女人|