Lucene 4.10.2开发示例

这里面用的是比较新的Lucene4.10.2 做的一个实例。(lucene的索引不能太大,要不然效率会很低。大于1G的时候就必须考虑分布索引的问题)

先介绍一下Lucene的几个参数意义:

 

IndexWriter:lucene中最重要的的类之一,它主要是用来将文档加入索引,同时控制索引过程中的一些参数使用。

 

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

 

Directory:索引存放的位置;lucene提供了两种索引存放的位置,一种是磁盘,一种是内存。一般情况将索引放在磁盘上;相应地lucene提供了FSDirectory和RAMDirectory两个类。

 

Document:文档;Document相当于一个要进行索引的单元,任何可以想要被索引的文件都必须转化为Document对象才能进行索引。

 

Field:字段。

 

IndexSearcher:是lucene中最基本的检索工具,所有的检索都会用到IndexSearcher工具;

 

Query:查询,lucene中支持模糊查询,语义查询,短语查询,组合查询等等,如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery等一些类。

 

QueryParser: 是一个解析用户输入的工具,可以通过扫描用户输入的字符串,生成Query对象。

 

话说Lucene就两个重要步骤,一个是创建索引,一个是查询索引,首先看下如何创建索引的代码。

 

import util.IOUtil;
/**
 * @author ${朱良兴}
 *2015-1-26
 */
public class CreateIndexer {  
    
    public void createIndex() throws Exception{
        
        IOUtil utils= new IOUtil();
        // 一、创建索引
        // 内存索引模板
        Directory dir = new RAMDirectory();
        Analyzer analyzer = new StandardAnalyzer();
        IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_2,
                analyzer);
        IndexWriter indexWriter = new IndexWriter(dir, config);
        //文件位置。
        File fileDir  =   new  File( "E:\\ftp" );   
       String path =  "E:\\ftp";
       long  startTime  =   new  Date().getTime(); 
       String id;
       //获取所有的文件名。
       List <String> fileList = utils.getFileName(path);
       for(int i=0; i<fileList.size();i++){
              String content = utils.getFileContent(new File(fileList.get(i)), "GBK");
              id ="id"+i;
              indexPost(id, content);
       }
    
       // 测试一下索引的时间   
       long  endTime  =   new  Date().getTime();   
      System.out .println( " 这花费了 " +  (endTime  -  startTime) + "  毫秒来把文档增加到索引里面去! " +  fileDir.getPath());   
      indexWriter.close();    
        
        
        
    }
    @SuppressWarnings("deprecation")
    private static void indexPost(String id,String content){
          /*  这里放索引文件的位置  */ 
        File indexDir = new File("E:\\index");
        Analyzer analyzer = new IKAnalyzer();
        TextField postIdField = new TextField("id", id, Store.YES);  // 不要用StringField
        TextField postContentField = new TextField("content", content, Store.YES);
 
        Document doc = new Document();
        doc.add(postIdField);
        doc.add(postContentField);
        IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_4_10_2, analyzer);
        iwConfig.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
        try {
            Directory fsDirectory = FSDirectory.open(indexDir);
            IndexWriter indexWriter = new IndexWriter(fsDirectory, iwConfig);
            indexWriter.addDocument(doc);
            indexWriter.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }

 

第二就是查询:

 

/**
 * 查询索引
 * @author ${朱良兴}
 *2015-1-26
 */
public class DoSearch {
    public static void main(String[] args) throws Exception {
        //创建索引
        CreateIndexer createIndexer = new CreateIndexer();
        createIndexer.createIndex();
        Analyzer analyzer = new IKAnalyzer();
        File indexDir = new File("E:\\index");
        try {
            Directory fsDirectory = FSDirectory.open(indexDir);
            DirectoryReader ireader = DirectoryReader.open(fsDirectory);
            IndexSearcher isearcher = new IndexSearcher(ireader);
            QueryParser qp = new QueryParser("content", analyzer);         //使用QueryParser查询分析器构造Query对象
            qp.setDefaultOperator(QueryParser.AND_OPERATOR);
            Query query = qp.parse("么么哒");     // 搜索Lucene
            long  beginTime  =   new  Date().getTime();   
            TopDocs topDocs = isearcher.search(query , 100);      //搜索相似度最高的100条记录
            long  endTime  =   new  Date().getTime();   
            System.out.println("命中:" + topDocs.totalHits);
            System.out.println("搜索花费的时间:"+(endTime-beginTime)+"毫秒");
            ScoreDoc[] scoreDocs = topDocs.scoreDocs;
            for (int i = 0; i < topDocs.totalHits; i++){
                Document targetDoc = isearcher.doc(scoreDocs[i].doc);
                System.out.println("内容:" + targetDoc.toString());
            }
 
        } catch (Exception e) {
 
        }
    }
}

 

用到的工具类代码:

 

package util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;


/**
 * IO 工具类。
 * @author ${朱良兴}
 *2015-1-26
 */
public class IOUtil{
    
    List<String> fileList = new ArrayList<String>();
  /**
   * 根据文件的全路径获得所有的文件内容
 * @param fileName
 * @param charset
 * @return
 * @throws Exception
 */
public String    getFileContent(File fileName, String charset) throws Exception{
        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;
  }
    /**
     * 获取所有的文件名
     * @param path
     * @return
     * @throws Exception
     */
    public List<String> getFileName(String path) throws Exception{
        
        String filenName ="";
         //文件位置。
        File fileDir = new  File(path);
        File[] textFiles  =  fileDir.listFiles(); 
        if (textFiles!=null){
        
        // 增加document到索引去   
            for  ( int  i  =   0 ; i  <  textFiles.length; i ++ )  {   
            if  (textFiles[i].isFile())  { 
                 System.out.println( " File  "   +  textFiles[i].getCanonicalPath()   
                         +   " 正在被索引. " ); 
                filenName=textFiles[i].getCanonicalPath();
                fileList.add(filenName);
                
            }else{
                
                getFileName(textFiles[i].getCanonicalPath());
            }
           }
        }
            return fileList;

    }
}

 

这里是和IK Analyzer  结合使用的简单示例

 

posted @ 2015-01-26 14:49  猪哥哥厉害  阅读(985)  评论(0编辑  收藏  举报