Lucene的官方网站(Apache的顶级项目):http://lucene.apache.org/
1、什么是Lucene?
Lucene 是 apache 软件基金会的一个子项目,由 Doug Cutting 开发,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的库,提供了完整的查询引擎和索引引擎,部分文本分析引擎。Lucene 的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene 是一套用于全文检索和搜寻的开源程式库,由 Apache 软件基金会支持和提供。
Lucene 提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在 Java 开发环境里 Lucene 是一个成熟的免费开源工具。就其本身而言,Lucene 是当前以及最近几年最受欢迎的免费 Java 信息检索程序库。人们经常提到信息检索程序库,虽然与搜索引擎有关,但不应该将信息检索程序库与搜索引擎相混淆。
ElasticSearch存在自己的生态系统,ELK,E是指ElasticSearch即全文检索,L是指Logstash即数据采集,K是指Kibana即报表。
ElasticSearch是基于Lucene的分布式全文检索系统,可以认为是一个分布式的NoSql数据库,而且支持全文检索。
Lucene是一个单机版程序,Es是一个集群版,底层使用的是Lucene,提供更方便的操作API。 注意:数据库和全文检索的区别。 a、数据库使用的是模糊查询。 b、全文检索可以快速,准确找到你想要的数据,快是指先从索引库中查找,准是指对查询条件进行分词,然后对查询的结果进行相关度排序,得分越高,排的越靠前。
2、建立索引的过程,是先进行分词,建立索引,将文档存储的信息与索引进行关联。查询的过程,就是先到索引库中查找,然后查找出对应的文档ID,然后根据文档ID去文档库中查询出真正的文档。
项目使用maven创建,所以引入所需的依赖包。pom.xml配置如下所示:
代码语言:javascript复制 1 <project xmlns="http://maven.apache.org/POM/4.0.0"
2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
4 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <modelVersion>4.0.0</modelVersion>
6 <groupId>com.bie</groupId>
7 <artifactId>luceneDemo</artifactId>
8 <version>0.0.1-SNAPSHOT</version>
9
10 <!-- 定义一下常量 -->
11 <properties>
12 <maven.compiler.source>1.8</maven.compiler.source>
13 <maven.compiler.target>1.8</maven.compiler.target>
14 <encoding>UTF-8</encoding>
15 </properties>
16
17 <dependencies>
18 <dependency>
19 <groupId>org.apache.httpcomponents</groupId>
20 <artifactId>httpclient</artifactId>
21 <version>4.5.2</version>
22 </dependency>
23 <dependency>
24 <groupId>org.apache.logging.log4j</groupId>
25 <artifactId>log4j-api</artifactId>
26 <version>2.3</version>
27 </dependency>
28 <dependency>
29 <groupId>commons-logging</groupId>
30 <artifactId>commons-logging</artifactId>
31 <version>1.2</version>
32 </dependency>
33 <dependency>
34 <groupId>org.slf4j</groupId>
35 <artifactId>slf4j-log4j12</artifactId>
36 <version>1.7.25</version>
37 <scope>test</scope>
38 </dependency>
39 <!-- lucene的核心 -->
40 <dependency>
41 <groupId>org.apache.lucene</groupId>
42 <artifactId>lucene-core</artifactId>
43 <version>6.6.0</version>
44 </dependency>
45 <!-- lucene的分词器,有标准的英文相关的分词器,没有中文的 -->
46 <dependency>
47 <groupId>org.apache.lucene</groupId>
48 <artifactId>lucene-analyzers-common</artifactId>
49 <version>6.6.0</version>
50 </dependency>
51 <!-- 查询解析器 -->
52 <dependency>
53 <groupId>org.apache.lucene</groupId>
54 <artifactId>lucene-queryparser</artifactId>
55 <version>6.6.0</version>
56 </dependency>
57 <!-- 各种查询方式 -->
58 <dependency>
59 <groupId>org.apache.lucene</groupId>
60 <artifactId>lucene-queries</artifactId>
61 <version>6.6.0</version>
62 </dependency>
63 <!-- 关键字高亮 -->
64 <dependency>
65 <groupId>org.apache.lucene</groupId>
66 <artifactId>lucene-highlighter</artifactId>
67 <version>6.6.0</version>
68 </dependency>
69 <dependency>
70 <groupId>org.apache.lucene</groupId>
71 <artifactId>lucene-demo</artifactId>
72 <version>6.6.0</version>
73 </dependency>
74 <dependency>
75 <groupId>junit</groupId>
76 <artifactId>junit</artifactId>
77 <version>4.12</version>
78 </dependency>
79 <dependency>
80 <groupId>log4j</groupId>
81 <artifactId>log4j</artifactId>
82 <version>1.2.17</version>
83 </dependency>
84 <dependency>
85 <groupId>org.slf4j</groupId>
86 <artifactId>slf4j-api</artifactId>
87 <version>1.7.22</version>
88 </dependency>
89 </dependencies>
90
91 </project>
创建一个实体类,如下所示:
代码语言:javascript复制 1 package com.bie.pojo;
2
3 import org.apache.lucene.document.Document;
4 import org.apache.lucene.document.Field.Store;
5 import org.apache.lucene.document.LongPoint;
6 import org.apache.lucene.document.StoredField;
7 import org.apache.lucene.document.StringField;
8 import org.apache.lucene.document.TextField;
9
10 /**
11 *
12 * @author biehl
13 *
14 */
15 public class Article {
16
17 private Long id;
18
19 private String title;
20
21 private String content;
22
23 private String author;
24
25 private String url;
26
27 public Article() {
28 }
29
30 public Article(Long id, String title, String content, String author, String url) {
31 super();
32 this.id = id;
33 this.title = title;
34 this.content = content;
35 this.author = author;
36 this.url = url;
37 }
38
39 public Long getId() {
40 return id;
41 }
42
43 public void setId(Long id) {
44 this.id = id;
45 }
46
47 public String getTitle() {
48 return title;
49 }
50
51 public void setTitle(String title) {
52 this.title = title;
53 }
54
55 public String getContent() {
56 return content;
57 }
58
59 public void setContent(String content) {
60 this.content = content;
61 }
62
63 public String getAuthor() {
64 return author;
65 }
66
67 public void setAuthor(String author) {
68 this.author = author;
69 }
70
71 public String getUrl() {
72 return url;
73 }
74
75 public void setUrl(String url) {
76 this.url = url;
77 }
78
79 public Document toDocument() {
80 // Lucene存储的格式(Map装的k,v)。
81 Document doc = new Document();
82 // 向文档中添加一个long类型的属性,建立索引。LongPoint不分词,建立索引。
83 doc.add(new LongPoint("id", id));
84 // 在文档中存储。
85 doc.add(new StoredField("id", id));
86
87 // 设置一个文本类型,会对内容进行分词,建立索引,并将内容在文档中存储。
88 doc.add(new TextField("title", title, Store.YES));
89 // 设置一个文本类型,会对内容进行分词,建立索引,存在文档中存储 / No代表不存储。
90 doc.add(new TextField("content", content, Store.YES));
91
92 // StringField,不分词,建立索引,Store.YES文档中存储。
93 doc.add(new StringField("author", author, Store.YES));
94
95 // StoredField不分词,不建立索引,在文档中存储。
96 doc.add(new StoredField("url", url));
97 return doc;
98 }
99
100 public static Article parseArticle(Document doc) {
101 Long id = Long.parseLong(doc.get("id"));
102 String title = doc.get("title");
103 String content = doc.get("content");
104 String author = doc.get("author");
105 String url = doc.get("url");
106 Article article = new Article(id, title, content, author, url);
107 return article;
108 }
109
110 @Override
111 public String toString() {
112 return "id : " id " , title : " title " , content : " content " , author : " author " , url : "
113 url;
114 }
115
116 }
搭建的项目结构如下所示,由于使用了中文分词器,所以需要引入别人写好的依赖(原始作者很久不更新了,这个是github上面下载使用的),你可以打成jar包依赖进去也可以的,和配置文件,引入即可,不然项目无法正常启动。
IKAnalyzer.cfg.xml配置文件引入ext.dic、stopword.dic配置文件。
ext.dic配置文件是扩展词库,可以写入自己的词条。
stopword.dic配置文件是停用词库(不和谐的词条可以被停用掉的),可以写入停用的词条。
main2012.dic配置文件是标准的词典。里面是默认配置好的,不可以进行更改的。
然后就是你的主类了,主要包含,添加索引和文档,查询索引和文档,删除索引和文档,更新索引和文档(即先删除后插入),多字段查询索引和文档,全字段内查询索引和文档,组合查询,布尔查询索引和文档,非连续范围查找索引(相当于in or),连续范围查找(相当于<,>)。
代码语言:javascript复制 1 package com.bie.lucene;
2
3 import java.io.IOException;
4 import java.nio.file.Paths;
5
6 import org.apache.lucene.analysis.Analyzer;
7 import org.apache.lucene.analysis.standard.StandardAnalyzer;
8 import org.apache.lucene.document.Document;
9 import org.apache.lucene.document.LongPoint;
10 import org.apache.lucene.index.DirectoryReader;
11 import org.apache.lucene.index.IndexWriter;
12 import org.apache.lucene.index.IndexWriterConfig;
13 import org.apache.lucene.index.Term;
14 import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
15 import org.apache.lucene.queryparser.classic.ParseException;
16 import org.apache.lucene.queryparser.classic.QueryParser;
17 import org.apache.lucene.search.BooleanClause;
18 import org.apache.lucene.search.BooleanQuery;
19 import org.apache.lucene.search.IndexSearcher;
20 import org.apache.lucene.search.MatchAllDocsQuery;
21 import org.apache.lucene.search.Query;
22 import org.apache.lucene.search.ScoreDoc;
23 import org.apache.lucene.search.TermQuery;
24 import org.apache.lucene.search.TopDocs;
25 import org.apache.lucene.store.FSDirectory;
26 import org.junit.Test;
27 import org.wltea.analyzer.lucene.IKAnalyzer;
28
29 import com.bie.pojo.Article;
30
31 /**
32 *
33 * @author biehl
34 *
35 */
36 public class LuceneDemo {
37
38 /**
39 * 往用lucene写入数据
40 *
41 * @throws IOException
42 */
43 @Test
44 public void luceneCreate() throws IOException {
45 // 创建几个文章对象
46 Article article = new Article();
47 article.setId(1008611L);
48 article.setAuthor("别先生");
49 article.setTitle("学习Lucene");
50 article.setContent("好好学习,争取早日成为Java高级工程师,加油!别先生");
51 article.setUrl("https://www.cnblogs.com/biehongli/p/11637267.html");
52
53 Article article2 = new Article();
54 article2.setId(1008612L);
55 article2.setAuthor("别先生");
56 article2.setTitle("学习Lucene");
57 article2.setContent("好好学习,争取早日成为Java初级工程师,加油!别先生");
58 article2.setUrl("https://www.cnblogs.com/biehongli/p/11637267.html");
59
60 Article article3 = new Article();
61 article3.setId(1008615L);
62 article3.setAuthor("别先生");
63 article3.setTitle("学习Lucene");
64 article3.setContent("好好学习,争取早日成为Java中级工程师,加油!别先生");
65 article3.setUrl("https://www.cnblogs.com/biehongli/p/11637267.html");
66
67 // 指定数据写入到文件夹
68 String indexPath = "F:\lucene\index";
69 // 打开指定的文件夹
70 FSDirectory fsDirectory = FSDirectory.open(Paths.get(indexPath));
71 // 创建一个标准分词器StandardAnalyzer,一个字分一次
72 // Analyzer analyzer = new StandardAnalyzer();
73 // IKAnalyzer中文分词器
74 Analyzer analyzer = new IKAnalyzer(true);
75 // 写入索引的配置,设置了分词器
76 IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
77 // 指定了写入数据目录和配置
78 IndexWriter indexWriter = new IndexWriter(fsDirectory, indexWriterConfig);
79 // 创建一个文档对象。Lucene只识别文档格式。
80 Document document = article.toDocument();
81 Document document2 = article2.toDocument();
82 Document document3 = article3.toDocument();
83 // 通过IndexWriter写入
84 indexWriter.addDocument(document);
85 indexWriter.addDocument(document2);
86 indexWriter.addDocument(document3);
87 // 关闭IndexWriter
88 indexWriter.close();
89 }
90
91 @Test
92 public void luceneSearch() throws IOException, ParseException {
93 // 指定要去查询的文件夹
94 String indexPath = "F:\lucene\index";
95 // 中文分词器
96 Analyzer analyzer = new IKAnalyzer(true);
97 // Analyzer analyzer = new IKAnalyzer(true);
98 DirectoryReader directoryReader = DirectoryReader.open(FSDirectory.open(Paths.get(indexPath)));
99 // 索引查询器IndexSearcher
100 IndexSearcher indexSearcher = new IndexSearcher(directoryReader);
101
102 String queryStr = "工程师";
103 // String queryStr = "高级";
104 // 创建一个查询条件解析器QueryParser
105 QueryParser parser = new QueryParser("content", analyzer);
106 // 对查询条件进行解析
107 Query query = parser.parse(queryStr);
108
109 // TermQuery将查询条件当成是一个固定的词
110 // Query query = new TermQuery(new Term("url",
111 // "https://www.cnblogs.com/biehongli/p/11637267.html"));
112 // 在【索引】中进行查找。10代表查询出前10条数据。
113 TopDocs topDocs = indexSearcher.search(query, 10);
114
115 // 获取到查找到的文文档ID和得分
116 ScoreDoc[] scoreDocs = topDocs.scoreDocs;
117 for (ScoreDoc scoreDoc : scoreDocs) {
118 // 从索引中查询到文档的ID。
119 int doc = scoreDoc.doc;
120 // 在根据ID到文档中查找文档内容。
121 Document document = indexSearcher.doc(doc);
122 // 将文档转换成对应的实体类。
123 Article article = Article.parseArticle(document);
124 // 打印输出
125 System.out.println(article);
126 }
127 // 关闭DirectoryReader
128 directoryReader.close();
129 }
130
131 @Test
132 public void luceneDelete() throws IOException, ParseException {
133 // 指定要去删除的文件夹
134 String indexPath = "F:\lucene\index";
135 // 指定中文分词器
136 Analyzer analyzer = new IKAnalyzer(true);
137 // 打开指定的文件夹
138 FSDirectory fsDirectory = FSDirectory.open(Paths.get(indexPath));
139 // 写入索引的配置,设置了分词器
140 IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
141 // 指定了写入数据目录和配置
142 IndexWriter indexWriter = new IndexWriter(fsDirectory, indexWriterConfig);
143
144 // 几种查询删除的使用。
145 // Term词条查找,内容必须完全匹配,不分词。
146 // indexWriter.deleteDocuments(new Term("content", "学好"));
147
148 // 指定查询条件,查询到的进行删除。
149 // QueryParser parser = new QueryParser("title", analyzer);
150 // Query query = parser.parse("高级");
151
152 // LongPoint是建立索引的。在newRangeQuery某个范围内的都进行删除。
153 // Query query = LongPoint.newRangeQuery("id", 1008611L, 1008612L);
154 // LongPoint是建立索引的。支持等值查询。
155 Query query = LongPoint.newExactQuery("id", 1008611L);
156
157 // 删除指定的文档
158 indexWriter.deleteDocuments(query);
159
160 // 提交
161 indexWriter.commit();
162 System.out.println("==================================删除完毕!");
163 // 关闭
164 indexWriter.close();
165 }
166
167 /**
168 * lucene的update比较特殊,update的代价太高,先删除,然后再插入。
169 *
170 * @throws IOException
171 * @throws ParseException
172 */
173 @Test
174 public void luceneUpdate() throws IOException, ParseException {
175 // 指定要去更新的文件夹
176 String indexPath = "F:\lucene\index";
177 // 指定标准的分词器
178 // StandardAnalyzer analyzer = new StandardAnalyzer();
179 // 指定中文分词器
180 Analyzer analyzer = new IKAnalyzer(true);
181 // 打开指定的文件夹
182 FSDirectory fsDirectory = FSDirectory.open(Paths.get(indexPath));
183 // 写入索引的配置,设置了分词器
184 IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
185 // 指定了写入数据目录和配置
186 IndexWriter indexWriter = new IndexWriter(fsDirectory, indexWriterConfig);
187
188 // 指定更新的实体类信息
189 Article article = new Article();
190 article.setId(1008611L);
191 article.setAuthor("别先生");
192 article.setTitle("学习Lucene");
193 article.setContent("好好学习哦,争取早日成为Java高级工程师,加油啦啦!别先生");
194 article.setUrl("https://www.cnblogs.com/biehongli/p/11637267.html");
195 Document document = article.toDocument();
196
197 // 更新文档
198 indexWriter.updateDocument(new Term("author", "别先生"), document);
199
200 // 提交
201 indexWriter.commit();
202 // 关闭
203 indexWriter.close();
204 }
205
206 /**
207 * 可以从多个字段中查找
208 *
209 * @throws IOException
210 * @throws ParseException
211 */
212 @Test
213 public void luceneMultiField() throws IOException, ParseException {
214 // 指定要去查询的文件夹
215 String indexPath = "F:\lucene\index";
216 // IKAnalyzer中文分词器
217 Analyzer analyzer = new IKAnalyzer(true);
218 // 打开指定的文件夹读取信息
219 DirectoryReader directoryReader = DirectoryReader.open(FSDirectory.open(Paths.get(indexPath)));
220 // 索引查询器IndexSearcher
221 IndexSearcher indexSearcher = new IndexSearcher(directoryReader);
222
223 // 指定多字段。可以从多个字段中查找
224 String[] fields = { "title", "content" };
225 // 多字段的查询转换器MultiFieldQueryParser
226 MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields, analyzer);
227 // 对查询条件进行解析
228 Query query = queryParser.parse("别先生");
229
230 // 在【索引】中进行查找。10代表查询出前10条数据。
231 TopDocs topDocs = indexSearcher.search(query, 10);
232 // 获取到查找到的文文档ID和得分
233 ScoreDoc[] scoreDocs = topDocs.scoreDocs;
234 // 遍历查找到的文档ID和得分
235 for (ScoreDoc scoreDoc : scoreDocs) {
236 // 获取到索引ID
237 int doc = scoreDoc.doc;
238 // 根据索引ID去文档里面进行查询即可
239 Document document = indexSearcher.doc(doc);
240 // 将查询到的文档信息转换为实体类,进行输出和业务需求
241 Article article = Article.parseArticle(document);
242 System.out.println(article);
243 }
244
245 // 关闭
246 directoryReader.close();
247 }
248
249 /**
250 * 查找全部的数据
251 *
252 * @throws IOException
253 * @throws ParseException
254 */
255 @Test
256 public void luceneMatchAll() throws IOException, ParseException {
257 // 指定要去查询的文件夹
258 String indexPath = "F:\lucene\index";
259 // 打开指定的文件夹读取信息
260 DirectoryReader directoryReader = DirectoryReader.open(FSDirectory.open(Paths.get(indexPath)));
261 // 索引查询器IndexSearcher
262 IndexSearcher indexSearcher = new IndexSearcher(directoryReader);
263
264 // 查找全部的数据
265 Query query = new MatchAllDocsQuery();
266
267 // 在【索引】中进行查找。10代表查询出前10条数据。
268 TopDocs topDocs = indexSearcher.search(query, 10);
269 // 获取到查找到的文文档ID和得分
270 ScoreDoc[] scoreDocs = topDocs.scoreDocs;
271 // 遍历查找到的文档ID和得分
272 for (ScoreDoc scoreDoc : scoreDocs) {
273 // 获取到索引ID
274 int doc = scoreDoc.doc;
275 // 根据索引ID去文档里面进行查询即可
276 Document document = indexSearcher.doc(doc);
277 // 将查询到的文档信息转换为实体类,进行输出和业务需求
278 Article article = Article.parseArticle(document);
279 System.out.println(article);
280 }
281
282 // 关闭
283 directoryReader.close();
284 }
285
286 /**
287 * 布尔查询,可以组合多个查询条件
288 *
289 * @throws Exception
290 */
291 @Test
292 public void testBooleanQuery() throws Exception {
293 // 指定要去查询的文件夹
294 String indexPath = "F:\lucene\index";
295 // 打开指定的文件夹读取信息
296 DirectoryReader directoryReader = DirectoryReader.open(FSDirectory.open(Paths.get(indexPath)));
297 // 索引查询器IndexSearcher
298 IndexSearcher indexSearcher = new IndexSearcher(directoryReader);
299
300 // 多个查询条件。按照title查询
301 Query query1 = new TermQuery(new Term("author", "别先生"));
302 // 按照content查询
303 Query query2 = new TermQuery(new Term("content", "哈哈哈"));
304 // BooleanClause.Occur.MUST必须满足此条件
305 BooleanClause bc1 = new BooleanClause(query1, BooleanClause.Occur.MUST);
306 // BooleanClause.Occur.MUST_NOT必须不包含此内容。
307 // author:别先生 -content:哈哈哈。 是必须满足,-是不能满足。
308 BooleanClause bc2 = new BooleanClause(query2, BooleanClause.Occur.MUST_NOT);
309 // 相当于and。
310 BooleanQuery boolQuery = new BooleanQuery.Builder().add(bc1).add(bc2).build();
311 System.out.println(boolQuery);
312
313 // 获取到查找到的文文档ID和得分
314 TopDocs topDocs = indexSearcher.search(boolQuery, 10);
315 // 获取到查找到的文文档ID和得分
316 ScoreDoc[] scoreDocs = topDocs.scoreDocs;
317 // 遍历查找到的文档ID和得分
318 for (ScoreDoc scoreDoc : scoreDocs) {
319 // 获取到索引ID
320 int doc = scoreDoc.doc;
321 // 根据索引ID去文档里面进行查询即可
322 Document document = indexSearcher.doc(doc);
323 // 将查询到的文档信息转换为实体类,进行输出和业务需求
324 Article article = Article.parseArticle(document);
325 System.out.println(article);
326 }
327
328 // 关闭
329 directoryReader.close();
330 }
331
332 /**
333 *
334 * @throws Exception
335 */
336 @Test
337 public void luceneQueryParser() throws Exception {
338 // 指定要去查询的文件夹
339 String indexPath = "F:\lucene\index";
340 // 打开指定的文件夹读取信息
341 DirectoryReader directoryReader = DirectoryReader.open(FSDirectory.open(Paths.get(indexPath)));
342 // 索引查询器IndexSearcher
343 IndexSearcher indexSearcher = new IndexSearcher(directoryReader);
344
345 // 创建一个QueryParser对象。参数1:默认搜索域 参数2:分析器对象。
346 QueryParser queryParser = new QueryParser("title", new IKAnalyzer(true));
347
348 // 条件组合
349 // Query query = queryParser.parse("数据");
350 // Query query = queryParser.parse("title:学习 OR title:Lucene");
351 Query query = queryParser.parse("title:学习 AND title:Lucene");
352 System.out.println(query);
353
354 // 在【索引】中进行查找。10代表查询出前10条数据。
355 TopDocs topDocs = indexSearcher.search(query, 10);
356 // 获取到查找到的文文档ID和得分
357 ScoreDoc[] scoreDocs = topDocs.scoreDocs;
358 // 遍历查找到的文档ID和得分
359 for (ScoreDoc scoreDoc : scoreDocs) {
360 // 获取到索引ID
361 int doc = scoreDoc.doc;
362 // 根据索引ID去文档里面进行查询即可
363 Document document = indexSearcher.doc(doc);
364 // 将查询到的文档信息转换为实体类,进行输出和业务需求
365 Article article = Article.parseArticle(document);
366 System.out.println(article);
367 }
368
369 directoryReader.close();
370 }
371
372 /**
373 * 范围查询
374 *
375 * @throws Exception
376 */
377 @Test
378 public void luceneRangeQuery() throws Exception {
379 // 指定要去查询的文件夹
380 String indexPath = "F:\lucene\index";
381 // 打开指定的文件夹读取信息
382 DirectoryReader directoryReader = DirectoryReader.open(FSDirectory.open(Paths.get(indexPath)));
383 // 索引查询器IndexSearcher
384 IndexSearcher indexSearcher = new IndexSearcher(directoryReader);
385
386 // 范围查找,相当于>、<这种范围查询。
387 Query query = LongPoint.newRangeQuery("id", 1008611L, 1008622L);
388
389 System.out.println("================================================" query);
390
391 // 在【索引】中进行查找。10代表查询出前10条数据。
392 TopDocs topDocs = indexSearcher.search(query, 10);
393 // 获取到查找到的文文档ID和得分
394 ScoreDoc[] scoreDocs = topDocs.scoreDocs;
395 // 遍历查找到的文档ID和得分
396 for (ScoreDoc scoreDoc : scoreDocs) {
397 // 获取到索引ID
398 int doc = scoreDoc.doc;
399 // 根据索引ID去文档里面进行查询即可
400 Document document = indexSearcher.doc(doc);
401 // 将查询到的文档信息转换为实体类,进行输出和业务需求
402 Article article = Article.parseArticle(document);
403 System.out.println(article);
404 }
405 // 关闭
406 directoryReader.close();
407 }
408
409 }
效果如下所示:
3、Luke 查看索引。
索引创建完成以后生成了如上的一批特殊格式的文件,如果直接用工具打开,会显示的都是乱码。可以使用索引查看工具 Luke 来查看。 Luke 是开源工具,代码托管在 GitHub 上,项目地址:https://github.com/DmitryKey/luke/releases,下载后解压,进入 luke 目录,如果是在Windows平台,运行 luke.bat (双击打开,需稍等片刻,使用的Java的图形化制作的工具,略慢)即可启动软件,并在 Path 中输入 index 存储的目录,即可打开索引文件,显示出索引的具体内容。
简单使用如下所示:
查找自己添加的信息如下所示:
作者:别先生