【lucene】入门级

          最近在帮同学弄一个东西,无奈需要研究一下lucene,在这里笔记一下叨。大牛绕行……

一,环境搭配

        下载lucene 2. 9.4 解压到任何一个地方。 

         然后在IDE中新建一个Java工程,将之前解压的文件夹下的lucene-core-2.9.4.jar 添加到库中。(工程右键属性,库,添加jar)

二,入门级例子及讲解

       1)建立索引
             为了对文档进行索引,Lucene 提供了五个基础的类,他们分别是 Document, Field, IndexWriter, Analyzer, Directory。下面我们分别介绍一下这五个类的用途:
           
            Document 是用来描述文档的,这里的文档可以指一个 HTML 页面,一封电子邮件,或者是一个文本文件。一个 Document 对象由多个 Field 对象组成的。可以把一个 Document 对象想象成数据库中的一个记录,而每个 Field 对象就是记录的一个字段。

            Field 对象是用来描述一个文档的某个属性的,比如一封电子邮件的标题和内容可以用两个 Field 对象分别描述。

           Analyzer在一个文档被索引之前,首先需要对文档内容进行分词处理,这部分工作就是由 Analyzer 来做的。Analyzer 类是一个抽象类,它有多个实现。针对不同的语言和应用需要选择适合的 Analyzer。Analyzer 把分词后的内容交给 IndexWriter 来建立索引。

           IndexWriter 是 Lucene 用来创建索引的一个核心的类,他的作用是把一个个的 Document 对象加到索引中来。

           Directory这个类代表了 Lucene 的索引的存储的位置,这是一个抽象类,它目前有两个实现,第一个是 FSDirectory,它表示一个存储在文件系统中的索引的位置。第二个是 RAMDirectory,它表示一个存储在内存当中的索引的位置。 

      熟悉了建立索引所需要的这些类后,我们就开始对某个目录下面的文本文件建立索引了:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package textfileindexer;
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( "D:\\luceneData" );   
  
         /**/ /*  这里放索引文件的位置  */   
        File indexDir  =   new  File( "D:\\luceneIndex" );   
        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();  //Document是一个记录。用来表示一个条目。就是搜索建立的倒排索引的条目。比如说,你要搜索自己电脑上的文件。这个时候就可以创建field。然后用field组合成 document 。最后会变成若干文件。这个document和 文件系统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()方法是对索引进行优化    
        indexWriter.optimize();   
        indexWriter.close();   
           
         //测试一下索引的时间    
         long  endTime  =   new  Date().getTime();   
        System.out.println( "这花费了 "+  (endTime  -  startTime)+   "  毫秒来把文档增加到索引里面去! " +  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;   
    }    
}  
结果:

FileD:\luceneData\1.txt正在被索引.
中国中华人民共和国人民lucenelucenelucene
FileD:\luceneData\2.txt正在被索引.
lucene中国中华人民共和国人民lucenelucene
FileD:\luceneData\3.txt正在被索引.
lucenelucene中国中华人民共和国人民lucenelucene
这花费了 63  毫秒来把文档增加到索引里面去! D:\luceneData


         2)搜索文档
               利用 Lucene 进行搜索就像建立索引一样也是非常方便的。在上面一部分中,我们已经为一个目录下的文本文档建立好了索引,现在我们就要在这个索引上进行搜索以找到包含某个关键词或短语的文档。Lucene 提供了几个基础的类来完成这个过程,它们分别是呢 IndexSearcher, Term, Query, TermQuery, Hits. 下面我们分别介绍这几个类的功能。

               Query这是一个抽象类,他有多个实现,比如 TermQuery, BooleanQuery, PrefixQuery. 这个类的目的是把用户输入的查询字符串封装成 Lucene 能够识别的 Query。

               Term 是搜索的基本单位,一个 Term 对象有两个 String 类型的域组成。生成一个 Term 对象可以有如下一条语句来完成:Term term = new Term(“fieldName”,”queryWord”); 其中第一个参数代表了要在文档的哪一个 Field 上进行查找,第二个参数代表了要查询的关键词。

               TermQuery 是抽象类 Query 的一个子类,它同时也是 Lucene 支持的最为基本的一个查询类。生成一个 TermQuery 对象由如下语句完成: TermQuery termQuery = new TermQuery(new Term(“fieldName”,”queryWord”)); 它的构造函数只接受一个参数,那就是一个 Term 对象。


               IndexSearcher 是用来在建立好的索引上进行搜索的。它只能以只读的方式打开一个索引,所以可以有多个 IndexSearcher 的实例在一个索引上进行操作。


               Hits 是用来保存搜索的结果的。

              介绍完这些搜索所必须的类之后,我们就开始在之前所建立的索引上进行搜索了:

package testquery;
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( "D:\\luceneIndex" );   
    
  
        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()  +   "  个结果! " );   
            }    
        }    
    }  
  
}   
运行结果:

找到: 3  个结果! 

三,小例子测验

       1)StandardAnalyzer

              StandardAnalyzer是lucene中内置的"标准分析器",可以做如下功能:
              1、对原有句子按照空格进行了分词 
              2、所有的大写字母都可以能转换为小写的字母 
              3、可以去掉一些没有用处的单词,例如"is","the","are"等单词,也删除了所有的标点 

package standardanalyzertest;
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    
{   
     //构造函数,    
     public  StandardAnalyzerTest()   
     {   
    }    
     public   static   void  main(String[] args)    
     {   
         //生成一个StandardAnalyzer对象    
        Analyzer aAnalyzer  =   new  StandardAnalyzer();   
         //测试字符串    
        StringReader sr  =   new  StringReader( " lighter javaeye com is the are on " );   
         //生成TokenStream对象    
        TokenStream ts  =  aAnalyzer.tokenStream( "name" , sr);    
         try   {   
             int  i = 0 ;   
            Token t  =  ts.next();   
             while (t != null )   
             {   
                 //辅助输出时显示行号    
                i ++ ;   
                 //输出处理后的字符    
                System.out.println( "第 " + i + "行: " + t.termText());   
                 //取得下一个字符    
                t = ts.next();   
            }    
        }   catch  (IOException e)  {   
            e.printStackTrace();   
        }    
    }    
}    
运行结果:

第 1行: lighter
第 2行: javaeye
第 3行: com

          2)简单的简历索引并进行搜索的例子

package fsdirectorytest;
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  =   "D:\\luceneIndex" ;   
  
     public   static   void  main(String[] args)  throws  Exception  {   
        Document doc1  =   new  Document();   
        doc1.add(  new  Field( "name" ,  "中国 javaeye com" ,Field.Store.YES,Field.Index.TOKENIZED));   
  
        Document doc2  =   new  Document();   
        doc2.add( new  Field( "name" ,  "中国 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( "中国" );   
        hits  =  searcher.search(query);   
        System.out.println( "查找  中国   共 "   +  hits.length()  +   "个结果 " );   
  
        query  =  qp.parse( "javaeye" );   
        hits  =  searcher.search(query);   
        System.out.println( "查找 javaeye   共 "   +  hits.length()  +   "个结果 " );   
  
    }    
} 





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值