Lucene的全文检索学习

2019-10-13 21:20:01 浏览数 (1)

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 存储的目录,即可打开索引文件,显示出索引的具体内容。

简单使用如下所示:

查找自己添加的信息如下所示:

作者:别先生

0 人点赞