Lucene3.6实现全文检索的小例子

引入jar包:

lucene-analyzers-3.6.1.jar
lucene-core-3.6.1.jar
lucene-highlighter-3.6.1.jar (高亮效果)

首先,将需要检索的数据用内定的方式创建索引,(这里创建索引保存在硬盘)

1、新建一个config.properties
#路径
indexPath=C:/lucene-doc

2、建一个Configuration类:

  1. import java.io.IOException;   
  2. import java.io.InputStream;   
  3. import java.util.Properties;   
  4.   
  5. public class Configuration {   
  6.      
  7.     //采用单例模式   
  8.     private static final Configuration configuration = new Configuration();   
  9.   
  10.     private Configuration(){}   
  11.      
  12.     public synchronized static Configuration getInstance(){   
  13.         return configuration;   
  14.     }   
  15.      
  16.     public String read(String properties,String key){   
  17.         //读取配置文件   
  18.         InputStream in = this.getClass().getClassLoader().getResourceAsStream(properties);   
  19.         Properties p = new Properties();   
  20.         try {   
  21.             p.load(in);   
  22.         } catch (IOException e) {   
  23.             e.printStackTrace();   
  24.         }   
  25.          
  26.         //取得配置文件中的值   
  27.         return p.getProperty(key);   
  28.     }   
  29. }  

3、创建索引:

  1. /**  
  2.   * 创建索引  
  3.   */  
  4. public String createSearch() throws Exception {   
  5.   System.out.println("开始创建索引。。。");   
  6.   long stime = new Date().getTime();   
  7.   String indexPath = Configuration.getInstance().read("config.properties""indexPath");    
  8.   Directory dir = FSDirectory.open(new File(indexPath));   
  9.   Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);   
  10.   IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_36, analyzer);   
  11.   iwc.setOpenMode(OpenMode.CREATE); //即创建新索引文件OpenMode.CREATE_OR_APPEND表示创建或追加到已有索引文件   
  12.   IndexWriter writer = new IndexWriter(dir, iwc);   
  13.     
  14.   //需要建立 索引的数据   
  15.   List<User> users = userService.getAll(); //从数据库获取数据   
  16.     
  17.   for(User u : users){   
  18.    Document doc = new Document();   
  19.    // int 要转换 String   
  20.    doc.add(new Field("id",String.valueOf(u.getId()), Field.Store.YES, Field.Index.ANALYZED));   
  21.    doc.add(new Field("username",u.getUsername(), Field.Store.YES, Field.Index.ANALYZED));   
  22.   
  23.    writer.addDocument(doc);    
  24.   }   
  25.   writer.close();   
  26.   long endTime = new Date().getTime();    
  27.   System.out.println("这花费了 " + (endTime - stime)+ "毫秒来把数据增加到索引"+indexPath+"里面去!");    
  28.   return SUCCESS;   
  29. }  

结果如下:

开始创建索引。。。
这花费了 1285毫秒来把数据增加到索引C:/lucene-doc里面去!

4、根据关键字,检索:

  1. /**  
  2.   * 从Lucene索引库中——搜索  
  3.   */  
  4. public String searchKeyword() throws Exception {   
  5.   System.out.println("开始检索。。。");   
  6.   long startTime = new Date().getTime();   
  7.   String indexPath = Configuration.getInstance().read("config.properties""indexPath");    
  8.   users = new ArrayList<User>();   
  9.     
  10.   IndexReader reader = IndexReader.open(FSDirectory.open(new File(indexPath)));   
  11.   IndexSearcher searcher = new IndexSearcher(reader);   
  12.   Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);   
  13.   String field = "username";//设置一个默认的field,因为在用户没有指定field时,lucene会在默认的field中检索   
  14.   QueryParser parser = new QueryParser(Version.LUCENE_36, field, analyzer);   
  15.   Query query = parser.parse(keyword); //搜索关键词   
  16.   searcher.search(query, null100);   
  17.   TopDocs results = searcher.search(query, 10); //只取排名前10的搜索结果   
  18.   ScoreDoc[] hits = results.scoreDocs;   
  19.   Document doc = null;   
  20.   for(ScoreDoc scorceDoc : hits){     
  21.       doc = searcher.doc(scorceDoc.doc);   
  22.    User u = new User();   
  23.    u.setId(Integer.parseInt(doc.get("id")));   
  24. //   u.setUsername(doc.get("username")); //不高亮   
  25.    u.setUsername(this.getHighLight(doc, analyzer, query, "username"));//使用高亮    
  26.    users.add(u);   
  27.   }   
  28.   searcher.close();   
  29.   reader.close();   
  30.   long endTime = new Date().getTime();    
  31.   System.out.println("检索花费了 " + (endTime - startTime)+ "毫秒来把数据从"+indexPath+"里面检索出来!");   
  32.   for(User u : users){   
  33.    System.out.println("以下是检索结果:"+u.getUsername()+"---"+u.getId());   
  34.   
  35.   }   
  36.   return SUCCESS;   
  37. }   

5、高亮方法

  1. public String getHighLight(Document doc,Analyzer analyzer,Query query,String field)throws Exception{    
  2.   //设置高亮显示格式    
  3.   SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'><strong>""</strong></font>");    
  4.   /* 语法高亮显示设置 */    
  5.   Highlighter highlighter = new Highlighter(simpleHTMLFormatter,new QueryScorer(query));    
  6.   highlighter.setTextFragmenter(new SimpleFragmenter(100));    
  7.   // 取 field 字段值,准备进行高亮    
  8.   String fieldValue = doc.get(field);    
  9.   TokenStream tokenStream = analyzer.tokenStream(field,new StringReader(fieldValue));    
  10.   //转成高亮的值    
  11.   String highLightFieldValue = highlighter.getBestFragment(tokenStream, fieldValue);    
  12.   if(highLightFieldValue == null)    
  13.          highLightFieldValue = fieldValue;    
  14.    return highLightFieldValue;    
  15. }  

 

PS:还有几个全局变量:

private String keyword;
private List<User> users;

  1. da shang
    donate-alipay
               donate-weixin weixinpay

发表评论↓↓