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

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

链接地址

个人博客站已经上线了,网址 www.llwjy.com ~欢迎各位吐槽


      在之前的《基于lucene的案例开发:Query查询》这篇博客中对实际开发过程中比较常见的Query做了简单的介绍,这里就介绍下具体的代码实现。查看最新代码点击这里或访问 http://www.llwjy.com/source/com.lulei.lucene.query.PackQuery.html 


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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
1/**  
2 *@Description:  创建查询Query  
3 */
4package com.lulei.lucene.query;  
5
6import java.io.IOException;
7import java.io.StringReader;
8import java.util.ArrayList;
9
10import org.apache.lucene.analysis.Analyzer;
11import org.apache.lucene.analysis.TokenStream;
12import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
13import org.apache.lucene.index.Term;
14import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
15import org.apache.lucene.queryparser.classic.ParseException;
16import org.apache.lucene.queryparser.classic.QueryParser;
17import org.apache.lucene.search.BooleanClause.Occur;
18import org.apache.lucene.search.BooleanQuery;
19import org.apache.lucene.search.NumericRangeQuery;
20import org.apache.lucene.search.PhraseQuery;
21import org.apache.lucene.search.PrefixQuery;
22import org.apache.lucene.search.Query;
23import org.apache.lucene.search.TermQuery;
24import org.apache.lucene.search.TermRangeQuery;
25import org.apache.lucene.search.WildcardQuery;
26import org.apache.lucene.util.Version;
27
28import com.lulei.lucene.index.manager.IndexManager;
29
30
31public class PackQuery {
32  //分词器
33  private Analyzer analyzer;
34  //使用索引中的分词器
35  public PackQuery(String indexName) {
36      analyzer = IndexManager.getIndexManager(indexName).getAnalyzer();
37  }
38  //使用自定义分词器
39  public PackQuery(Analyzer analyzer) {
40      this.analyzer = analyzer;
41  }
42
43  /**
44   * @param key
45   * @param fields
46   * @return Query
47   * @throws ParseException
48   * @Author: lulei  
49   * @Description: 查询字符串匹配多个查询域
50   */
51  public Query getMultiFieldQuery(String key, String[] fields) throws ParseException{
52      MultiFieldQueryParser parse = new MultiFieldQueryParser(Version.LUCENE_43, fields, analyzer);
53      Query query = null;
54      query = parse.parse(key);
55      return query;
56  }
57 
58  /**
59   * @param key
60   * @param field
61   * @return Query
62   * @throws ParseException
63   * @Author: lulei  
64   * @Description: 查询字符串匹配单个查询域
65   */
66  public Query getOneFieldQuery(String key, String field) throws ParseException{
67      if (key == null || key.length() < 1){
68          return null;
69      }
70      QueryParser parse = new QueryParser(Version.LUCENE_43, field, analyzer);
71      Query query = null;
72      query = parse.parse(key);
73      return query;
74  }
75 
76  /**
77   * @param key
78   * @param fields
79   * @param occur
80   * @return Query
81   * @throws IOException
82   * @Author: lulei  
83   * @Description: 查询字符串、多个查询域以及查询域在查询语句中的关系
84   */
85  public Query getBooleanQuery(String key, String[] fields, Occur[] occur) throws IOException{
86      if (fields.length != occur.length){
87          System.out.println("fields.length isn't equals occur.length, please check params!");
88          return null;
89      }
90      BooleanQuery query = new BooleanQuery();
91      TokenStream tokenStream = analyzer.tokenStream("", new StringReader(key));
92      ArrayList<String> analyzerKeys = new ArrayList<String>();
93      while(tokenStream.incrementToken()){
94          CharTermAttribute term = tokenStream.getAttribute(CharTermAttribute.class);
95          analyzerKeys.add(term.toString());
96      }
97      for(int i = 0; i < fields.length; i++){
98          BooleanQuery queryField = new BooleanQuery();
99          for(String analyzerKey : analyzerKeys){
100             TermQuery termQuery = new TermQuery(new Term(fields[i], analyzerKey));
101             queryField.add(termQuery, Occur.SHOULD);
102         }
103         query.add(queryField, occur[i]);
104     }
105     return query;
106 }
107
108 /**
109  * @param querys
110  * @param occur
111  * @return Query
112  * @Author: lulei  
113  * @Description: 组合多个查询,之间的关系由occur确定
114  */
115 public Query getBooleanQuery(ArrayList<Query> querys, ArrayList<Occur> occurs){
116     if (querys.size() != occurs.size()){
117         System.out.println("querys.size() isn't equals occurs.size(), please check params!");
118         return null;
119     }
120     BooleanQuery query = new BooleanQuery();
121     for (int i = 0; i < querys.size(); i++){
122         query.add(querys.get(i), occurs.get(i));
123     }
124     return query;
125 }
126
127 /**
128  * @param fieldName
129  * @param value
130  * @return
131  * @Author: lulei  
132  * @Description: StringField属性的搜索
133  */
134 public Query getStringFieldQuery(String value, String fieldName){
135     Query query = null;
136     query = new TermQuery(new Term(fieldName, value));
137     return query;
138 }
139
140 /**
141  * @param fields
142  * @param values
143  * @return
144  * @Author: lulei  
145  * @Description: 多个StringField属性的搜索
146  */
147 public Query getStringFieldQuery(String[] values, String[] fields, Occur occur){
148     if (fields == null || values == null || fields.length != values.length){
149         return null;
150     }
151     ArrayList<Query> querys = new ArrayList<Query>();
152     ArrayList<Occur> occurs = new ArrayList<Occur>();
153     for (int i = 0; i < fields.length; i++){
154         querys.add(getStringFieldQuery(values[i], fields[i]));
155         occurs.add(occur);
156     }
157     return getBooleanQuery(querys, occurs);
158 }
159
160 /**
161  * @param key
162  * @param field
163  * @param lucene43
164  * @return
165  * @throws ParseException
166  * @Author: lulei  
167  * @Description: 查询字符串和单个查询域 QueryParser是否使用4.3
168  */
169 public Query getOneFieldQuery(String key, String field, boolean lucene43) throws ParseException{
170     if (key == null || key.length() < 1){
171         return null;
172     }
173     if (lucene43){
174         return getOneFieldQuery(key, field);
175     }
176     @SuppressWarnings("deprecation")
177     QueryParser parse = new QueryParser(Version.LUCENE_30, field, analyzer);
178     Query query = null;
179     query = parse.parse(key);
180     return query;
181 }
182
183 /**
184  * @param key
185  * @param field
186  * @Author: lulei  
187  * @Description: key开头的查询字符串,和单个域匹配
188  */
189 public Query getStartQuery(String key, String field) {
190     if (key == null || key.length() < 1){
191         return null;
192     }
193     Query query = new PrefixQuery(new Term(field, key));
194     return  query;
195 }
196
197 /**
198  * @param key
199  * @param fields
200  * @param occur
201  * @Author: lulei  
202  * @Description: key开头的查询字符串,和多个域匹配,每个域之间的关系由occur确定
203  */
204 public Query getStartQuery(String key, String []fields, Occur occur){
205     if (key == null || key.length() < 1){
206         return null;
207     }
208     ArrayList<Query> querys = new ArrayList<Query>();
209     ArrayList<Occur> occurs = new ArrayList<Occur>();
210     for (String field : fields) {
211         querys.add(getStartQuery(key, field));
212         occurs.add(occur);
213     }
214     return getBooleanQuery(querys, occurs);
215 }
216
217 /**
218  * @param key
219  * @param fields
220  * @Author: lulei  
221  * @Description: key开头的查询字符串,和多个域匹配,每个域之间的关系Occur.SHOULD
222  */
223 public Query getStartQuery(String key, String []fields) {
224     return getStartQuery(key, fields, Occur.SHOULD);
225 }
226
227 /**
228  * @param key
229  * @param field
230  * @param slop
231  * @return
232  * @Author:lulei  
233  * @Description: 自定每个词元之间的最大距离
234  */
235 public Query getPhraseQuery(String key, String field, int slop) {
236     if (key == null || key.length() < 1){
237         return null;
238     }
239     StringReader reader = new StringReader(key);
240     PhraseQuery query = new PhraseQuery();
241     query.setSlop(slop);
242     try {
243         TokenStream  tokenStream  = this.analyzer.tokenStream(field, reader);
244         tokenStream.reset();
245         CharTermAttribute  term = tokenStream.getAttribute(CharTermAttribute.class);
246         while(tokenStream.incrementToken()){  
247             query.add(new Term(field, term.toString()));
248         }
249         reader.close();
250     } catch (IOException e) {
251         e.printStackTrace();
252         return null;
253     }
254     return query;
255 }
256
257 /**
258  * @param key
259  * @param fields
260  * @param slop
261  * @param occur
262  * @return
263  * @Author:lulei  
264  * @Description: 自定每个词元之间的最大距离,查询多个域,每个域之间的关系由occur确定
265  */
266 public Query getPhraseQuery(String key, String[] fields, int slop, Occur occur) {
267     if (key == null || key.length() < 1){
268         return null;
269     }
270     ArrayList<Query> querys = new ArrayList<Query>();
271     ArrayList<Occur> occurs = new ArrayList<Occur>();
272     for (String field : fields) {
273         querys.add(getPhraseQuery(key, field, slop));
274         occurs.add(occur);
275     }
276     return getBooleanQuery(querys, occurs);
277 }
278
279 /**
280  * @param key
281  * @param fields
282  * @param slop
283  * @return
284  * @Author:lulei  
285  * @Description:  自定每个词元之间的最大距离,查询多个域,每个域之间的关系是Occur.SHOULD
286  */
287 public Query getPhraseQuery(String key, String[] fields, int slop) {
288     return getPhraseQuery(key, fields, slop, Occur.SHOULD);
289 }
290
291 /**
292  * @param key
293  * @param field
294  * @return
295  * @Author:lulei  
296  * @Description: 通配符检索 eg:getWildcardQuery("a*thor", "field")
297  */
298 public Query getWildcardQuery(String key, String field) {
299     if (key == null || key.length() < 1){
300         return null;
301     }
302     return new WildcardQuery(new Term(field, key));
303 }
304
305 /**
306  * @param key
307  * @param fields
308  * @param occur
309  * @return
310  * @Author:lulei  
311  * @Description: 通配符检索,域之间的关系为occur
312  */
313 public Query getWildcardQuery(String key, String[] fields, Occur occur) {
314     if (key == null || key.length() < 1){
315         return null;
316     }
317     ArrayList<Query> querys = new ArrayList<Query>();
318     ArrayList<Occur> occurs = new ArrayList<Occur>();
319     for (String field : fields) {
320         querys.add(getWildcardQuery(key, field));
321         occurs.add(occur);
322     }
323     return getBooleanQuery(querys, occurs);
324 }
325
326 /**
327  * @param key
328  * @param fields
329  * @return
330  * @Author:lulei  
331  * @Description: 通配符检索,域之间的关系为Occur.SHOULD
332  */
333 public Query getWildcardQuery(String key, String[] fields) {
334     return getWildcardQuery(key, fields, Occur.SHOULD);
335 }
336
337 /**
338  * @param keyStart
339  * @param keyEnd
340  * @param field
341  * @param includeStart
342  * @param includeEnd
343  * @return
344  * @Author:lulei  
345  * @Description: 范围搜索
346  */
347 public Query getRangeQuery (String keyStart, String keyEnd, String field, boolean includeStart, boolean includeEnd) {
348     return TermRangeQuery.newStringRange(field, keyStart, keyEnd, includeStart, includeEnd);
349 }
350
351 /**
352  * @param min
353  * @param max
354  * @param field
355  * @param includeMin
356  * @param includeMax
357  * @return
358  * @Author:lulei  
359  * @Description: 范围搜索
360  */
361 public Query getRangeQuery (int min, int max, String field, boolean includeMin, boolean includeMax) {
362     return NumericRangeQuery.newIntRange(field, min, max, includeMin, includeMax);
363 }
364
365 /**
366  * @param min
367  * @param max
368  * @param field
369  * @param includeMin
370  * @param includeMax
371  * @return
372  * @Author:lulei  
373  * @Description: 范围搜索
374  */
375 public Query getRangeQuery (float min, float max, String field, boolean includeMin, boolean includeMax) {
376     return NumericRangeQuery.newFloatRange(field, min, max, includeMin, includeMax);
377 }
378
379 /**
380  * @param min
381  * @param max
382  * @param field
383  * @param includeMin
384  * @param includeMax
385  * @return
386  * @Author:lulei  
387  * @Description: 范围搜索
388  */
389 public Query getRangeQuery (double min, double max, String field, boolean includeMin, boolean includeMax) {
390     return NumericRangeQuery.newDoubleRange(field, min, max, includeMin, includeMax);
391 }
392
393 public static void main(String[] args) throws IOException {
394 }
395}
396

      PackQuery类的构造方法,可以手动指定分词器也可以使用索引的分词器。个人建议,在项目中使用索引中的分词器,这样就不会因为分词器的不同造成不知名的错误。


ps:最近发现其他网站可能会对博客转载,上面并没有源链接,如想查看更多关于 基于lucene的案例开发http://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

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