在檢索數據的時候,我們很希望可以檢索出數據源的各種信息。就比如檢索磁盤文件,可以檢索出文件的路徑,名字, 內容,修改時間等等。再比如檢索圖書的書號、書名、作者、出版時間....? Lucene是如何組織這些數據源的不同屬性信息呢?
?
Lucene 數據源組織結構
?
org.apache.lucene.document包中有兩個很重要的類:Document 和 Field。這兩個類將雜亂無章的數據形式組織成可以被Lucene使用的內存數據結構。
?
Field類的作用主要是用來表示當前數據源的各種屬性。 數據源的每種屬性信息都可以組織成一個Field對象。這些對象有不同的屬性名,屬性值,以及屬性數據的存儲方式和索引方式。
?
舉個列子,比如我們想要檢索文件的路徑,修改時間和內容。我們可以創建三個Field對象分別存儲這三種數據:
//文件路徑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) //文件內容Field Field contentField=new Field("contents", new FileReader(file));
?
下面是Field構造器(Field構造器有很多種,這里只做簡單說明)
/** * name: 名字 * value: 需要處理的字符串 * store: 是否需要將Field的原始value保存在索引文件中 * index: 是否需要對Field的原始value建立索引,如果需要,那么Field值要被分詞。 */ public Field(String name, String value, Store store, Index index)
?
Store和Index是Field中的枚舉類型,用來表示這個Field的存儲和索引方式。它們主要是為了告訴Lucene,哪些數據不需要存儲,哪些數據不需要檢索。
/** * 確定該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值中的詞語進行查詢,適合內容查詢(全文檢索) 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作為數據源的各種屬性信息的集合,向Lucene提供原始的要索引的數據。這些數據源不僅可以是文件,也可以是一段字符串、幾個數字、甚至一些鏈接。只要把它們加入到Document對象中,Lucene就可以為這些數據源建立索引。下面的部分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。我們可以創建一個Document對象,加入這三個Field,來表示一個文檔文件需要被檢索的三種數據。
Document doc = new Document(); doc.add(pathField); doc.add(modifiedField); doc.add(contentField);
?
?
總結 :下面的圖很清楚的說明Lucene的數據源表示形式
?
舉個例子,按照 《Lucene體系結構概述》 中代碼( IndexFiles.java )對3個txt文件建立索引。Lucene首先將這三個數據源在內存中組織成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可以對任何形式的數據源建立索引,比如字符串、純文本、XML、HTML等數據形式。怎么多雜亂無章的數據必須組織成統一有效的結構才能更好的處理,Document / Field 無疑做到了這一點。
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

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