1 Field的特性
Document(文檔)是Field(域)的承載體, 一個Document由多個Field組成. Field由名稱和值兩部分組成, Field的值是要索引的內容, 也是要搜索的內容.
-
是否分詞(tokenized)
是: 將Field的值進行分詞處理, 分詞的目的是為了索引. 如: 商品名稱, 商品描述. 這些內容用戶會通過輸入關鍵詞進行查詢, 由於內容多樣, 需要進行分詞處理建立索引.
否: 不做分詞處理. 如: 訂單編號, 身份證號, 是一個整體, 分詞以后就失去了意義, 故不需要分詞.
-
是否索引(indexed)
是: 將Field內容進行分詞處理后得到的詞(或整體Field內容)建立索引, 存儲到索引域. **索引的目的是為了搜索. **如: 商品名稱, 商品描述需要分詞建立索引. 訂單編號, 身份證號作為整體建立索引. **只要可能作為用戶查詢條件的詞, 都需要索引. **
否: 不索引. 如: 商品圖片路徑, 不會作為查詢條件, 不需要建立索引.
-
是否存儲(stored)
是: 將Field值保存到Document中. 如: 商品名稱, 商品價格. **凡是將來在搜索結果頁面展現給用戶的內容, 都需要存儲. **
否: 不存儲. 如: 商品描述. 內容多格式大, 不需要直接在搜索結果頁面展現, 不做存儲. 需要的時候可以從關系數據庫取.
2 常用的Field類型
以下是企業項目開發中常用的Field類型:
Field類型 | 數據類型 | 是否分詞 | 是否索引 | 是否存儲 | 說明 |
---|---|---|---|---|---|
StringField(FieldName, FieldValue, Store.YES) | 字符串 | N | Y | Y/N | 字符串類型Field, 不分詞, 作為一個整體進行索引 (如: 身份證號, 訂單編號), 是否需要存儲由Store.YES或Store.NO決定 |
LongField(FieldName, FieldValue, Store.YES) | 數值型代表 | Y | Y | Y/N | Long數值型Field代表, 分詞並且索引(如: 價格), 是否需要存儲由Store.YES或Store.NO決定 |
StoredField(FieldName, FieldValue) | 重載方法, 支持多種類型 | N | N | Y | 構建不同類型的Field, 不分詞, 不索引, 要存儲. (如: 商品圖片路徑) |
TextField(FieldName, FieldValue, Store.NO) | 文本類型 | Y | Y | Y/N | 文本類型Field, 分詞並且索引, 是否需要存儲由Store.YES或Store.NO決定 |
3 常用的Field種類使用
3.1 准備環境
復制Lucene 02 - Lucene的入門程序(Java API的簡單使用)中的lucene-first
項目, 修改名稱為lucene-second
;
修改pom.xml文件, 將所有的lucene-first
修改為lucene-second
.
3.2 需求分析
Field名稱 | 是否分詞 | 是否索引 | 是否存儲 | Field類型 |
---|---|---|---|---|
圖書id | 不需要 | 需要(這里可以索引, 也可以不索引) | 需要 | StringField |
圖書名稱 | 需要 | 需要 | 需要 | TextField |
圖書價格 | 需要 | 需要(數值型的Field, Lucene使用內部分詞) | 需要 | FloatField |
圖書圖片 | 不需要 | 不需要 | 需要 | StoredField |
圖書描述 | 需要 | 需要 | 不需要 | TextField |
3.3 修改代碼
public class IndexManager {
/**
* 創建索引功能的測試
* @throws Exception
*/
@Test
public void createIndex() throws IOException{
// 1. 采集數據
BookDao bookDao = new BookDaoImpl();
List<Book> books = bookDao.listAll();
// 2. 創建文檔對象
List<Document> documents = new ArrayList<Document>();
for (Book book : books) {
Document document = new Document();
// 給文檔對象添加域
// add方法: 把域添加到文檔對象中, field參數: 要添加的域
// TextField: 文本域, 屬性name:域的名稱, value:域的值, store:指定是否將域值保存到文檔中
// 圖書Id --> StringField
document.add(new StringField("bookId", book.getId() + "", Store.YES));
// 圖書名稱 --> TextField
document.add(new TextField("bookName", book.getBookname(), Store.YES));
// 圖書價格 --> FloatField
document.add(new FloatField("bookPrice", book.getPrice(), Store.YES));
// 圖書圖片 --> StoredField
document.add(new StoredField("bookPic", book.getPic()));
// 圖書描述 --> TextField
document.add(new TextField("bookDesc", book.getBookdesc(), Store.NO));
// 將文檔對象添加到文檔對象集合中
documents.add(document);
}
// 3. 創建分析器對象(Analyzer), 用於分詞
Analyzer analyzer = new StandardAnalyzer();
// 4. 創建索引配置對象(IndexWriterConfig), 用於配置Lucene
// 參數一:當前使用的Lucene版本, 參數二:分析器
IndexWriterConfig indexConfig = new IndexWriterConfig(Version.LUCENE_4_10_2, analyzer);
// 5. 創建索引庫目錄位置對象(Directory), 指定索引庫的存儲位置
File path = new File("/Users/healchow/Documents/index");
Directory directory = FSDirectory.open(path);
// 6. 創建索引寫入對象(IndexWriter), 將文檔對象寫入索引
IndexWriter indexWriter = new IndexWriter(directory, indexConfig);
// 7. 使用IndexWriter對象創建索引
for (Document doc : documents) {
// addDocement(doc): 將文檔對象寫入索引庫
indexWriter.addDocument(doc);
}
// 8. 釋放資源
indexWriter.close();
}
}
3.4 重新建立索引
刪除之前建立的索引, 再次建立索引. 打開Luke工具查看索引信息, 可看到圖書圖片不分詞, 故沒有索引, 圖書價格使用了Lucene的內部分詞, 故按照UTF-8解碼后顯示亂碼, 如下圖示:
圖書的描述信息沒有存儲:
版權聲明
作者: 馬瘦風
出處: 博客園 馬瘦風的博客
您的支持是對博主的極大鼓勵, 感謝您的閱讀.
本文版權歸博主所有, 歡迎轉載, 但請保留此段聲明, 並在文章頁面明顯位置給出原文鏈接, 否則博主保留追究相關人員法律責任的權利.