Lucene入门,小例子,笔记

最近在研究Lucene的用法,经过这两天的努力,在网上搜索资料,还专门买了本书《开发自己的搜索引擎---Lucene+Heritrix》打算系统 的学习一下这东西,大的项目是肯定离不开搜索引擎的,学吧,没错~ 这两天有过无助、有过失落、也有过新发现时的欣喜若狂,总之最后还是做出了个小例子,怕以后再忘记,还是记录一下吧~也记录自己的成长,只有把学到的东西 讲给别人,才算是真的会了,此例子也献给那些正在搜索Lucene资料的朋友们吧~愿对你们有所帮助~

    好了先贴代码吧!

主类:TestIndex.java

Java代码   收藏代码
  1. package com.lj.test;  
  2.   
  3. import java.io.StringReader;  
  4. import java.util.ArrayList;  
  5. import java.util.Date;  
  6. import java.util.List;  
  7.   
  8. import net.paoding.analysis.analyzer.PaodingAnalyzer;  
  9.   
  10. import org.apache.lucene.analysis.Analyzer;  
  11. import org.apache.lucene.analysis.TokenStream;  
  12. import org.apache.lucene.document.Document;  
  13. import org.apache.lucene.document.Field;  
  14. import org.apache.lucene.index.IndexWriter;  
  15. import org.apache.lucene.index.IndexWriter.MaxFieldLength;  
  16. import org.apache.lucene.queryParser.MultiFieldQueryParser;  
  17. import org.apache.lucene.search.BooleanClause;  
  18. import org.apache.lucene.search.Filter;  
  19. import org.apache.lucene.search.IndexSearcher;  
  20. import org.apache.lucene.search.Query;  
  21. import org.apache.lucene.search.ScoreDoc;  
  22. import org.apache.lucene.search.TopDocs;  
  23. import org.apache.lucene.search.highlight.Highlighter;  
  24. import org.apache.lucene.search.highlight.QueryScorer;  
  25. import org.apache.lucene.search.highlight.SimpleFragmenter;  
  26. import org.apache.lucene.search.highlight.SimpleHTMLFormatter;  
  27.   
  28. import com.lj.entity.Product;  
  29. import com.lj.util.Configuration;  
  30.   
  31. /** 
  32.  * Lucene初级小例子,简单测试。 
  33.  * @author LiangJian 
  34.  * 2011-6-17 11:56:14 
  35.  */  
  36. public class TestIndex {  
  37.      
  38.     /** 创建Lucene索引 */  
  39.     public void createIndex(String indexPath,List<Product> productList) throws Exception{  
  40.         //记录开始时间  
  41.         long startTime = new Date().getTime();  
  42.         /** 建立索引,使用庖丁中文分词器PaodingAnalyzer。*/  
  43.         IndexWriter indexWriter = new IndexWriter(indexPath, new PaodingAnalyzer(), true, MaxFieldLength.LIMITED);  
  44.         /** 
  45.          * 说明: 
  46.         * Field.TermVector.NO:不保存term vectors 
  47.           Field.TermVector.YES:保存term vectors 
  48.           Field.TermVector.WITH_POSITIONS:保存term vectors.(保存值和token位置信息) 
  49.           Field.TermVector.WITH_OFFSETS:保存term vectors.(保存值和Token的offset) 
  50.           Field.TermVector.WITH_POSITIONS_OFFSETS:保存term vectors.(保存值和token位置信息和Token的offset) 
  51.         */  
  52.         for(Product product:productList){  
  53.             Document doc = new Document();  
  54.             doc.add(new Field("p_id",product.getP_id()+"",Field.Store.YES,Field.Index.NO));  
  55.             doc.add(new Field("p_name",product.getP_name(),Field.Store.YES,Field.Index.ANALYZED));  
  56.             doc.add(new Field("p_price",product.getP_price(),Field.Store.YES,Field.Index.NO));  
  57.             doc.add(new Field("p_content",product.getP_content(),Field.Store.YES,Field.Index.ANALYZED));  
  58.             indexWriter.addDocument(doc);  
  59.         }  
  60.         // optimize()方法是对索引进行优化,进行了索引优化后,索引才算是真正的生效。  
  61.         indexWriter.optimize();  
  62.         indexWriter.close();  
  63.         // 测试一下索引的时间  
  64.         long endTime = new Date().getTime();  
  65.         System.out.println("这花费了 " + (endTime - startTime)+ "毫秒来把数据增加到索引里面去!");  
  66.     }  
  67.      
  68.     /** 
  69.      * 按Content字段查询 
  70.      * @param indexPath 索引文件路径 
  71.      * @param keyword 关键字 
  72.      * @return 
  73.      * @throws Exception 
  74.      */  
  75.     public List<Product> searchByKeyWord(String indexPath,String keyword)throws Exception{  
  76.         List<Product> productList = new ArrayList<Product>();  
  77.         IndexSearcher search = new IndexSearcher(indexPath);  
  78.          
  79.         long startTime = new Date().getTime();  
  80.          
  81.         //下面的是进行p_content和p_name 范围内进行搜索.  
  82.         String[] keywords = new String[]{"p_content","p_name"};//要检索的字段  
  83.         /** 这里需要注意的就是BooleanClause.Occur[]数组,它表示多个条件之间的关系, 
  84.          * BooleanClause.Occur.MUST表示and, 
  85.          * BooleanClause.Occur.MUST_NOT表示not, 
  86.          * BooleanClause.Occur.SHOULD表示or.  
  87.          * */  
  88.         BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD};//对应要检索的字段的逻辑(与、或)  
  89.         Analyzer analyzer = new PaodingAnalyzer();//使用庖丁分词,按分词进行检索  
  90.         //用MultiFieldQueryParser得到query对象  
  91.         Query query = MultiFieldQueryParser.parse(keyword, keywords, clauses, analyzer);//parser.parse(query);  
  92.         Filter filter = null;//过滤  
  93.         //开始匹配  
  94.         TopDocs topDocs = search.search(query, filter, 1000);  
  95.         System.out.println("共匹配到:"+topDocs.totalHits+"个.");  
  96.          
  97.         for(ScoreDoc scorceDoc : topDocs.scoreDocs){  
  98.             Document doc = search.doc(scorceDoc.doc);  
  99. //            System.out.println(scorceDoc.doc+"---"+doc);//便于学习,可以打印出来看看。  
  100.             Product product = new Product();  
  101.             product.setP_id(Integer.parseInt(doc.get("p_id")));  
  102.             product.setP_name(doc.get("p_name"));  
  103.             product.setP_price(doc.get("p_price"));  
  104. //            product.setP_content(doc.get("p_content"));//不使用高亮  
  105.             product.setP_content(this.getHighLight(doc, analyzer, query, "p_content"));//使用高亮  
  106.             productList.add(product);  
  107.         }  
  108.         search.close();  
  109.         long endTime = new Date().getTime();  
  110.         System.out.println("检索耗时: " + (endTime - startTime)+ "毫秒!");  
  111.         return productList;  
  112.     }  
  113.      
  114.     /** 
  115.      * 高亮设置 
  116.      * @param doc 
  117.      * @param analyzer 分词器 
  118.      * @param query 
  119.      * @param field 字段 
  120.      * @throws Exception 
  121.      * @reutrn 高亮后的值 
  122.      */  
  123.     public String getHighLight(Document doc,Analyzer analyzer,Query query,String field)throws Exception{  
  124.         //设置高亮显示格式  
  125. //        SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'><strong>", "</strong></font>");  
  126.         SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<b>""</b>");  
  127.         /* 语法高亮显示设置 */  
  128.         Highlighter highlighter = new Highlighter(simpleHTMLFormatter,new QueryScorer(query));  
  129.         highlighter.setTextFragmenter(new SimpleFragmenter(100));  
  130.         // 取 field 字段值,准备进行高亮  
  131.         String fieldValue = doc.get(field);  
  132.         TokenStream tokenStream = analyzer.tokenStream(field,new StringReader(fieldValue));  
  133.         //转成高亮的值  
  134.         String highLightFieldValue = highlighter.getBestFragment(tokenStream, fieldValue);  
  135.         if(highLightFieldValue == null)  
  136.             highLightFieldValue = fieldValue;  
  137.         return highLightFieldValue;  
  138.     }  
  139.   
  140.     /** 创建测试数据 */  
  141.     public List<Product> createProductList(){  
  142.         List<Product> productList = new ArrayList<Product>();  
  143.         for(int i=1;i<=20;i++){  
  144.             Product product = new Product();  
  145.             product.setP_id(i);  
  146.             product.setP_name("手表"+i);  
  147.             product.setP_price((i*i+Math.random())+"元");  
  148.             product.setP_content("手表的描述"+i+"块");  
  149.             productList.add(product);  
  150.         }  
  151.         return productList;  
  152.     }  
  153.   
  154.     /** 
  155.      * 测试主方法 
  156.      * @param args 
  157.      * @throws Exception 
  158.      */  
  159.     public static void main(String[] args) throws Exception {  
  160.         TestIndex test = new TestIndex();  
  161.         String indexPath = Configuration.getInstance().read("config.properties""indexPath");  
  162.         //创建Lucene索引  
  163.         test.createIndex(indexPath+"Product/index", test.createProductList());  
  164.          
  165.         //从Lucene索引库中——搜索  
  166.         List<Product> productList = test.searchByKeyWord(indexPath+"Product/index""手表4 描述3");  
  167.         //搜索结果  
  168.         for(Product product:productList){  
  169.             System.out.println("---------------");  
  170.             System.out.println("p_id:"+product.getP_id());  
  171.             System.out.println("p_name:"+product.getP_name());  
  172.             System.out.println("p_price:"+product.getP_price());  
  173.             System.out.println("p_content:"+product.getP_content());  
  174.             System.out.println("---------------");  
  175.         }  
  176.          
  177.     }  
  178.   
  179. }  

 读取配置文件类:Configuration.java

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

 配置文件:config.properties

Java代码   收藏代码
  1. #配置索引路径  
  2. indexPath=d:/LuceneIndex/LuceneTest02/  

 

Lucene入门,小例子,笔记_第1张图片

 

运行结果:

这花费了 1672毫秒来把数据增加到索引里面去!
共匹配到:2个.
检索耗时: 109毫秒!
---------------
p_id:4
p_name:手表4
p_price:16.29956430691176元
p_content:<b>手表</b>的<b>描述</b><b>4</b>块
---------------
---------------
p_id:3
p_name:手表3
p_price:9.465650388124237元
p_content:<b>手表</b>的<b>描述</b><b>3</b>块
---------------

 

你需要导入几个Jar文件:

lucene-core-2.4.1.jar(Lucene核心包)

lucene-highlighter-2.4.0.jar(用于高亮显示的)

commons-logging.jar

paoding-analysis.jar(到网上搜索paoding-analysis-2.0.4-beta,解压后把Jar拷贝过来就OK,把dic文件夹拷贝到工程的根目录下,或者配置PAODING_DIC_HOME环境变量到bic目录下)

  • Lucene小例子-梁健.rar (964.9 KB)
  • 下载次数: 401

你可能感兴趣的:(Lucene入门,小例子,笔记)