• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            為生存而奔跑

               :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
              271 Posts :: 0 Stories :: 58 Comments :: 0 Trackbacks

            留言簿(5)

            我參與的團(tuán)隊(duì)

            搜索

            •  

            積分與排名

            • 積分 - 328403
            • 排名 - 74

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            Luceneapache組織的一個(gè)用java實(shí)現(xiàn)全文搜索引擎的開源項(xiàng)目。 其功能非常的強(qiáng)大,api也很簡(jiǎn)單。總得來(lái)說(shuō)用Lucene來(lái)進(jìn)行建立 和搜索和操作數(shù)據(jù)庫(kù)是差不多的(有點(diǎn)像)Document可以看作是 數(shù)據(jù)庫(kù)的一行記錄,Field可以看作是數(shù)據(jù)庫(kù)的字段。用lucene實(shí) 現(xiàn)搜索引擎就像用JDBC實(shí)現(xiàn)連接數(shù)據(jù)庫(kù)一樣簡(jiǎn)單。

            Lucene2.0,它與以前廣泛應(yīng)用和介紹的Lucene 1.4.3并不兼容。 Lucene2.0的下載地址是http://apache.justdn.org/lucene/java/


            例子一 

            1
            、在windows系統(tǒng)下的的C盤,建一個(gè)名叫s的文件夾,在該文件夾里面隨便建三個(gè)txt文件,隨便起名啦,就叫"1.txt","2.txt""3.txt" 
            其中1.txt的內(nèi)容如下:

            中華人民共和國(guó)   
            全國(guó)人民   
            2006
              

            "2.txt""3.txt"的內(nèi)容也可以隨便寫幾寫,這里懶寫,就復(fù)制一個(gè)和1.txt文件的內(nèi)容一樣吧

            2
            、下載lucene包,放在classpath路徑中 
            建立索引:

            package  lighter.javaeye.com;   
              
            import  java.io.BufferedReader;   
            import  java.io.File;   
            import  java.io.FileInputStream;   
            import  java.io.IOException;   
            import  java.io.InputStreamReader;   
            import  java.util.Date;   
              
            import  org.apache.lucene.analysis.Analyzer;   
            import  org.apache.lucene.analysis.standard.StandardAnalyzer;   
            import  org.apache.lucene.document.Document;   
            import  org.apache.lucene.document.Field;   
            import  org.apache.lucene.index.IndexWriter;   
              
            /**   
             * author lighter date 2006-8-7  
             
             */   
            public   class  TextFileIndexer  {   
                
             public   static   void  main(String[] args)  throws  Exception  {   
                    
             /*  
            指明要索引文件夾的位置,這里是C盤的S文件夾下  */   
                    File fileDir 
             =   new  File( " c:\\s " );   
              
                    
             /*  
            這里放索引文件的位置  */   
                    File indexDir 
             =   new  File( " c:\\index " );   
                    Analyzer luceneAnalyzer 
             =   new  StandardAnalyzer();   
                    IndexWriter indexWriter 
             =   new  IndexWriter(indexDir, luceneAnalyzer,   
                            
             true );   
                    File[] textFiles 
             =  fileDir.listFiles();   
                    
             long  startTime  =   new  Date().getTime();   
                       
                    
             // 
            增加document到索引去    
                     for  ( int  i  =   0 ; i  <  textFiles.length; i ++  {   
                        
             if  (textFiles[i].isFile()   
                                
             &&  textFiles[i].getName().endsWith( " .txt " ))  {   
                            System.out.println(
             " File  "   +  textFiles[i].getCanonicalPath()   
                                    
             +   " 
            正在被索引 . " );   
                            String temp 
             =  FileReaderAll(textFiles[i].getCanonicalPath(),   
                                    
             " GBK " );   
                            System.out.println(temp);   
                            Document document 
             =   new  Document();   
                            Field FieldPath 
             =   new  Field( " path " , textFiles[i].getPath(),   
                                    Field.Store.YES, Field.Index.NO);   
                            Field FieldBody 
             =   new  Field( " body " , temp, Field.Store.YES,   
                                    Field.Index.TOKENIZED,   
                                    Field.TermVector.WITH_POSITIONS_OFFSETS);   
                            document.add(FieldPath);   
                            document.add(FieldBody);   
                            indexWriter.addDocument(document);   
                        }
                
                    }
                
                    
             // optimize()
            方法是對(duì)索引進(jìn)行優(yōu)化    
                    indexWriter.optimize();   
                    indexWriter.close();   
                       
                    
             // 
            測(cè)試一下索引的時(shí)間    
                     long  endTime  =   new  Date().getTime();   
                    System.out   
                            .println(
             " 
            這花費(fèi)了 "   
                                    
             +  (endTime  -  startTime)   
                                    
             +   "  
            毫秒來(lái)把文檔增加到索引里面去! "   
                                    
             +  fileDir.getPath());   
                }
                
              
                
             public   static  String FileReaderAll(String FileName, String charset)   
                        
             throws  IOException  {   
                    BufferedReader reader 
             =   new  BufferedReader( new  InputStreamReader(   
                            
             new  FileInputStream(FileName), charset));   
                    String line 
             =   new  String();   
                    String temp 
             =   new  String();   
                       
                    
             while  ((line  =  reader.readLine())  !=   null  {   
                        temp 
             +=  line;   
                    }
                
                    reader.close();   
                    
             return  temp;   
                }
                
            }
              

            索引的結(jié)果:

            File C:\s\ 1 .txt正在被索引 .   
            中華人民共和國(guó)全國(guó)人民2006   
            File C:\s\
             2 .txt正在被索引 .   
            中華人民共和國(guó)全國(guó)人民2006   
            File C:\s\
             3 .txt正在被索引 .   
            中華人民共和國(guó)全國(guó)人民2006   
            這花費(fèi)了297 毫秒來(lái)把文檔增加到索引里面去 ! c:\s  


            3
            、建立了索引之后,查詢啦....

            package  lighter.javaeye.com;   
              
            import  java.io.IOException;   
              
            import  org.apache.lucene.analysis.Analyzer;   
            import  org.apache.lucene.analysis.standard.StandardAnalyzer;   
            import  org.apache.lucene.queryParser.ParseException;   
            import  org.apache.lucene.queryParser.QueryParser;   
            import  org.apache.lucene.search.Hits;   
            import  org.apache.lucene.search.IndexSearcher;   
            import  org.apache.lucene.search.Query;   
              
            public   class  TestQuery  {   
                
             public   static   void  main(String[] args)  throws  IOException, ParseException  {   
                    Hits hits 
             =   null ;   
                    String queryString 
             =   " 
            中華 " ;   
                    Query query 
             =   null ;   
                    IndexSearcher searcher 
             =   new  IndexSearcher( " c:\\index " );   
              
                    Analyzer analyzer 
             =   new  StandardAnalyzer();   
                    
             try   {   
                        QueryParser qp 
             =   new  QueryParser( " body " , analyzer);   
                        query 
             =  qp.parse(queryString);   
                    }
               catch  (ParseException e)  {   
                    }
                
                    
             if  (searcher  !=   null  {   
                        hits 
             =  searcher.search(query);   
                        
             if  (hits.length()  >   0  {   
                            System.out.println(
             " 
            找到: "   +  hits.length()  +   "  個(gè)結(jié)果! " );   
                        }
                
                    }
                
                }
              
              
            }
               

            其運(yùn)行結(jié)果:

            找到: 3  個(gè)結(jié)果 !

             

            Lucene 其實(shí)很簡(jiǎn)單的,它最主要就是做兩件事:建立索引和進(jìn)行搜索 
            來(lái)看一些在lucene中使用的術(shù)語(yǔ),這里并不打算作詳細(xì)的介紹,只是點(diǎn)一下而已----因?yàn)檫@一個(gè)世界有一種好東西,叫搜索。

            IndexWriter:lucene中最重要的的類之一,它主要是用來(lái)將文檔加入索引,同時(shí)控制索引過程中的一些參數(shù)使用。

            Analyzer:分析器,主要用于分析搜索引擎遇到的各種文本。常用的有StandardAnalyzer分析器,StopAnalyzer分析器,WhitespaceAnalyzer分析器等。

            Directory:索引存放的位置;lucene提供了兩種索引存放的位置,一種是磁盤,一種是內(nèi)存。一般情況將索引放在磁盤上;相應(yīng)地lucene提供了FSDirectoryRAMDirectory兩個(gè)類。

            Document:文檔;Document相當(dāng)于一個(gè)要進(jìn)行索引的單元,任何可以想要被索引的文件都必須轉(zhuǎn)化為Document對(duì)象才能進(jìn)行索引。

            Field:字段。

            IndexSearcher:lucene中最基本的檢索工具,所有的檢索都會(huì)用到IndexSearcher工具;

            Query:查詢,lucene中支持模糊查詢,語(yǔ)義查詢,短語(yǔ)查詢,組合查詢等等,如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery等一些類。

            QueryParser是一個(gè)解析用戶輸入的工具,可以通過掃描用戶輸入的字符串,生成Query對(duì)象。

            Hits:在搜索完成之后,需要把搜索結(jié)果返回并顯示給用戶,只有這樣才算是完成搜索的目的。在lucene中,搜索的結(jié)果的集合是用Hits類的實(shí)例來(lái)表示的。

            上面作了一大堆名詞解釋,下面就看幾個(gè)簡(jiǎn)單的實(shí)例吧
            1
            、簡(jiǎn)單的的StandardAnalyzer測(cè)試?yán)?/span>

             

            package  lighter.javaeye.com;   
              
            import  java.io.IOException;   
            import  java.io.StringReader;   
              
            import  org.apache.lucene.analysis.Analyzer;   
            import  org.apache.lucene.analysis.Token;   
            import  org.apache.lucene.analysis.TokenStream;   
            import  org.apache.lucene.analysis.standard.StandardAnalyzer;   
              
            public   class  StandardAnalyzerTest    
            {   
                
             // 
            構(gòu)造函數(shù),    
                 public  StandardAnalyzerTest()   
                
             {   
                }
                
                
             public   static   void  main(String[] args)    
                
             {   
                    
             // 
            生成一個(gè)StandardAnalyzer對(duì)象    
                    Analyzer aAnalyzer  =   new  StandardAnalyzer();   
                    
             // 
            測(cè)試字符串    
                    StringReader sr  =   new  StringReader( " lighter javaeye com is the are on " );   
                    
             // 
            生成TokenStream對(duì)象    
                    TokenStream ts  =  aAnalyzer.tokenStream( " name " , sr);    
                    
             try   {   
                        
             int  i = 0 ;   
                        Token t 
             =  ts.next();   
                        
             while (t != null )   
                        
             {   
                            
             // 
            輔助輸出時(shí)顯示行號(hào)    
                            i ++ ;   
                            
             // 
            輸出處理后的字符    
                            System.out.println( " 
             " + i + " : " + t.termText());   
                            
             // 
            取得下一個(gè)字符    
                            t = ts.next();   
                        }
                
                    }
               catch  (IOException e)  {   
                        e.printStackTrace();   
                    }
                
                }
                
            }
                

            顯示結(jié)果:

            1:lighter 
            2:javaeye 
            3:com

            提示一下: 
            StandardAnalyzer
            lucene中內(nèi)置的"標(biāo)準(zhǔn)分析器",可以做如下功能
            1
            、對(duì)原有句子按照空格進(jìn)行了分詞 
            2
            、所有的大寫字母都可以能轉(zhuǎn)換為小寫的字母 
            3
            、可以去掉一些沒有用處的單詞,例如"is","the","are"等單詞,也刪除了所有的標(biāo)點(diǎn) 
            查看一下結(jié)果與"new StringReader("lighter javaeye com is the are on")"作一個(gè)比較就清楚明了。 
            這里不對(duì)其API進(jìn)行解釋了,具體見lucene的官方文檔。需要注意一點(diǎn),這里的代碼使用的是lucene2API,與1.43版有一些明顯的差別。

            2、看另一個(gè)實(shí)例,簡(jiǎn)單地建立索引,進(jìn)行搜索

            package  lighter.javaeye.com;   
            import  org.apache.lucene.analysis.standard.StandardAnalyzer;   
            import  org.apache.lucene.document.Document;   
            import  org.apache.lucene.document.Field;   
            import  org.apache.lucene.index.IndexWriter;   
            import  org.apache.lucene.queryParser.QueryParser;   
            import  org.apache.lucene.search.Hits;   
            import  org.apache.lucene.search.IndexSearcher;   
            import  org.apache.lucene.search.Query;   
            import  org.apache.lucene.store.FSDirectory;   
              
            public   class  FSDirectoryTest  {   
              
                
             // 
            建立索引的路徑    
                 public   static   final  String path  =   " c:\\index2 " ;   
              
                
             public   static   void  main(String[] args)  throws  Exception  {   
                    Document doc1 
             =   new  Document();   
                    doc1.add( 
             new  Field( " name "  " lighter javaeye com " ,Field.Store.YES,Field.Index.TOKENIZED));   
              
                    Document doc2 
             =   new  Document();   
                    doc2.add(
             new  Field( " name "  " lighter blog " ,Field.Store.YES,Field.Index.TOKENIZED));   
              
                    IndexWriter writer 
             =   new  IndexWriter(FSDirectory.getDirectory(path,  true ),  new  StandardAnalyzer(),  true );   
                    writer.setMaxFieldLength(
             3 );   
                    writer.addDocument(doc1);   
                    writer.setMaxFieldLength(
             3 );   
                    writer.addDocument(doc2);   
                    writer.close();   
              
                    IndexSearcher searcher 
             =   new  IndexSearcher(path);   
                    Hits hits 
             =   null ;   
                    Query query 
             =   null ;   
                    QueryParser qp 
             =   new  QueryParser( " name " , new  StandardAnalyzer());   
                       
                    query 
             =  qp.parse( " lighter " );   
                    hits 
             =  searcher.search(query);   
                    System.out.println(
             " 
            查找\ " lighter\ "   "   +  hits.length()  +   " 個(gè)結(jié)果 " );   
              
                    query 
             =  qp.parse( " javaeye " );   
                    hits 
             =  searcher.search(query);   
                    System.out.println(
             " 
            查找\ " javaeye\ "   "   +  hits.length()  +   " 個(gè)結(jié)果 " );   
              
                }
                
              
            }
               

            運(yùn)行結(jié)果:

            查找 " lighter "  2個(gè)結(jié)果   
            查找 " javaeye "  1個(gè)結(jié)果 


            到現(xiàn)在我們已經(jīng)可以用lucene建立索引了
            下面介紹一下幾個(gè)功能來(lái)完善一下:
            1
            .索引格式

            其實(shí)索引目錄有兩種格式,

            一種是除配置文件外,每一個(gè)Document獨(dú)立成為一個(gè)文件(這種搜索起來(lái)會(huì)影響速度)。

            另一種是全部的Document成一個(gè)文件,這樣屬于復(fù)合模式就快了。

            2.
            索引文件可放的位置:

            索引可以存放在兩個(gè)地方1.硬盤,2.內(nèi)存
            放在硬盤上可以用FSDirectory(),放在內(nèi)存的用RAMDirectory()不過一關(guān)機(jī)就沒了

            FSDirectory.getDirectory(File file,  boolean  create)
            FSDirectory.getDirectory(String path, 
             boolean  create)

            兩個(gè)工廠方法返回目錄
            New RAMDirectory()
            就直接可以
            再和

            IndexWriter(Directory d, Analyzer a,  boolean  create)

            一配合就行了
            如:

            IndexWrtier indexWriter  =   new  IndexWriter(FSDirectory.getDirectory(“c:\\index”, true ), new  StandardAnlyazer(), true );
            IndexWrtier indexWriter 
             =   new  IndexWriter( new  RAMDirectory(), new  StandardAnlyazer(), true );

            3.索引的合并
            這個(gè)可用

            IndexWriter.addIndexes(Directory[] dirs)

            將目錄加進(jìn)去
            來(lái)看個(gè)例子:

            public   void  UniteIndex()  throws  IOException
                
             {
                    IndexWriter writerDisk 
             =   new  IndexWriter(FSDirectory.getDirectory( " c:\\indexDisk "  true ), new  StandardAnalyzer(), true );
                    Document docDisk 
             =   new  Document();
                    docDisk.add(
             new  Field( " name " , " 
            程序員之家 " ,Field.Store.YES,Field.Index.TOKENIZED));
                    writerDisk.addDocument(docDisk);
                    RAMDirectory ramDir 
             =   new  RAMDirectory();
                    IndexWriter writerRam 
             =   new  IndexWriter(ramDir, new  StandardAnalyzer(), true );
                    Document docRam 
             =   new  Document();
                    docRam.add(
             new  Field( " name " , " 
            程序員雜志 " ,Field.Store.YES,Field.Index.TOKENIZED));
                    writerRam.addDocument(docRam);
                    writerRam.close();
             // 
            這個(gè)方法非常重要,是必須調(diào)用的 
                    writerDisk.addIndexes( new  Directory[] {ramDir} );
                    writerDisk.close();
                }
             
                
             public   void  UniteSearch()  throws  ParseException, IOException
                
             {
                    QueryParser queryParser 
             =   new  QueryParser( " name " , new  StandardAnalyzer());
                    Query query 
             =  queryParser.parse( " 
            程序員 " );
                    IndexSearcher indexSearcher 
             = new  IndexSearcher( " c:\\indexDisk " );
                    Hits hits 
             =  indexSearcher.search(query);
                    System.out.println(
             " 
            找到了 " + hits.length() + " 結(jié)果 " );
                    
             for ( int  i = 0 ;i
                    
             {
                        Document doc 
             =  hits.doc(i);
                        System.out.println(doc.get(
             " name " ));
                    }
             
            }


            這個(gè)例子是將內(nèi)存中的索引合并到硬盤上來(lái).
            注意:合并的時(shí)候一定要將被合并的那一方的IndexWriterclose()方法調(diào)用。

            4.
            對(duì)索引的其它操作:
            IndexReader
            類是用來(lái)操作索引的,它有對(duì)Document,Field的刪除等操作。
            下面一部分的內(nèi)容是:全文的搜索
            全文的搜索主要是用:IndexSearcher,Query,Hits,Document(都是Query的子類),有的時(shí)候用QueryParser
            主要步驟:

            1 . new  QueryParser(Field字段, new  分析器)
            2
             .Query query  =  QueryParser.parser(“要查詢的字串”);這個(gè)地方我們可以用反射api看一下query究竟是什么類型
            3
             . new  IndexSearcher(索引目錄).search(query);返回Hits
            4
             .Hits.doc(n);可以遍歷出Document
            5
             .Document可得到Field的具體信息了。

            其實(shí)1 ,2兩步就是為了弄出個(gè)Query 實(shí)例,究竟是什么類型的看分析器了。

            拿以前的例子來(lái)說(shuō)吧

            QueryParser queryParser  =   new  QueryParser( " name " , new  StandardAnalyzer());
                    Query query 
             =  queryParser.parse( " 
            程序員 " );
            /* 
            這里返回的就是org.apache.lucene.search.PhraseQuery */ 
                    IndexSearcher indexSearcher 
             = new  IndexSearcher( " c:\\indexDisk " );
                    Hits hits 
             =  indexSearcher.search(query);


            不管是什么類型,無(wú)非返回的就是Query的子類,我們完全可以不用這兩步直接new個(gè)Query的子類的實(shí)例就ok了,不過一般還是用這兩步因?yàn)樗祷氐氖?/span>PhraseQuery這個(gè)是非常強(qiáng)大的query子類它可以進(jìn)行多字搜索用QueryParser可以設(shè)置各個(gè)關(guān)鍵字之間的關(guān)系這個(gè)是最常用的了。
            IndexSearcher:
            其實(shí)IndexSearcher它內(nèi)部自帶了一個(gè)IndexReader用來(lái)讀取索引的,IndexSearcher有個(gè)close()方法,這個(gè)方法不是用來(lái)關(guān)閉IndexSearche的是用來(lái)關(guān)閉自帶的IndexReader

            QueryParser
            呢可以用parser.setOperator()來(lái)設(shè)置各個(gè)關(guān)鍵字之間的關(guān)系(與還是或)它可以自動(dòng)通過空格從字串里面將關(guān)鍵字分離出來(lái)。
            注意:用QueryParser搜索的時(shí)候分析器一定的和建立索引時(shí)候用的分析器是一樣的。
            Query:
            可以看一個(gè)lucene2.0的幫助文檔有很多的子類:
            BooleanQuery, ConstantScoreQuery, ConstantScoreRangeQuery, DisjunctionMaxQuery, FilteredQuery, MatchAllDocsQuery, MultiPhraseQuery, MultiTermQuery, PhraseQuery, PrefixQuery, RangeQuery, SpanQuery, TermQuery
            各自有用法看一下文檔就能知道它們的用法了
            下面一部分講一下lucene的分析器:
            分析器是由分詞器和過濾器組成的,拿英文來(lái)說(shuō)吧分詞器就是通過空格把單詞分開,過濾器就是把the,to,of等詞去掉不被搜索和索引。
            我們最常用的是StandardAnalyzer()它是lucene的標(biāo)準(zhǔn)分析器它集成了內(nèi)部的許多的分析器。
            最后一部分了:lucene的高級(jí)搜索了
            1.
            排序
            Lucene
            有內(nèi)置的排序用IndexSearcher.search(query,sort)但是功能并不理想。我們需要自己實(shí)現(xiàn)自定義的排序。
            這樣的話得實(shí)現(xiàn)兩個(gè)接口: ScoreDocComparator, SortComparatorSource
            IndexSearcher.search(query,new Sort(new SortField(String Field,SortComparatorSource)));
            就看個(gè)例子吧:
            這是一個(gè)建立索引的例子:

            public   void  IndexSort()  throws  IOException
            {
                    IndexWriter writer 
             =   new  IndexWriter( " C:\\indexStore " , new  StandardAnalyzer(), true );
                    Document doc 
             =   new  Document()
                    doc.add(
             new  Field( " sort " , " 1 " ,Field.Store.YES,Field.Index.TOKENIZED));
                    writer.addDocument(doc);
                    doc 
             =   new  Document();
                    doc.add(
             new  Field( " sort " , " 4 " ,Field.Store.YES,Field.Index.TOKENIZED));
                    writer.addDocument(doc);
                    doc 
             =   new  Document();
                    doc.add(
             new  Field( " sort " , " 3 " ,Field.Store.YES,Field.Index.TOKENIZED));
                    writer.addDocument(doc);
                    doc 
             =   new  Document();
                    doc.add(
             new  Field( " sort " , " 5 " ,Field.Store.YES,Field.Index.TOKENIZED));
                    writer.addDocument(doc);
                    doc 
             =   new  Document();
                    doc.add(
             new  Field( " sort " , " 9 " ,Field.Store.YES,Field.Index.TOKENIZED));
                    writer.addDocument(doc);
                    doc 
             =   new  Document();
                    doc.add(
             new  Field( " sort " , " 6 " ,Field.Store.YES,Field.Index.TOKENIZED));
                    writer.addDocument(doc);
                    doc 
             =   new  Document();
                    doc.add(
             new  Field( " sort " , " 7 " ,Field.Store.YES,Field.Index.TOKENIZED));
                    writer.addDocument(doc);
                    writer.close();
            }
             


            下面是搜索的例子:
            [code]
            public void SearchSort1() throws IOException, ParseException
            {
                    IndexSearcher indexSearcher = new IndexSearcher("C:\\indexStore");
                    QueryParser queryParser = new QueryParser("sort",new StandardAnalyzer());
                    Query query = queryParser.parse("4");
                   
                    Hits hits = indexSearcher.search(query);
                    System.out.println("
            "+hits.length()+"個(gè)結(jié)果");
                    Document doc = hits.doc(0);
                    System.out.println(doc.get("sort"));
            }
            public void SearchSort2() throws IOException, ParseException
            {
                    IndexSearcher indexSearcher = new IndexSearcher("C:\\indexStore");
                    Query query = new RangeQuery(new Term("sort","1"),new Term("sort","9"),true);//
            這個(gè)地方前面沒有提到,它是用于范圍的Query可以看一下幫助文檔.
                    Hits hits = indexSearcher.search(query,new Sort(new SortField("sort",new MySortComparatorSource())));
                    System.out.println("
            "+hits.length()+"個(gè)結(jié)果");
                    for(int i=0;i
                    {
                        Document doc = hits.doc(i);
                        System.out.println(doc.get("sort"));
                    }
            }
            public class MyScoreDocComparator implements ScoreDocComparator
            {
                private Integer[]sort;
                public MyScoreDocComparator(String s,IndexReader reader, String fieldname) throws IOException
                {
                    sort = new Integer[reader.maxDoc()];
                    for(int i = 0;i
                    {
                        Document doc =reader.document(i);
                        sort[i]=new Integer(doc.get("sort"));
                    }
                }
                public int compare(ScoreDoc i, ScoreDoc j)
                {
                    if(sort[i.doc]>sort[j.doc])
                        return 1;
                    if(sort[i.doc]
                        return -1;
                    return 0;
                }
                public int sortType()
                {
                    return SortField.INT;
                }
                public Comparable sortValue(ScoreDoc i)
                {
                    // TODO 
            自動(dòng)生成方法存根
                    return new Integer(sort[i.doc]);
                }
            }
            public class MySortComparatorSource implements SortComparatorSource
            {
                private static final long serialVersionUID = -9189690812107968361L;
                public ScoreDocComparator newComparator(IndexReader reader, String fieldname)
                        throws IOException
                {
                    if(fieldname.equals("sort"))
                        return new MyScoreDocComparator("sort",reader,fieldname);
                    return null;
                }
            }[/code]
            SearchSort1()
            輸出的結(jié)果沒有排序,SearchSort2()就排序了。
            2.
            多域搜索MultiFieldQueryParser
            如果想輸入關(guān)鍵字而不想關(guān)心是在哪個(gè)Field里的就可以用MultiFieldQueryParser
            用它的構(gòu)造函數(shù)即可后面的和一個(gè)Field一樣。
            MultiFieldQueryParser. parse(String[] queries, String[] fields, BooleanClause.Occur[] flags, Analyzer analyzer)                                          ~~~~~~~~~~~~~~~~~
            第三個(gè)參數(shù)比較特殊這里也是與以前lucene1.4.3不一樣的地方
            看一個(gè)例子就知道了
            String[] fields = {"filename", "contents", "description"};
             BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
                            BooleanClause.Occur.MUST,//
            在這個(gè)Field里必須出現(xiàn)的
                            BooleanClause.Occur.MUST_NOT};//
            在這個(gè)Field里不能出現(xiàn)
             MultiFieldQueryParser.parse("query", fields, flags, analyzer);

            1
            lucene的索引不能太大,要不然效率會(huì)很低。大于1G的時(shí)候就必須考慮分布索引的問題

            2、不建議用多線程來(lái)建索引,產(chǎn)生的互鎖問題很麻煩。經(jīng)常發(fā)現(xiàn)索引被lock,無(wú)法重新建立的情況

            3、中文分詞是個(gè)大問題,目前免費(fèi)的分詞效果都很差。如果有能力還是自己實(shí)現(xiàn)一個(gè)分詞模塊,用最短路徑的切分方法,網(wǎng)上有教材和demo源碼,可以參考。

            4、建增量索引的時(shí)候很耗cpu,在訪問量大的時(shí)候會(huì)導(dǎo)致cpuidle0

            5、默認(rèn)的評(píng)分機(jī)制不太合理,需要根據(jù)自己的業(yè)務(wù)定制

             

            整體來(lái)說(shuō)lucene要用好不容易,必須在上述方面擴(kuò)充他的功能,才能作為一個(gè)商用的搜索引擎

            posted on 2010-01-05 09:14 baby-fly 閱讀(1959) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Information Retrival / Data Mining
            思思久久99热只有频精品66| 少妇被又大又粗又爽毛片久久黑人| 中文成人无码精品久久久不卡| 久久伊人色| 思思久久好好热精品国产| 亚洲精品无码久久久影院相关影片| 99久久精品免费看国产一区二区三区 | 人人狠狠综合久久亚洲| 思思久久99热只有频精品66| 久久夜色精品国产噜噜亚洲AV| 久久青青草原精品影院| 亚洲欧美国产精品专区久久| 久久久久久久久久久久中文字幕 | 97精品伊人久久大香线蕉app| 99久久精品日本一区二区免费 | 亚洲国产欧洲综合997久久| 久久91精品久久91综合| 欧美与黑人午夜性猛交久久久| 无码人妻精品一区二区三区久久 | 久久精品三级视频| 久久超碰97人人做人人爱| 久久久久无码专区亚洲av| 国产精品国色综合久久| 欧美日韩精品久久久久| 久久综合久久综合久久| 日韩人妻无码一区二区三区久久 | 91久久精品视频| 99久久国产综合精品女同图片| 91精品国产91久久久久久青草| 久久久久亚洲av成人网人人软件| 26uuu久久五月天| 国产精品久久久福利| 久久青青草原亚洲av无码app| 性欧美大战久久久久久久| 久久久久亚洲精品中文字幕| 亚洲午夜精品久久久久久人妖| 亚洲欧美成人综合久久久| 久久精品国产乱子伦| 99久久免费国产精品特黄| 久久久高清免费视频| 一本综合久久国产二区|