目錄
- 一、Field域
- 1.Field屬性
- 2.Field常用型別
- 3.Field改進代碼
- 二、索引維護
- 1.添加索引
- 2.洗掉索引
- 1)洗掉指定索引
- 2)洗掉全部索引(慎用)
- 3.修改索引
一、Field域
1.Field屬性
Field是檔案中的域,包括Field名和Field值兩部分,一個檔案可以包括多個Field,Document只是Field的一個承載體,Field值即為要索引的內容,也是要搜索的內容,
是否分詞(tokenized)
是:作分詞處理,即將Field值進行分詞,分詞的目的是為了索引,
比如:商品名稱、商品簡介等,這些內容用戶要輸入關鍵字搜索,由于搜索的內容格式大、內容多需要分詞后將語匯單元索引,
否:不作分詞處理
比如:商品id、訂單號、身份證號等
是否索引(indexed)
是:進行索引,將Field分詞后的詞或整個Field值進行索引,索引的目的是為了搜索,
比如:商品名稱、商品簡介分析后進行索引,訂單號、身份證號不用分析但也要索引,這些將來都要作為查詢條件,
否:不索引,該域的內容無法搜索到
比如:商品id、檔案路徑、圖片路徑等,不用作為查詢條件的不用索引,
是否存盤(stored)
是:將Field值存盤在檔案中,存盤在檔案中的Field才可以從Document中獲取,
比如:商品名稱、訂單號,凡是將來要從Document中獲取的Field都要存盤,
否:不存盤Field值,不存盤的Field無法通過Document獲取
比如:商品簡介,內容較大不用存盤,如果要向用戶展示商品簡介可以從系統的關系資料庫中獲取商品簡介,
如果需要商品描述,則根據搜索出的商品ID去資料庫中查詢,然后顯示出商品描述資訊即可,
2.Field常用型別
開發中常用 的Filed型別,注意Field的屬性,根據需求選擇:
Field常用型別.PNG
3.Field改進代碼
圖書id:
是否分詞:不用分詞,因為不會根據商品id來搜索商品
是否索引:不索引,因為不需要根據圖書ID進行搜索
是否存盤:要存盤,因為查詢結果頁面需要使用id這個值,
圖書名稱:
是否分詞:要分詞,因為要將圖書的名稱內容分詞索引,根據關鍵搜索圖書名稱抽取的詞,
是否索引:要索引,
是否存盤:要存盤,
圖書價格:
是否分詞:要分詞,lucene對數字型的值只要有搜索需求的都要分詞和索引,
因為lucene對數字型的內容要特殊分詞處理,本例子可能要根據價格范圍搜索,需要分詞和索引,
是否索引:要索引
是否存盤:要存盤
圖書圖片地址:
是否分詞:不分詞
是否索引:不索引
是否存盤:要存盤
圖書描述:
是否分詞:要分詞
是否索引:要索引
是否存盤:因為圖書描述內容量大,不在查詢結果頁面直接顯示,不存盤,
不存盤是來不在lucene的索引檔案中記錄,節省lucene的索引檔案空間,如果要在詳情頁面顯示描述,
思路:
從lucene中取出圖書的id,根據圖書的id查詢關系資料庫中book表得到描述資訊,
代碼:
@Test
public void createIndex() throws Exception {
// 采集資料
BookDao dao = new BookDaoImpl();
List<Book> list = dao.queryBooks();
// 將采集到的資料封裝到Document物件中
List<Document> docList = new ArrayList<>();
Document document;
for (Book book : list) {
document = new Document();
// store:如果是yes,則說明存盤到檔案域中
// 圖書ID
// 不分詞、索引、存盤 StringField
Field id = new StringField("id", book.getId().toString(), Store.YES);
// 圖書名稱
// 分詞、索引、存盤 TextField
Field name = new TextField("name", book.getName(), Store.YES);
// 圖書價格
// 分詞、索引、存盤 但是是數字型別,所以使用FloatField
Field price = new FloatField("price", book.getPrice(), Store.YES);
// 圖書圖片地址
// 不分詞、不索引、存盤 StoredField
Field pic = new StoredField("pic", book.getPic());
// 圖書描述
// 分詞、索引、不存盤 TextField
Field description = new TextField("description",
book.getDescription(), Store.NO);
// 設定boost值
if (book.getId() == 4)
description.setBoost(100f);
// 將field域設定到Document物件中
document.add(id);
document.add(name);
document.add(price);
document.add(pic);
document.add(description);
docList.add(document);
}
二、索引維護
需求:
管理人員通過電商系統更改圖書資訊,這時更新的是資料庫,如果使用lucene搜索圖書資訊需要在資料庫表book資訊變化時及時更新lucene索引庫,
1.添加索引
呼叫 indexWriter.addDocument(doc)添加索引,
@Test
public void createIndex() throws Exception {
// 采集資料
BookDao dao = new BookDaoImpl();
List<Book> list = dao.queryBooks();
// 將采集到的資料封裝到Document物件中
List<Document> docList = new ArrayList<>();
Document document;
for (Book book : list) {
document = new Document();
// store:如果是yes,則說明存盤到檔案域中
// 圖書ID
Field id = new TextField("id", book.getId().toString(), Store.YES);
// 圖書名稱
Field name = new TextField("name", book.getName(), Store.YES);
// 圖書價格
Field price = new TextField("price", book.getPrice().toString(),
Store.YES);
// 圖書圖片地址
Field pic = new TextField("pic", book.getPic(), Store.YES);
// 圖書描述
Field description = new TextField("description",
book.getDescription(), Store.YES);
// 將field域設定到Document物件中
document.add(id);
document.add(name);
document.add(price);
document.add(pic);
document.add(description);
docList.add(document);
}
// 創建分詞器,標準分詞器
Analyzer analyzer = new StandardAnalyzer();
// 創建IndexWriter
IndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_4_10_3,
analyzer);
// 指定索引庫的地址
File indexFile = new File("E:\\11-index\\hm19\\");
Directory directory = FSDirectory.open(indexFile);
IndexWriter writer = new IndexWriter(directory, cfg);
// 通過IndexWriter物件將Document寫入到索引庫中
for (Document doc : docList) {
writer.addDocument(doc);
}
// 關閉writer
writer.close();
}
2.洗掉索引
1)洗掉指定索引
根據Term項洗掉索引,滿足條件的將全部洗掉,
Term是索引域中最小的單位,根據條件洗掉時,建議根據唯一鍵來進行洗掉,在solr中就是根據ID來進行洗掉和修改操作的,
@Test
public void deleteIndex() throws Exception {
// 創建分詞器,標準分詞器
Analyzer analyzer = new StandardAnalyzer();
// 創建IndexWriter
IndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_4_10_3,
analyzer);
Directory directory = FSDirectory
.open(new File("E:\\11-index\\hcx\\"));
// 創建IndexWriter
IndexWriter writer = new IndexWriter(directory, cfg);
// Terms
writer.deleteDocuments(new Term("id", "1"));
writer.close();
}
2)洗掉全部索引(慎用)
將索引目錄的索引資訊全部洗掉,直接徹底洗掉,無法恢復,慎用!
// 洗掉索引
@Test
public void deleteIndex() throws Exception {
// 1、指定索引庫目錄
Directory directory = FSDirectory.open(new File("E:\\11-index\\0720"));
// 2、創建IndexWriterConfig
IndexWriterConfig cfg = new IndexWriterConfig(Version.LATEST,
new StandardAnalyzer());
// 3、 創建IndexWriter
IndexWriter writer = new IndexWriter(directory, cfg);
// 4、通過IndexWriter來洗掉索引
// a)、洗掉全部索引
writer.deleteAll();
// 5、關閉IndexWriter
writer.close();
}
建議參照關系資料庫基于主鍵洗掉方式,所以在創建索引時需要創建一個主鍵Field,洗掉時根據此主鍵Field洗掉,
索引洗掉后將放在Lucene的回收站中,Lucene3.X版本可以恢復洗掉的檔案,3.X之后無法恢復,
3.修改索引
更新索引是先洗掉再添加,建議對更新需求采用此方法并且要保證對已存在的索引執行更新,可以先查詢出來,確定更新記錄存在執行更新操作,
@Test
public void updateIndex() throws Exception {
// 創建分詞器,標準分詞器
Analyzer analyzer = new StandardAnalyzer();
// 創建IndexWriter
IndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_4_10_3,
analyzer);
Directory directory = FSDirectory
.open(new File("E:\\11-index\\hcx\\"));
// 創建IndexWriter
IndexWriter writer = new IndexWriter(directory, cfg);
// 第一個引數:指定查詢條件
// 第二個引數:修改之后的物件
// 修改時如果根據查詢條件,可以查詢出結果,則將以前的刪掉,然后覆寫新的Document物件,如果沒有查詢出結果,則新增一個Document
// 修改流程即:先查詢,再洗掉,在添加
Document doc = new Document();
doc.add(new TextField("name", "lisi", Store.YES));
writer.updateDocument(new Term("name", "zhangsan"), doc);
writer.close();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/235459.html
標籤:其他
