在檢索數(shù)據(jù)的時(shí)候,我們很希望可以檢索出數(shù)據(jù)源的各種信息。就比如檢索磁盤文件,可以檢索出文件的路徑,名字, 內(nèi)容,修改時(shí)間等等。再比如檢索圖書(shū)的書(shū)號(hào)、書(shū)名、作者、出版時(shí)間....? Lucene是如何組織這些數(shù)據(jù)源的不同屬性信息呢?
?
Lucene 數(shù)據(jù)源組織結(jié)構(gòu)
?
org.apache.lucene.document包中有兩個(gè)很重要的類:Document 和 Field。這兩個(gè)類將雜亂無(wú)章的數(shù)據(jù)形式組織成可以被Lucene使用的內(nèi)存數(shù)據(jù)結(jié)構(gòu)。
?
Field類的作用主要是用來(lái)表示當(dāng)前數(shù)據(jù)源的各種屬性。 數(shù)據(jù)源的每種屬性信息都可以組織成一個(gè)Field對(duì)象。這些對(duì)象有不同的屬性名,屬性值,以及屬性數(shù)據(jù)的存儲(chǔ)方式和索引方式。
?
舉個(gè)列子,比如我們想要檢索文件的路徑,修改時(shí)間和內(nèi)容。我們可以創(chuàng)建三個(gè)Field對(duì)象分別存儲(chǔ)這三種數(shù)據(jù):
//文件路徑Field Field pathField=new Field("path", file.getPath(), Field.Store.YES, Field.Index.NOT_ANALYZED) //文件修改時(shí)間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)造器有很多種,這里只做簡(jiǎn)單說(shuō)明)
/** * name: 名字 * value: 需要處理的字符串 * store: 是否需要將Field的原始value保存在索引文件中 * index: 是否需要對(duì)Field的原始value建立索引,如果需要,那么Field值要被分詞。 */ public Field(String name, String value, Store store, Index index)
?
Store和Index是Field中的枚舉類型,用來(lái)表示這個(gè)Field的存儲(chǔ)和索引方式。它們主要是為了告訴Lucene,哪些數(shù)據(jù)不需要存儲(chǔ),哪些數(shù)據(jù)不需要檢索。
/** * 確定該Field的原始value是否需要存儲(chǔ)在索引中 */ enum Store { //該Field的原始值要被存儲(chǔ)在索引中 //對(duì)短文本很有用。比如一個(gè)文檔的標(biāo)題,這個(gè)value以原始形式存儲(chǔ),在存儲(chǔ)之前并不通過(guò)analyze分詞 ?YES { public boolean isStored() { return true; } }, //該Field的原始值不需要存儲(chǔ)在索引中 NO { public boolean isStored() { return false; } }; public abstract boolean isStored(); } /** * 確定該Field是否需要索引 */ enum Index{ //該Field的值不需要索引,也就是不能提供關(guān)于這種Field值的查詢 //但是如果這個(gè)Field被存儲(chǔ)了(Stored=YES),那么我們查詢別的Field的時(shí)候,可以得到這種Field信息 NO{ public boolean isIndexed() { return false; } public boolean isAnalyzed() { return false; } public boolean omitNorms() { return true; } }, //該Field值需要建索引,而且需要分詞 // 可以通過(guò)Field值中的詞語(yǔ)進(jìn)行查詢,適合內(nèi)容查詢(全文檢索) ANALYZED { public boolean isIndexed() { return true; } public boolean isAnalyzed() { return true; } public boolean omitNorms() { return false; } }, //該Field值需要建索引,但不需要分詞 //由于不分詞,只能夠通過(guò)整個(gè)值進(jìn)行查詢,適合像商品編號(hào)這樣的ID值或者單個(gè)詞語(yǔ) 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ù)源不僅可以是文件,也可以是一段字符串、幾個(gè)數(shù)字、甚至一些鏈接。只要把它們加入到Document對(duì)象中,Lucene就可以為這些數(shù)據(jù)源建立索引。下面的部分Document源碼表明:Document主要起到對(duì)Field信息進(jìn)行記錄和管理的作用。
?
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) {....} ..... }
?
還是上面檢索文件的例子,每個(gè)文檔文件的不同屬性信息都被組織成了三個(gè)Field對(duì)象:path Field、modified Field、content Field。我們可以創(chuàng)建一個(gè)Document對(duì)象,加入這三個(gè)Field,來(lái)表示一個(gè)文檔文件需要被檢索的三種數(shù)據(jù)。
Document doc = new Document(); doc.add(pathField); doc.add(modifiedField); doc.add(contentField);
?
?
總結(jié) :下面的圖很清楚的說(shuō)明Lucene的數(shù)據(jù)源表示形式
?
舉個(gè)例子,按照 《Lucene體系結(jié)構(gòu)概述》 中代碼( IndexFiles.java )對(duì)3個(gè)txt文件建立索引。Lucene首先將這三個(gè)數(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可以對(duì)任何形式的數(shù)據(jù)源建立索引,比如字符串、純文本、XML、HTML等數(shù)據(jù)形式。怎么多雜亂無(wú)章的數(shù)據(jù)必須組織成統(tǒng)一有效的結(jié)構(gòu)才能更好的處理,Document / Field 無(wú)疑做到了這一點(diǎn)。
?
【Lucene3.0 初窺】數(shù)據(jù)源內(nèi)存組織結(jié)構(gòu)—Document/Field
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
