lucene是一個基於Java的全文檢索庫,使用lucene能夠建立全文索引和搜尋,當資料量比較大的時候,比起傳統的順序搜尋,索引搜尋速度提升會非常明顯。很多搜尋引擎例如Elasticsearch 和 solor 都是以lucene為核心的。
全文檢索指的是,提前對文章或者文件中的每一個詞建立索引,索引中包含該詞在文章中出現的位置和次數,當使用者查詢時,根據事先建立好的索引進行查詢,並返回查詢結果。
這種建立索引,在透過搜尋索引返回資料的方式就叫全文檢索。
優點:
- 查詢準確高。
- 查詢速度快,不會隨著資料量的增大而變得越來越慢。
缺點:
- 索引會佔據磁碟儲存空間
應用場景:
- 大量資料檢索(貼吧,論壇,淘寶,京東)
- 搜尋引擎 (google、baidu)
Lucene是Apache旗下的一個開源全文檢索引擎庫,提供了完整了查詢引擎和索引引擎。使用lucene可以在系統中實現全文檢索功能,或者以此為基礎構建一個全文檢索引擎。
Lucene不是現成的搜尋引擎產品,但確可以用來製作搜尋引擎產品。
假如要為資料庫中的資料庫建立全文檢索,大致的步驟如下:先獲取到資料庫中的資料庫,對這批資料建立索引,索引儲存在索引庫中。當使用者查詢時,對索引庫的索引進行查詢,從而找到相對應的資料。
重點在於建立索引的這部分。建立索引時需要將資料構建為Lucene中的 文件物件,並對文件物件進行分析,最後建立索引
程式碼步驟如下:
1.建立索引:
- 獲取資料
- 建立Document文件物件()
- 建立分詞器
- 建立Directory物件,宣告索引庫儲存位置
- 建立IndexWriterConfig配置資訊類
- 建立IndexWriter寫入物件
- 把Document寫入到索引庫中(底層自動建立索引)
- 關閉寫入流
POJO類省略–
Dao層省略–
pom.xml 中引入依賴:
<!--lucene核心-->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>7.7.2</version>
</dependency>
<!--lucene分詞器-->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>7.7.2</version>
</dependency>
<!--lucene查詢解析-->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>7.7.2</version>
</dependency>
<!--中文分詞器-->
<dependency>
<groupId>org.wltea.ik-analyzer</groupId>
<artifactId>ik-analyzer</artifactId>
<version>8.1.0</version>
</dependency>
測試類
建立索引:
/*###
建立索引:
* 獲取資料
* 建立Document文件物件()
* 建立分詞器
* 建立Directory物件,宣告索引庫儲存位置
* 建立IndexWriterConfig配置資訊類
* 建立IndexWriter寫入物件
* 把Document寫入到索引庫中(底層自動建立索引)
*/
//建立全部索引
@Test
public void createIndex() throws IOException {
//獲取原始資料
List<YxStoreProduct> skuList = yxStoreProductRepository.findAll();
//建立分詞器
Analyzer analyzerIK = new IKAnalyzer();
//建立文件物件集合
List<Document> documents =new ArrayList<>();
for (YxStoreProduct sku : skuList) {
Document document = new Document();
document.add(new StringField("id",sku.getId().toString(), Field.Store.YES));
document.add(new TextField("store_name",sku.getStoreName(), Field.Store.YES));
document.add(new TextField("storeInfo",sku.getStoreInfo(), Field.Store.YES));
document.add(new TextField("price",sku.getPrice().toString(), Field.Store.YES));
documents.add(document);
}
Directory directory = FSDirectory.open(Paths.get("D:\\lucene\\indexDir"));
Directory directory2 = FSDirectory.open(Paths.get(msgIndex));
//建立IndexWriterConfig物件,寫入索引需要的配置
IndexWriterConfig config = new IndexWriterConfig(analyzerIK);
//建立IndexWriter寫入物件
IndexWriter indexWriter = new IndexWriter(directory2,config);
indexWriter.addDocuments(documents);
indexWriter.close();
}
搜尋索引:
@Test
public void searchIndex() throws Exception {
//建立分詞器
Analyzer analyzerIK = new IKAnalyzer();
//建立Directory流物件,宣告索引庫位置
Directory directory = FSDirectory.open(Paths.get("D:\\yshop\\msgindex"));
//建立搜尋解析器 第一個引數是指定預設搜尋的field
QueryParser queryParser = new QueryParser("store_name",analyzerIK);
//建立搜尋物件
Query query = queryParser.parse("商品");
//建立索引讀取物件
IndexReader reader = DirectoryReader.open(directory);
//建立索引搜尋物件
IndexSearcher searcher = new IndexSearcher(reader);
//使用索引搜尋物件執行搜尋
TopDocs topDocs =searcher.search(query,10);
System.out.println("查詢到的資料總條數是:"+topDocs.totalHits);
//獲取查詢結果集
ScoreDoc[] docs = topDocs.scoreDocs;
//解析結果集:
for(ScoreDoc scoreDoc:docs){
//拿到文件id
int docID = scoreDoc.doc;
Document doc =searcher.doc(docID);
System.out.println("=============================");
System.out.println("docID:"+docID);
System.out.println("id:"+doc.get("id"));
System.out.println("store_name:"+doc.get("store_name"));
System.out.println("storeInfo:"+doc.get("storeInfo"));
System.out.println("price:"+doc.get("price"));
}
reader.close();
}
結果展示:
本作品採用《CC 協議》,轉載必須註明作者和本文連結