Lucene查询简述

本示例是对Lucene查询,对结果进行了一些处理(Lucene 3.5):


  1、支持前缀搜索,如*国,可以搜索出中国、美国等国字结尾的词的内容:
        支持后缀匹配,如国* 则可以搜索中国、美国等以国字结尾的词,*:*可以查询所有索引。
  parser.setAllowLeadingWildcard(true);

  2、搜索时在有通配符时可以不区分大小写:

  // 有通配符时不转换大小写
  parser.setLowercaseExpandedTerms(false);

  3、结果进行多字段排序,详细见代码排序部分;

  4、结果高亮显示,详细见代码高亮部分。


  1. package cn.test.gxg.engine.query;   
  2.    
  3. import java.io.File;   
  4. import java.io.IOException;   
  5. import java.io.StringReader;   
  6.    
  7. import org.apache.lucene.analysis.Analyzer;   
  8. import org.apache.lucene.analysis.TokenStream;   
  9. import org.apache.lucene.analysis.standard.StandardAnalyzer;   
  10. import org.apache.lucene.document.Document;   
  11. import org.apache.lucene.document.Field;   
  12. import org.apache.lucene.document.Fieldable;   
  13. import org.apache.lucene.document.NumericField;   
  14. import org.apache.lucene.document.Field.Store;   
  15. import org.apache.lucene.index.CorruptIndexException;   
  16. import org.apache.lucene.index.IndexReader;   
  17. import org.apache.lucene.index.IndexWriter;   
  18. import org.apache.lucene.queryParser.ParseException;   
  19. import org.apache.lucene.queryParser.QueryParser;   
  20. import org.apache.lucene.search.IndexSearcher;   
  21. import org.apache.lucene.search.Query;   
  22. import org.apache.lucene.search.ScoreDoc;   
  23. import org.apache.lucene.search.Searcher;   
  24. import org.apache.lucene.search.Sort;   
  25. import org.apache.lucene.search.SortField;   
  26. import org.apache.lucene.search.TopDocs;   
  27. import org.apache.lucene.search.highlight.Highlighter;   
  28. import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;   
  29. import org.apache.lucene.search.highlight.QueryScorer;   
  30. import org.apache.lucene.search.highlight.SimpleFragmenter;   
  31. import org.apache.lucene.search.highlight.SimpleHTMLFormatter;   
  32. import org.apache.lucene.store.FSDirectory;   
  33. import org.apache.lucene.store.LockObtainFailedException;   
  34. import org.apache.lucene.util.Version;   
  35.    
  36. /**   
  37.  * 创建索引并查询示例   
  38.  *   
  39.  * @createTime: Feb 22, 2010 3:02:28 PM   
  40.  * @author:  <a href="mailto:leader1212@sina.com.cn">天涯 </a>   
  41.  * @version: 0.1   
  42.  * @lastVersion: 0.1   
  43.  * @updateTime:   
  44.  * @updateAuthor:  <a href="mailto:leader1212@sina.com.cn">天涯 </a>   
  45.  * @changesSum:   
  46.  *    
  47.  */   
  48. public class QueryTest {   
  49.     public static void main(String[] args) {   
  50.         //索引目录   D:\workspace\code\java\TestLucene3\index\txt\test   
  51.         String INDNEX_PATH = "D:\\workspace\\code\\java\\TestLucene3\\index\\txt\\test";   
  52.         createIndex(INDNEX_PATH);   
  53.         search(INDNEX_PATH);   
  54.     }   
  55.        
  56.     public static void createIndex (String indexPath) {   
  57.         // 获取中文分词器,查询的时候也要用一样的分词器。不然会导致查询结果不准确   
  58.         Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);   
  59.         // 建立索引   
  60.         IndexWriter writer;   
  61.         NumericField nField = null;   
  62.         try {   
  63.             writer = new IndexWriter(FSDirectory.open(new File(indexPath)),   
  64.                     analyzer, true, IndexWriter.MaxFieldLength.LIMITED);   
  65.    
  66.             Document doc = new Document();   
  67.             Field field = null;   
  68.             for(int i =0; i  <10; i++) {   
  69.                 doc = new Document();   
  70.                 field = new Field("Code", "feinnocdb_App_info"+i, Field.Store.YES,   
  71.                         Field.Index.ANALYZED);   
  72.                 doc.add(field);   
  73.                 nField = new NumericField("Id", Store.YES, true).setIntValue(i%3);   
  74.                 doc.add(nField);   
  75.                 field = new Field("Name", "国家名字-" + i, Field.Store.YES,   
  76.                         Field.Index.ANALYZED);   
  77.                 doc.add(nField);   
  78.                 field = new Field("Content", "中国中华人民共和国—" + i, Field.Store.YES,   
  79.                         Field.Index.ANALYZED);   
  80.                 doc.add(field);   
  81.                 nField = new NumericField("Type", Store.YES, true).setIntValue((i%10));   
  82.                 doc.add(nField);   
  83.                 nField = new NumericField("Price", Store.YES, true).setFloatValue((i%3));   
  84.                 doc.add(nField);   
  85.                 nField = new NumericField("Sex", Store.YES, true).setIntValue((i%2));   
  86.                 doc.add(nField);   
  87.                 writer.addDocument(doc);   
  88.             }   
  89.             writer.close();   
  90.             System.out.println("Indexed success!");   
  91.         } catch (Exception e) {   
  92.             e.printStackTrace();   
  93.         }   
  94.     }   
  95.        
  96.     public static void search(String indexPath) {   
  97.         //获取Lucene标准分词器,可以使用其他分词器,前提是创建索引的时候也使用相同的分词器         
  98.         Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);   
  99.         //建立索引         
  100.         try {   
  101.             IndexReader reader = IndexReader.open(FSDirectory.open(new File(indexPath)));   
  102.             QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "Content", analyzer);   
  103.             Query query = null;   
  104.             String q = "Content:国";   
  105.             try {   
  106.                 query = parser.parse(q);   
  107.                 // 支持后缀匹配,如*国 则可以搜索中国、美国等以国字结尾的词,*:*可以查询所有索引。   
  108.                 parser.setAllowLeadingWildcard(true);   
  109.                 // 有通配符时不转换大小写   
  110.                 parser.setLowercaseExpandedTerms(false);   
  111.             } catch (ParseException e) {   
  112.                 e.printStackTrace();   
  113.             }   
  114.                
  115.             // 多字段排序,设置在前面的会优先排序   
  116.             SortField[] sortFields = new SortField[2];   
  117.             SortField sortField = new SortField("Id", SortField.INT, true);   
  118.             SortField FIELD_SEX = new SortField("Sex", SortField.INT, false);   
  119.             sortFields[0] = sortField;   
  120.             sortFields[1] = FIELD_SEX;   
  121.             Sort sort = new Sort(sortFields);   
  122.             // 单字段排序   
  123.             /*   
  124.             SortField sortField = new SortField("Id", SortField.INT, true);   
  125.             Sort sort = new Sort(sortField);   
  126.              */   
  127.                
  128.             Searcher searcher = new IndexSearcher(reader);   
  129.             // 如果不需要排序则使用注释掉的代码查询   
  130.                        // TopDocs topDocs = searcher.search(query, 100);   
  131.             TopDocs topDocs = searcher.search(query, null, 1000, sort);   
  132.                
  133.             System.out.println("查询语句为:" + query.toString());   
  134.             System.out.println("查询到数据条数为:" + topDocs.totalHits);   
  135.             if (topDocs.totalHits != 0) {   
  136.                 // 用作高亮显示的Query语句。绝大多数情况都是使用查询的Query语句。   
  137.                 // 这里为了演示,所以不那样做   
  138.                 Query hilightQuery = null;   
  139.                 try {   
  140.                     hilightQuery = parser.parse("Content:中");   
  141.                 } catch (ParseException e) {   
  142.                     // TODO Auto-generated catch block   
  143.                     e.printStackTrace();   
  144.                 }   
  145.                    
  146.                 // 设置需要高亮的字段值   
  147.                 String[] highlightCol = {"Content", "Name"};   
  148.                 Highlighter highlighter = null;   
  149.                 // 关键字高亮显示设置   
  150.                 // 设定高亮显示的格式,也就是对高亮显示的词组加上前缀后缀     
  151.                 SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter(" <FONT COLOR='RED'>", " </FONT>");   
  152.                 highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(hilightQuery));   
  153.                    
  154.                 //设置每次返回的字符数   
  155.                 highlighter.setTextFragmenter(new SimpleFragmenter(1000));    
  156.                    
  157.                     // 遍历查询的索引,得到具体索引值。   
  158.                 for(ScoreDoc sd : topDocs.scoreDocs) {   
  159.                     Document document = searcher.doc(sd.doc);   
  160.                     for (Fieldable fa : document.getFields()) {   
  161.                         String value = document.get(fa.name());   
  162.                         for (String col : highlightCol) {   
  163.                             if(fa.name().equals(col)) {   
  164.                                 //设置高显内容   
  165.                                 TokenStream tokenStream = analyzer.tokenStream("Content",new StringReader(value));    
  166.                                 value = highlighter.getBestFragment(tokenStream, value);   
  167.                             }   
  168.                         }   
  169.                         System.out.print(fa.name() + ":" + value + "  ");   
  170.                     }   
  171.                     System.out.println();   
  172.                 }   
  173.             }   
  174.             reader.close();   
  175.         } catch (CorruptIndexException e) {   
  176.             // TODO Auto-generated catch block         
  177.             e.printStackTrace();   
  178.         } catch (LockObtainFailedException e) {   
  179.             // TODO Auto-generated catch block         
  180.             e.printStackTrace();   
  181.         } catch (IOException e) {   
  182.             // TODO Auto-generated catch block         
  183.             e.printStackTrace();   
  184.         } catch (InvalidTokenOffsetsException e) {   
  185.             // TODO Auto-generated catch block   
  186.             e.printStackTrace();   
  187.         }   
  188.     }   
  189. }   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值