Lucene的全文檢索學習

Lucene的官方網站(Apache的頂級項目):http://lucene.apache.org/html

 一、什麼是Lucene?java

  Lucene 是 apache 軟件基金會的一個子項目,由 Doug Cutting 開發,是一個開放源代碼的全文檢索引擎工具包,但它不是一個完整的全文檢索引擎,而是一個全文檢索引擎的庫,提供了完整的查詢引擎和索引引擎,部分文本分析引擎。Lucene 的目的是爲軟件開發人員提供一個簡單易用的工具包,以方便的在目標系統中實現全文檢索的功能,或者是以此爲基礎創建起完整的全文檢索引擎。Lucene 是一套用於全文檢索和搜尋的開源程式庫,由 Apache 軟件基金會支持和提供。git

  Lucene 提供了一個簡單卻強大的應用程式接口,可以作全文索引和搜尋。在 Java 開發環境裏 Lucene 是一個成熟的免費開源工具。就其自己而言,Lucene 是當前以及最近幾年最受歡迎的免費 Java 信息檢索程序庫。人們常常提到信息檢索程序庫,雖然與搜索引擎有關,但不該該將信息檢索程序庫與搜索引擎相混淆。github

  ElasticSearch存在本身的生態系統,ELK,E是指ElasticSearch即全文檢索,L是指Logstash即數據採集,K是指Kibana即報表。數據庫

  ElasticSearch是基於Lucene的分佈式全文檢索系統,能夠認爲是一個分佈式的NoSql數據庫,並且支持全文檢索。apache

  Lucene是一個單機版程序,Es是一個集羣版,底層使用的是Lucene,提供更方便的操做API。
注意:數據庫和全文檢索的區別。
  a、數據庫使用的是模糊查詢。
  b、全文檢索能夠快速,準確找到你想要的數據,快是指先從索引庫中查找,準是指對查詢條件進行分詞,而後對查詢的結果進行相關度排序,得分越高,排的越靠前。
api

二、創建索引的過程,是先進行分詞,創建索引,將文檔存儲的信息與索引進行關聯。查詢的過程,就是先到索引庫中查找,而後查找出對應的文檔ID,而後根據文檔ID去文檔庫中查詢出真正的文檔。 maven

項目使用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>

建立一個實體類,以下所示:ide

  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.dicstopword.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 }

效果以下所示:

三、Luke 查看索引。

  索引建立完成之後生成了如上的一批特殊格式的文件,若是直接用工具打開,會顯示的都是亂碼。可使用索引查看工具 Luke 來查看。
  Luke 是開源工具,代碼託管在 GitHub 上,項目地址:https://github.com/DmitryKey/luke/releases,下載後解壓,進入 luke 目錄,若是是在Windows平臺,運行 luke.bat (雙擊打開,需稍等片刻,使用的Java的圖形化製做的工具,略慢)便可啓動軟件,並在 Path 中輸入 index 存儲的目錄,便可打開索引文件,顯示出索引的具體內容。

簡單使用以下所示:

查找本身添加的信息以下所示:

做者:別先生

博客園:https://www.cnblogs.com/biehongli/

若是您想及時獲得我的撰寫文章以及著做的消息推送,能夠掃描上方二維碼,關注我的公衆號哦。

相關文章
相關標籤/搜索