分享

基于lucene的案例开发7:Query查询

本帖最后由 nettman 于 2015-4-16 22:41 编辑
问题导读

1.Query子类有哪些?
2.QueryParser与MultiFieldQueryParser有什么不同?
3.哪个类用于通配符搜索?
4.如何实现基于lucene的Query查询?




接上篇:基于lucene的案例开发6:分词器介绍


在Lucene索引的搜索过程中,构建Query对象是一个十分重要的过程。对于Query的理解,可以把它想象成数据库SQL查询语句中的where条件(当然Query的功能要比sql强大很多),在这篇博客中,我们将重点介绍几种常用的Query子类:QueryParser、 MultiFieldQueryParser、TermQuery 、PrefixQuery、 PhraseQuery、 WildcardQuery、 TermRangeQuery、 NumericRangeQuery、 BooleanQuery。


      这篇博客稍微和前面的排版不同,先分别对几个类做简单介绍,然后在给出具体的demo程序,如若对其中的某些介绍不理解,可以先阅读后面的demo程序再看前面的介绍。


QueryParser
      QueryParser主要用于对单个域搜索时创建查询query,QueryParser的构造方法需指定具体的域名和分词方法,lucene不同版本,创建的Query对象会略有不同,具体不同还请参照博客:关于QueryParser类前后修改

MultiFieldQueryParser
      MultiFieldQueryParser可以想象成QueryParser的升级版,QueryParser主要用于单个域的搜索,而MultiFieldQueryParser则用于多个域的搜索,其构造方法和具体使用和QueryParser类似。

TermQuery
      TermQuery重要对一个Term(最小的索引块,包含一个field名和值),TermQuery可以用于对关键字域查询时Query的创建,比如分类、文档唯一ID等。

PrefixQuery
      PrefixQuery前缀查询字符串的构建,其效果和“abc*”这种通配符使用WildcardQuery构建Query类似;PrefixQuery只需要前缀指定的若干个字符相同即可,如PrefixQuery(new Term("", "lu")),将会匹配lucene、luke等。

PhraseQuery
      PhraseQuery短语搜索,它可以指定关键词之间的最大距离,如下面demo程序中,指定了“基于”“案例”这两个词之间最大的距离为2,一旦文档中,这两个词的具体大于2就不满足条件。

WildcardQuery
      WildcardQuery通配符搜索,可以想象是PrefixQuery的升级版,WildcardQuery提供了更细的控制和更大的灵活行,lucene中有* ? 这两个通配符,*表示匹配任意多个字符,?表示匹配一个任意字符。如lu*e可以和lucene、luke匹配;lu?e可以和luke匹配,但和lucene却不匹配。

TermRangeQuery
      TermRangeQuery字符串范围搜索,在创建时一般有5个参数分别是 域名、域下限值、域上限值、是否包括下限、是否包括上限,这个和下面的NumericRangeQuery的参数含义相同。

NumericRangeQuery
      NumericRangeQuery数字范围搜索,它针对不同的数据类型(int、float、double),提供的不同的方法,参数含义参照TermRangeQuery。

BooleanQuery
      上面介绍的Query子类几乎都是针对单个域或多个域单个关键字的,那多个域不同关键字有该如何处理?多个Query对象又如何组成一个Query对象?这些BooleanQuery都可以实现,BooleanQuery可以嵌套非常复杂的查询,其和布尔运算类似,提供与(Occur.MUST)、或(Occur.SHOULD)、非(Occur.MUST_NOT)三种逻辑关系。


      当然lucene中提供的Query子类还有很多,这里就只简单的介绍了几种比较常用的,剩下的如在以后的实际项目中遇到再做介绍学习。

Query测试demo
  1. /**   
  2. *@Description:     Query学习demo
  3. */   
  4. package com.lulei.lucene.study;   
  5.   
  6. import org.apache.lucene.analysis.Analyzer;  
  7. import org.apache.lucene.analysis.standard.StandardAnalyzer;  
  8. import org.apache.lucene.index.Term;  
  9. import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;  
  10. import org.apache.lucene.queryparser.classic.QueryParser;  
  11. import org.apache.lucene.search.BooleanClause.Occur;  
  12. import org.apache.lucene.search.BooleanQuery;  
  13. import org.apache.lucene.search.NumericRangeQuery;  
  14. import org.apache.lucene.search.PhraseQuery;  
  15. import org.apache.lucene.search.PrefixQuery;  
  16. import org.apache.lucene.search.Query;  
  17. import org.apache.lucene.search.TermQuery;  
  18. import org.apache.lucene.search.TermRangeQuery;  
  19. import org.apache.lucene.search.WildcardQuery;  
  20. import org.apache.lucene.util.Version;  
  21.    
  22. public class QueryStudy {  
  23.   
  24.     public static void main(String[] args) throws Exception {  
  25.         //Query过程中使用的分词器  
  26.         Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_43);  
  27.         //搜索词  
  28.         String keyValue = "基于lucene的案例开发";  
  29. //      keyValue = "基于lucene的案例开发 更多内容请访问:http://blog.csdn.net/xiaojimanman/article/category/2841877";  
  30.         //将搜索词进行下转义,如果搜索词中没有lucene中的特殊字符,可以不进行转义  
  31.         String key = LuceneKey.escapeLuceneKey(keyValue);  
  32.         //单个搜索域  
  33.         String field = "content";  
  34.         //多个搜索域  
  35.         String []fields = {"name" , "content"};  
  36.         Query query = null;  
  37.          
  38.         //对单个域构建查询语句  
  39.         QueryParser parse = new QueryParser(Version.LUCENE_43, field, analyzer);  
  40.         query = parse.parse(key);   
  41.         System.out.println(QueryParser.class);  
  42.         System.out.println(query.toString());  
  43.         System.out.println("--------------------------------");  
  44.          
  45.         //对多个域创建查询语句  
  46.         MultiFieldQueryParser parse1 = new MultiFieldQueryParser(Version.LUCENE_43, fields, analyzer);  
  47.         query = parse1.parse(key);  
  48.         System.out.println(MultiFieldQueryParser.class);  
  49.         System.out.println(query.toString());  
  50.         System.out.println("--------------------------------");  
  51.          
  52.         //词条搜索  
  53.         query = new TermQuery(new Term(field, key));  
  54.         System.out.println(query.getClass());  
  55.         System.out.println(query.toString());  
  56.         System.out.println("--------------------------------");  
  57.          
  58.         //前缀搜索  
  59.         query = new PrefixQuery(new Term(field, key));  
  60.         System.out.println(query.getClass());  
  61.         System.out.println(query.toString());  
  62.         System.out.println("--------------------------------");  
  63.          
  64.         //短语搜索  
  65.         PhraseQuery query1 = new PhraseQuery();  
  66.         //设置短语间允许的最大间隔  
  67.         query1.setSlop(2);  
  68.         query1.add(new Term("content", "基于"));  
  69.         query1.add(new Term("content", "案例"));  
  70.         System.out.println(query1.getClass());  
  71.         System.out.println(query1.toString());  
  72.         System.out.println("--------------------------------");  
  73.          
  74.         //通配符搜索  
  75.         query = new WildcardQuery(new Term(field, "基于?"));  
  76.         System.out.println(query.getClass());  
  77.         System.out.println(query.toString());  
  78.         System.out.println("--------------------------------");  
  79.          
  80.         //字符串范围搜索  
  81.         query = TermRangeQuery.newStringRange(field, "abc", "azz", true, false);  
  82.         System.out.println(query.getClass());  
  83.         System.out.println(query.toString());  
  84.          
  85.         //int范围搜索  
  86.         query = NumericRangeQuery.newIntRange("star", 0, 3, false, false);  
  87.         System.out.println(query.getClass() + "\tint");  
  88.         System.out.println(query.toString());  
  89.          
  90.         //float范围搜索  
  91.         query = NumericRangeQuery.newFloatRange("star", 0.0f, 3.0f, false, false);  
  92.         System.out.println(query.getClass() + "\tfloat");  
  93.         System.out.println(query.toString());  
  94.          
  95.         //double范围搜索  
  96.         query = NumericRangeQuery.newDoubleRange("star", 0.0, 3d, false, false);  
  97.         System.out.println(query.getClass() + "\tdouble");  
  98.         System.out.println(query.toString());  
  99.         System.out.println("--------------------------------");  
  100.          
  101.         //BooleanQuery  
  102.         BooleanQuery query2 = new BooleanQuery();  
  103.         query2.add(new TermQuery(new Term("content", "基于")), Occur.SHOULD);  
  104.         query2.add(new TermQuery(new Term("name", "lucene")), Occur.MUST);  
  105.         query2.add(new TermQuery(new Term("star", "3")), Occur.MUST_NOT);  
  106.         System.out.println(query2.getClass());  
  107.         System.out.println(query2.toString());  
  108.         System.out.println("--------------------------------");  
  109.     }  
  110. }  
复制代码

      上述demo程序的运行截图如下:


20150121155558356.png


      关于上述Query的意思以及查询索引得到的结果,这里就不再做介绍,如对其感兴趣可以自己按照前面的几篇博客,创建对应索引文件以及编写搜索程序。



相关内容:
基于lucene的案例开发1:lucene初始认知

基于lucene的案例开发2:索引数学模型

基于lucene的案例开发3:索引文件结构

基于lucene的案例开发4:创建索引

基于lucene的案例开发5:搜索索引

基于lucene的案例开发6:分词器介绍

基于lucene的案例开发7:Query查询

基于lucene的案例开发8:IndexSearcher中检索方法

基于lucene的案例开发9:案例初识

基于lucene的案例开发10:搜索后台基础,JsonUtil & XmlUtil类介绍

基于lucene的案例开发11:项目常用类ClassUtil & CharsetUtil介绍

基于lucene的案例开发12:数据库连接池

基于lucene的案例开发13:实现实时索引基本原理

基于lucene的案例开发14:实时索引管理类IndexManager

基于lucene的案例开发15:实时索引的检索

基于lucene的案例开发16:实时索引的修改

基于lucene的案例开发17:查询语句创建PackQuery

基于lucene的案例开发18:纵横小说更新列表页抓取

基于lucene的案例开发19:纵横小说简介页采集

基于lucene的案例开发20:纵横小说章节列表采集

基于lucene的案例开发21:纵横小说阅读页采集


出处: http://blog.csdn.net/xiaojimanman/article/details/42969443

已有(3)人评论

跳转到指定楼层
LeucotheaShi 发表于 2015-4-9 10:34:38
大谢楼主~大谢楼主~大谢楼主~大谢楼主~
回复

使用道具 举报

zhujun182104906 发表于 2015-4-10 15:47:22
回复

使用道具 举报

漂泊一剑客 发表于 2015-6-14 23:32:43
谢谢楼主的整理,辛苦了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条