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配置如下所示:
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>
创建一个实体类,如下所示:
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),连续范围查找(相当于<,>)。
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 存储的目录,即可打开索引文件,显示出索引的具体内容。
简单使用如下所示:
查找自己添加的信息如下所示:
作者:别先生
博客园:https://www.cnblogs.com/biehongli/
CSDN:https://blog.csdn.net/Biexiansheng
如果您想及时得到个人撰写文章以及著作的消息推送,可以扫描上方二维码,关注个人公众号哦。