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

释放双眼,带上耳机,听听看~!

转载请注明出处: http://www.aiuxian.com/article/p-2078379.html

      在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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
1/**  
2 *@Description:     Query学习demo
3 */
4package com.lulei.lucene.study;  
5
6import org.apache.lucene.analysis.Analyzer;
7import org.apache.lucene.analysis.standard.StandardAnalyzer;
8import org.apache.lucene.index.Term;
9import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
10import org.apache.lucene.queryparser.classic.QueryParser;
11import org.apache.lucene.search.BooleanClause.Occur;
12import org.apache.lucene.search.BooleanQuery;
13import org.apache.lucene.search.NumericRangeQuery;
14import org.apache.lucene.search.PhraseQuery;
15import org.apache.lucene.search.PrefixQuery;
16import org.apache.lucene.search.Query;
17import org.apache.lucene.search.TermQuery;
18import org.apache.lucene.search.TermRangeQuery;
19import org.apache.lucene.search.WildcardQuery;
20import org.apache.lucene.util.Version;
21  
22public 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}
111

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

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

ps:最近发现其他网站可能会对博客转载,上面并没有源链接,如想查看更多关于 http://www.aiuxian.com/catalog/p-322798.htmlhttp://www.aiuxian.com/catalog/p-322798.html。或访问网址http://blog.csdn.net/xiaojimanman/article/category/2841877

给TA打赏
共{{data.count}}人
人已打赏
安全运维

OpenSSH-8.7p1离线升级修复安全漏洞

2021-10-23 10:13:25

安全运维

设计模式的设计原则

2021-12-12 17:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索