个人博客小站搭建成功,网址 www.llwjy.com,欢迎大家来吐槽~
在前面的博客中,我们已经介绍了IndexSearcher中的检索方法,也介绍了如何基于lucene中的NRT*类去创建实时索引,在这篇博客中我们就重点介绍下基于实时索引的检索方案。在开始介绍之前,我们首先定一下检索结果的数据结构(这样做的好处是无论是什么检索,得到的数据结构都是一样的,方便以后的处理~)
原来我长这样
检索结果的数据结构主要包括两个字段,如下:
1
2
3 1private int count;
2private List<Document> datas;
3
这两个字段分别代表着该检索条件下的符合条件的记录条数和本次查询到的记录数组(该记录是索引中的记录),因此检索结果类源代码如下:
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 1/**
2 * @Description: 索引搜索结果数据结构
3 */
4package com.lulei.lucene.index.model;
5
6import java.util.List;
7
8import org.apache.lucene.document.Document;
9
10public class SearchResultBean {
11 private int count;
12 private List<Document> datas;
13
14 public int getCount() {
15 return count;
16 }
17 public void setCount(int count) {
18 this.count = count;
19 }
20 public List<Document> getDatas() {
21 return datas;
22 }
23 public void setDatas(List<Document> datas) {
24 this.datas = datas;
25 }
26}
27
1
2 1 **检索原来如此简单**
2
检索结果介绍完了,下面就看下如何基于上次博客中的实时索引去检索数据,不知还记得上篇博客中封装的getIndexSearcher()方法(如果忘记了,看下该系列的前一篇博客),这个方法提供了当前最新可用的IndexSearcher对象,索引我们再去检索的时候,直接调用该方法即可。IndexManager类实现了另类的单例模式,使用了索引名来标识IndexManager,因此我们在写检索基类的时候,需要添加一个构造方法,如下:
1
2
3
4 1public NRTSearch(String indexName) {
2 indexManager = IndexManager.getIndexManager(indexName);
3}
4
1
2 1 在NRTSearch类中,我们主要封装4个方法:
2
1
2
3
4
5 11.public int getIndexNum(){}
22.public SearchResultBean search(Query query, int start, int end){}
33.public SearchResultBean search(Query query, int start, int end, Sort sort){}
44.public SearchResultBean search(int start, int count){}
5
1
2 1 在四个方法分别实现:
2
1.获取索引中的记录条数;
2.根据query查询索引,根据相关读排序,返回[start, end)记录;
3.根据query查询索引,根据指定sort排序,返回[start, end)记录;
4:从索引中的第start条开始,获取后面的count条记录(如果start + count 大于索引中的记录总条数,则从头补齐)。
这四个方法已经可以实现了80%的站内搜索功能,如果还有其他复杂的,可以根据实际情况来拓展,NRTSearch类源代码如下:
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 1/**
2 * @Description: 索引的查询操作
3 */
4package com.lulei.lucene.index.operation;
5
6import java.util.ArrayList;
7import java.util.List;
8
9import org.apache.lucene.document.Document;
10import org.apache.lucene.search.IndexSearcher;
11import org.apache.lucene.search.Query;
12import org.apache.lucene.search.Sort;
13import org.apache.lucene.search.TopDocs;
14
15import com.lulei.lucene.index.manager.IndexManager;
16import com.lulei.lucene.index.model.SearchResultBean;
17
18public class NRTSearch {
19 private IndexManager indexManager;
20
21 /**
22 * @param indexName 索引名
23 */
24 public NRTSearch(String indexName) {
25 indexManager = IndexManager.getIndexManager(indexName);
26 }
27
28 /**
29 * @return
30 * @Author:lulei
31 * @Description: 索引中的记录数量
32 */
33 public int getIndexNum() {
34 return indexManager.getIndexNum();
35 }
36
37 /**
38 * @param query 查询字符串
39 * @param start 起始位置
40 * @param end 结束位置
41 * @author lulei
42 * @return 查询结果
43 */
44 public SearchResultBean search(Query query, int start, int end) {
45 start = start < 0 ? 0 : start;
46 end = end < 0 ? 0 : end;
47 if (indexManager == null || query == null || start >= end) {
48 return null;
49 }
50 SearchResultBean result = new SearchResultBean();
51 List<Document> datas = new ArrayList<Document>();
52 result.setDatas(datas);
53 IndexSearcher searcher = indexManager.getIndexSearcher();
54 try {
55 TopDocs docs = searcher.search(query, end);
56 result.setCount(docs.totalHits);
57 end = end > docs.totalHits ? docs.totalHits : end;
58 for (int i = start; i < end; i++) {
59 datas.add(searcher.doc(docs.scoreDocs[i].doc));
60 }
61 } catch (Exception e) {
62 e.printStackTrace();
63 } finally {
64 indexManager.release(searcher);
65 }
66 return result;
67 }
68
69 /**
70 * @param query 查询字符串
71 * @param start 起始位置
72 * @param end 结束位置
73 * @param sort 排序条件
74 * @return 查询结果
75 */
76 public SearchResultBean search(Query query, int start, int end, Sort sort) {
77 start = start < 0 ? 0 : start;
78 end = end < 0 ? 0 : end;
79 if (indexManager == null || query == null || start >= end) {
80 return null;
81 }
82 SearchResultBean result = new SearchResultBean();
83 List<Document> datas = new ArrayList<Document>();
84 result.setDatas(datas);
85 IndexSearcher searcher = indexManager.getIndexSearcher();
86 try {
87 TopDocs docs = searcher.search(query, end, sort);
88 result.setCount(docs.totalHits);
89 end = end > docs.totalHits ? docs.totalHits : end;
90 for (int i = start; i < end; i++) {
91 datas.add(searcher.doc(docs.scoreDocs[i].doc));
92 }
93 } catch (Exception e) {
94 e.printStackTrace();
95 } finally {
96 indexManager.release(searcher);
97 }
98 return result;
99 }
100
101 /**
102 * @param start
103 * @param count
104 * @return
105 * @Author:lulei
106 * @Description: 按序号检索
107 */
108 public SearchResultBean search(int start, int count) {
109 start = start < 0 ? 0 : start;
110 count = count < 0 ? 0 : count;
111 if (indexManager == null) {
112 return null;
113 }
114 SearchResultBean result = new SearchResultBean();
115 List<Document> datas = new ArrayList<Document>();
116 result.setDatas(datas);
117 IndexSearcher searcher = indexManager.getIndexSearcher();
118 result.setCount(count);
119 try {
120 for (int i = 0; i < count; i++) {
121 datas.add(searcher.doc((start + i) % getIndexNum()));
122 }
123 } catch (Exception e) {
124 e.printStackTrace();
125 } finally {
126 indexManager.release(searcher);
127 }
128 return result;
129 }
130}
131
1
2 1 到这里为止,NRTSearch类就介绍完毕了,之后就可以根据实际的应用来创建子类,实现一系列的查询操作,如:关键字检索、分类检索、标签检索、作者检索等等,在之后的应用中在继续介绍。
2
ps:最近发现其他网站可能会对博客转载,上面并没有源链接,如想查看更多关于 基于lucene的案例开发 请http://www.aiuxian.com/catalog/p-322798.html。或访问网址http://blog.csdn.net/xiaojimanman/article/category/2841877 或 http://www.llwjy.com/