在檢索數(shù)據(jù)的時候,我們很希望可以檢索出數(shù)據(jù)源的各種信息。就比如檢索磁盤文件,可以檢索出文件的路徑,名字, 內(nèi)容,修改時間等等。再比如檢索圖書的書號、書名、作者、出版時間....? Lucene是如何組織這些數(shù)據(jù)源的不同屬性信息呢?
?
Lucene 數(shù)據(jù)源組織結(jié)構(gòu)
?
org.apache.lucene.document包中有兩個很重要的類:Document 和 Field。這兩個類將雜亂無章的數(shù)據(jù)形式組織成可以被Lucene使用的內(nèi)存數(shù)據(jù)結(jié)構(gòu)。
?
Field類的作用主要是用來表示當前數(shù)據(jù)源的各種屬性。 數(shù)據(jù)源的每種屬性信息都可以組織成一個Field對象。這些對象有不同的屬性名,屬性值,以及屬性數(shù)據(jù)的存儲方式和索引方式。
?
舉個列子,比如我們想要檢索文件的路徑,修改時間和內(nèi)容。我們可以創(chuàng)建三個Field對象分別存儲這三種數(shù)據(jù):
//文件路徑Field
Field pathField=new Field("path", file.getPath(), Field.Store.YES, Field.Index.NOT_ANALYZED)
//文件修改時間Field
Field modifiedField=new Field("modified", DateTools.timeToString(file.lastModified(), DateTools.Resolution.MINUTE), Field.Store.YES, Field.Index.NOT_ANALYZED)
//文件內(nèi)容Field
Field contentField=new Field("contents", new FileReader(file));
?
下面是Field構(gòu)造器(Field構(gòu)造器有很多種,這里只做簡單說明)
/**
* name: 名字
* value: 需要處理的字符串
* store: 是否需要將Field的原始value保存在索引文件中
* index: 是否需要對Field的原始value建立索引,如果需要,那么Field值要被分詞。
*/
public Field(String name, String value, Store store, Index index)
?
Store和Index是Field中的枚舉類型,用來表示這個Field的存儲和索引方式。它們主要是為了告訴Lucene,哪些數(shù)據(jù)不需要存儲,哪些數(shù)據(jù)不需要檢索。
/**
* 確定該Field的原始value是否需要存儲在索引中
*/
enum Store {
//該Field的原始值要被存儲在索引中
//對短文本很有用。比如一個文檔的標題,這個value以原始形式存儲,在存儲之前并不通過analyze分詞
?YES {
public boolean isStored() { return true; }
},
//該Field的原始值不需要存儲在索引中
NO {
public boolean isStored() { return false; }
};
public abstract boolean isStored();
}
/**
* 確定該Field是否需要索引
*/
enum Index{
//該Field的值不需要索引,也就是不能提供關于這種Field值的查詢
//但是如果這個Field被存儲了(Stored=YES),那么我們查詢別的Field的時候,可以得到這種Field信息
NO{
public boolean isIndexed() { return false; }
public boolean isAnalyzed() { return false; }
public boolean omitNorms() { return true; }
},
//該Field值需要建索引,而且需要分詞
// 可以通過Field值中的詞語進行查詢,適合內(nèi)容查詢(全文檢索)
ANALYZED {
public boolean isIndexed() { return true; }
public boolean isAnalyzed() { return true; }
public boolean omitNorms() { return false; }
},
//該Field值需要建索引,但不需要分詞
//由于不分詞,只能夠通過整個值進行查詢,適合像商品編號這樣的ID值或者單個詞語
NOT_ANALYZED {
public boolean isIndexed() { return true; }
public boolean isAnalyzed() { return false; }
public boolean omitNorms() { return false; }
},
}
?
Document 是Field 的集合(并不是狹隘的文件的含義) 。 在Lucene中,Document作為數(shù)據(jù)源的各種屬性信息的集合,向Lucene提供原始的要索引的數(shù)據(jù)。這些數(shù)據(jù)源不僅可以是文件,也可以是一段字符串、幾個數(shù)字、甚至一些鏈接。只要把它們加入到Document對象中,Lucene就可以為這些數(shù)據(jù)源建立索引。下面的部分Document源碼表明:Document主要起到對Field信息進行記錄和管理的作用。
?
public final class Document implements java.io.Serializable {
//Field列表
List<Fieldable> fields = new ArrayList<Fieldable>();
//在Document中加入Field
public final void add(Fieldable field) {
fields.add(field);
}
public final void removeField(String name){....}
public final Field getField(String name) {....}
.....
}
?
還是上面檢索文件的例子,每個文檔文件的不同屬性信息都被組織成了三個Field對象:path Field、modified Field、content Field。我們可以創(chuàng)建一個Document對象,加入這三個Field,來表示一個文檔文件需要被檢索的三種數(shù)據(jù)。
Document doc = new Document();
doc.add(pathField);
doc.add(modifiedField);
doc.add(contentField);
?
?
總結(jié) :下面的圖很清楚的說明Lucene的數(shù)據(jù)源表示形式
?
舉個例子,按照 《Lucene體系結(jié)構(gòu)概述》 中代碼( IndexFiles.java )對3個txt文件建立索引。Lucene首先將這三個數(shù)據(jù)源在內(nèi)存中組織成Document、Field 如下表:
?
| Document | ?? Field1 (path) |
? ? Field2 (modified)
|
??? Field3 (content) |
| ??? 1.txt | ?? e:\\....\\1.txt | ?????? 2010-4-1 | ?I'm a good stud.. |
| ??? 2.txt | ?? e:\\....\\2.txt | ?????? 2010-4-2 | ?It's me to a fini... |
| ??? 3.txt | ?? e:\\....\\3.txt | ?????? 2010-2-11 | ?Hi, Jack me too... |
?
Document 和 Field在Lucene中的作用是巨大的。我們都知道Lucene可以對任何形式的數(shù)據(jù)源建立索引,比如字符串、純文本、XML、HTML等數(shù)據(jù)形式。怎么多雜亂無章的數(shù)據(jù)必須組織成統(tǒng)一有效的結(jié)構(gòu)才能更好的處理,Document / Field 無疑做到了這一點。
?
【Lucene3.0 初窺】數(shù)據(jù)源內(nèi)存組織結(jié)構(gòu)—Document/Field
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

