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

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

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

    posts - 431,  comments - 344,  trackbacks - 0

    一.  概述

    隨著系統(tǒng)信息的越來越多,怎么樣從這些信息海洋中撈起自己想要的那一根針就變得非常重要了,全文檢索是通常用于解決此類問題的方案,而Lucene則為實現(xiàn)全文檢索的工具,任何應(yīng)用都可通過嵌入它來實現(xiàn)全文檢索。

    二.  環(huán)境搭建

    從lucene.apache.org上下載最新版本的lucene.jar,將此jar作為項目的build path,那么在項目中就可以直接使用lucene了。

    三.  使用說明

    3.1.       基本概念

    這里介紹的主要為在使用中經(jīng)常碰到一些概念,以大家都比較熟悉的數(shù)據(jù)庫來進行類比的講解,使用Lucene進行全文檢索的過程有點類似數(shù)據(jù)庫的這個過程,table---à查詢相應(yīng)的字段或查詢條件----à返回相應(yīng)的記錄,首先是IndexWriter,通過它建立相應(yīng)的索引表,相當(dāng)于數(shù)據(jù)庫中的table,在構(gòu)建此索引表時需指定的為該索引表采用何種方式進行構(gòu)建,也就是說對于其中的記錄的字段以什么方式來進行格式的劃分,這個在Lucene中稱為Analyzer,Lucene提供了幾種環(huán)境下使用的Analyzer:SimpleAnalyzer、StandardAnalyzer、GermanAnalyzer等,其中StandardAnalyzer是經(jīng)常使用的,因為它提供了對于中文的支持,在表建好后我們就需要往里面插入用于索引的記錄,在Lucene中這個稱為Document,有點類似數(shù)據(jù)庫中table的一行記錄,記錄中的字段的添加方法,在Lucene中稱為Field,這個和數(shù)據(jù)庫中基本一樣,對于Field Lucene分為可被索引的,可切分的,不可被切分的,不可被索引的幾種組合類型,通過這幾個元素基本上就可以建立起索引了。在查詢時經(jīng)常碰到的為另外幾個概念,首先是Query,Lucene提供了幾種經(jīng)常可以用到的Query:TermQuery、MultiTermQuery、BooleanQuery、WildcardQuery、PhraseQuery、PrefixQuery、PhrasePrefixQuery、FuzzyQuery、RangeQuery、SpanQuery,Query其實也就是指對于需要查詢的字段采用什么樣的方式進行查詢,如模糊查詢、語義查詢、短語查詢、范圍查詢、組合查詢等,還有就是QueryParser,QueryParser可用于創(chuàng)建不同的Query,還有一個MultiFieldQueryParser支持對于多個字段進行同一關(guān)鍵字的查詢,IndexSearcher概念指的為需要對何目錄下的索引文件進行何種方式的分析的查詢,有點象對數(shù)據(jù)庫的哪種索引表進行查詢并按一定方式進行記錄中字段的分解查詢的概念,通過IndexSearcher以及Query即可查詢出需要的結(jié)果,Lucene返回的為Hits.通過遍歷Hits可獲取返回的結(jié)果的Document,通過Document則可獲取Field中的相關(guān)信息了。

    比較一下Lucene和數(shù)據(jù)庫:

    Lucene 數(shù)據(jù)庫
    索引數(shù)據(jù)源:doc(field1,field2...) doc(field1,field2...)
    \ indexer /
    _____________
    | Lucene Index|
    --------------
    / searcher \
    結(jié)果輸出:Hits(doc(field1,field2) doc(field1...))
     索引數(shù)據(jù)源:record(field1,field2...) record(field1..)
    \ SQL: insert/
    _____________
    | DB Index |
    -------------
    / SQL: select \
    結(jié)果輸出:results(record(field1,field2..) record(field1...))
    Document:一個需要進行索引的“單元”
    一個Document由多個字段組成
    Record:記錄,包含多個字段
    Field:字段 Field:字段
    Hits:查詢結(jié)果集,由匹配的Document組成 RecordSet:查詢結(jié)果集,由多個Record組成

    通過對于上面在建立索引和全文檢索的基本概念的介紹希望能讓你對Lucene建立一定的了解。

    需要熟悉幾個接口:
    分析器Analyzer
            分析器主要工作是篩選,一段文檔進來以后,經(jīng)過它,出去的時候只剩下那些有用的部分,其他則剔除。而這個分析器也可以自己根據(jù)需要而編寫。
            org.apache.lucene.analysis.Analyzer:這是一個虛構(gòu)類,以下兩個借口均繼承它而來。

            org.apache.lucene.analysis.SimpleAnalyzer:分析器,支持最簡單拉丁語言。
            org.apache.lucene.analysis.standard.StandardAnalyzer:標(biāo)準(zhǔn)分析器,除了拉丁語言還支持亞洲語言,并在一些匹配功能上進行完善。在這個接口中還有一個很重要的構(gòu)造函數(shù):StandardAnalyzer(String[] stopWords),可以對分析器定義一些使用詞語,這不僅可以免除檢索一些無用信息,而且還可以在檢索中定義禁止的政治性、非法性的檢索關(guān)鍵詞。
    IndexWriter
            IndexWriter的構(gòu)造函數(shù)有三種接口,針對目錄Directory、文件File、文件路徑String三種情況。
    例如IndexWriter(String path, Analyzer a, boolean create),path為文件路徑,a為分析器,create標(biāo)志是否重建索引(true:建立或者覆蓋已存在的索引,false:擴展已存在的索引。)
           一些重要的方法:

    接口名

    備注

    addDocument(Document doc)

    索引添加一個文檔

    addIndexes(Directory[] dirs)

    將目錄中已存在索引添加到這個索引

    addIndexes(IndexReader[] readers)

    將提供的索引添加到這個索引

    optimize()

    合并索引并優(yōu)化

    close()

    關(guān)閉

     
           IndexWriter為了減少大量的io維護操作,在每得到一定量的索引后建立新的小索引文件(筆者測試索引批量的最小單位為10),然后再定期將它們整合到一個索引文件中,因此在索引結(jié)束時必須進行wirter.optimize(),以便將所有索引合并優(yōu)化。
    org.apache.lucene.document
     以下介紹兩種主要的類:
     a)org.apache.lucene.document.Document:
            Document文檔類似數(shù)據(jù)庫中的一條記錄,可以由好幾個字段(Field)組成,并且字段可以套用不同的類型(詳細見b)。Document的幾種接口: 

    接口名

    備注

    add(Field field)

    添加一個字段(Field)到Document中

    String get(String name)

    從文檔中獲得一個字段對應(yīng)的文本

    Field getField(String name)

    由字段名獲得字段值

    Field[] getFields(String name)

    由字段名獲得字段值的集


     b)org.apache.lucene.document.Field
            即上文所說的“字段”,它是Document的片段section。
            Field的構(gòu)造函數(shù):
           Field(String name, String string, boolean store, boolean index, boolean token)。
            Indexed:如果字段是Indexed的,表示這個字段是可檢索的。
            Stored:如果字段是Stored的,表示這個字段的值可以從檢索結(jié)果中得到。
            Tokenized:如果一個字段是Tokenized的,表示它是有經(jīng)過Analyzer轉(zhuǎn)變后成為一個tokens序列,在這個轉(zhuǎn)變過程tokenization中,Analyzer提取出需要進行索引的文本,而剔除一些冗余的詞句(例如:a,the,they等,詳見org.apache.lucene.analysis.StopAnalyzer.ENGLISH_STOP_WORDS和org.apache.lucene.analysis.standard.StandardAnalyzer(String[] stopWords)的API)。Token是索引時候的基本單元,代表一個被索引的詞,例如一個英文單詞,或者一個漢字。因此,所有包含中文的文本都必須是Tokenized的。
         Field的幾種接口:

    Name

    Stored

    Indexed

    Tokenized

    use

    Keyword(String name,

            String value)

    Y

    Y

    N

    date,url

    Text(String name, Reader value)

    N

    Y

    Y

    short text fields:

    title,subject

    Text(String name, String value)

    Y

    Y

    Y

    longer text fields,

    like “body”

    UnIndexed(String name,

    String value)

    Y

    N

    N

     

    UnStored(String name,

             String value)

    N

    Y

    Y

     

    Hits與Searcher
           Hits的主要使用接口:

    接口名

    備注

    Doc(int n)

    返回第n個的文檔的所有字段

    length()

    返回這個集中的可用個數(shù)


    3.2.       全文檢索需求的實現(xiàn)

    索引建立部分的代碼:


    private void createIndex(String indexFilePath) throws Exception{

            IndexWriter iwriter=getWriter(indexFilePath);

            Document doc=new Document();

            doc.add(Field.Keyword("name","jerry"));

            doc.add(Field.Text("sender","bluedavy@gmail.com"));

            doc.add(Field.Text("receiver","google@gmail.com"));

            doc.add(Field.Text("title","用于索引的標(biāo)題"));

            doc.add(Field.UnIndexed("content","不建立索引的內(nèi)容"));

            Document doc2=new Document();

            doc2.add(Field.Keyword("name","jerry.lin"));

            doc2.add(Field.Text("sender","bluedavy@hotmail.com"));

            doc2.add(Field.Text("receiver","msn@hotmail.com"));

            doc2.add(Field.Text("title","用于索引的第二個標(biāo)題"));

            doc2.add(Field.Text("content","建立索引的內(nèi)容"));

            iwriter.addDocument(doc);

            iwriter.addDocument(doc2);

            iwriter.optimize();

            iwriter.close();

        }

       

        private IndexWriter getWriter(String indexFilePath) throws Exception{

            boolean append=true;

            File file=new File(indexFilePath+File.separator+"segments");

            if(file.exists())

                append=false;

            return new IndexWriter(indexFilePath,analyzer,append);

        }


    3.2.1.       對于某字段的關(guān)鍵字的模糊查詢


    Query query=new WildcardQuery(new Term("sender","*davy*"));

           

            Searcher searcher=new IndexSearcher(indexFilePath);

            Hits hits=searcher.search(query);

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

                System.out.println(hits.doc(i).get("name"));

            }


    3.2.2.       對于某字段的關(guān)鍵字的語義查詢


    Query query=QueryParser.parse("索引","title",analyzer);

           

            Searcher searcher=new IndexSearcher(indexFilePath);

            Hits hits=searcher.search(query);

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

                System.out.println(hits.doc(i).get("name"));

            }


    3.2.3.       對于多字段的關(guān)鍵字的查詢


    Query query=MultiFieldQueryParser.parse("索引",new String[]{"title","content"},analyzer);

           

            Searcher searcher=new IndexSearcher(indexFilePath);

            Hits hits=searcher.search(query);

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

                System.out.println(hits.doc(i).get("name"));

            }


    3.2.4.       復(fù)合查詢(多種查詢條件的綜合查詢)


    Query query=MultiFieldQueryParser.parse("索引",new String[]{"title","content"},analyzer);

            Query mquery=new WildcardQuery(new Term("sender","bluedavy*"));

            TermQuery tquery=new TermQuery(new Term("name","jerry"));

           

            BooleanQuery bquery=new BooleanQuery();

            bquery.add(query,true,false);

            bquery.add(mquery,true,false);

            bquery.add(tquery,true,false);

           

            Searcher searcher=new IndexSearcher(indexFilePath);

            Hits hits=searcher.search(bquery);

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

                System.out.println(hits.doc(i).get("name"));

            }


    四.  總結(jié)

    相信大家通過上面的說明能知道Lucene的一個基本的使用方法,在全文檢索時建議大家先采用語義時的搜索,先搜索出有意義的內(nèi)容,之后再進行模糊之類的搜索,^_^,這個還是需要根據(jù)搜索的需求才能定了,Lucene還提供了很多其他更好用的方法,這個就等待大家在使用的過程中自己去進一步的摸索了,比如對于Lucene本身提供的Query的更熟練的掌握,對于Filter、Sorter的使用,自己擴展實現(xiàn)Analyzer,自己實現(xiàn)Query等等,甚至可以去了解一些關(guān)于搜索引擎的技術(shù)(切詞、索引排序 etc)等等

    posted on 2007-01-28 10:38 周銳 閱讀(501) 評論(0)  編輯  收藏 所屬分類: Lucene

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 在线观看亚洲免费| 在线观看免费成人| 亚洲AV永久无码精品一百度影院| 精品在线免费视频| 国产小视频在线免费| 久久亚洲精品11p| 四虎成人精品在永久免费| 亚洲欧洲无码AV不卡在线| 成全视频免费高清| 国产亚洲综合久久| 亚洲毛片av日韩av无码| A级毛片高清免费视频在线播放| 曰韩亚洲av人人夜夜澡人人爽 | 亚洲AV无码一区二区乱子伦| 国产一级片免费看| 亚洲欧洲在线播放| 精品无码国产污污污免费| 黄色毛片免费网站| 亚洲欧洲自拍拍偷午夜色无码| 久久大香伊焦在人线免费| 亚洲乱码一二三四区麻豆| 国产青草视频免费观看97| 成人a毛片视频免费看| 亚洲AV无码精品色午夜果冻不卡 | 亚洲av无码片vr一区二区三区| 又色又污又黄无遮挡的免费视| www一区二区www免费| 亚洲国产综合专区在线电影| 四虎永久在线精品免费观看视频| 亚洲av无码一区二区三区人妖 | 亚洲中文字幕人成乱码| 国产成人精品123区免费视频| 丁香花在线观看免费观看图片| 亚洲国产综合91精品麻豆| 午夜dj在线观看免费视频| aa在线免费观看| 亚洲中文字幕AV在天堂| 久久精品国产亚洲精品| 成人AV免费网址在线观看| 2022国内精品免费福利视频| 亚洲人成777在线播放|