我最近一直在與開源搜索引擎Lucene合作 。 我不是專家,但是由于我只是瀏覽了一些相當稀疏的文檔并將應用程序從Lucene的很舊的版本遷移到了最新版本的2.4,所以我在總體上很清楚。 Lucene的文檔有點讓人難以想象,因此我想趁此機會在我腦海中嶄露頭角時,對Lucene進行高層次的概述。
如果您發現此頁面正在尋找Lucene的入門資料,那么對您有好處! 那就是它的目的。 不要期望找到最佳實踐,代碼示例或高級主題。 您將對Lucene的概念體系結構有一個清晰的介紹,通過它您可以高效地訪問項目網站上的FAQ和教程。 我正在使用Lucene的Java實現,但是所有這些高級內容都將同樣適用于任何其他Lucene風格。
您應該了解的第一件事是Lucene的實際作用。 Lucene實際上只做兩件事。
- 它創建搜索索引。
- 它在那些索引中搜索內容。
索引是您需要進行搜索的任何數據的有效導航表示。 您的數據可能與內容管理系統中的一組Word文檔一樣簡單,或者可能是來自數據庫,HTML頁面或系統中任何類型的數據對象的記錄。 由您決定要使哪些實體可搜索。 對于我們的討論,我們假設我們正在處理一組Word文檔。
創建索引
因此,第一步是為我們的Word文檔集創建索引。 為此,我們需要編寫一些代碼,以從Word文檔中獲取信息并將其轉換為可搜索的索引。 唯一的方法就是蠻力。 我們必須遍歷每個Word文檔,檢查每個文檔并將其轉換為Lucene創建索引時需要處理的部分。
Lucene創建索引需要哪些步驟? 那里有兩個。
- 文件資料
- 領域
這兩個抽象是Lucene的關鍵,Lucene用兩個頂級Java類(Document和Field)來表示它們。 文檔,不要與我們的實際Word文檔混淆,是一個Java類,表示Lucene中的可搜索項目。 可搜索項是指文檔是您在搜索時發現的東西。 創建這些文檔由您決定。
對于我們來說幸運的是,這是從實際的Word文檔到Lucene文檔的非常清晰的一步。 我想任何人都會同意,這將是我們的用戶在進行搜索時希望找到的Word文檔。 這使我們的處理變得相當簡單,我們將為每個實際的Word文檔簡單地創建一個Lucene文檔。
創建文檔及其字段
但是我們該怎么做呢? 實際上非常簡單。 首先,我們使用new運算符創建Document對象-僅此而已。 但是,在這一點上,文檔是沒有意義的。 現在,我們必須確定要添加到文檔中的字段。 這是我們必須思考的部分。 文檔由任意數量的字段組成,每個字段都有一個名稱和一個值。 這里的所有都是它的。
創建Lucene索引的開發人員幾乎普遍創建了兩個字段。 最重要的字段將是“內容”字段。 這個字段保存了我們要為其創建Lucene文檔的Word文檔的內容。 請記住,字段的名稱完全是任意的,但是大多數人將字段之一稱為“內容”,他們將現實世界中可搜索對象(在我們的情況下為Word文檔)的實際內容粘貼到該字段的值中。 本質上,字段只是一個名稱:值對。
開發人員創建的另一個非常常見的字段是“標題”字段。 該字段的值將是Word文檔的標題。 我們可能希望將有關Word文檔的其他信息保留在索引中。 其他常見字段是諸如“作者”,“ creation_date”,“關鍵字”等之類的內容。對所需字段的標識完全取決于業務需求。
因此,對于我們要使其可搜索的每個Word文檔,我們都必須創建一個Lucene文檔,其中包含我們上面概述的字段。 使用這些字段創建文檔后,我們將其添加到Lucene索引編寫器中,并要求它編寫索引。 而已! 現在,我們有了一個可搜索的索引。 的確如此,但是我們可能已經忽略了幾個Field細節。 讓我們仔細看看Fields。
字段詳細信息:存儲還是索引?
字段可以以多種方式保留在索引中。 您最初可能懷疑存在的最明顯的方法,也許是唯一的方法是可搜索的方法。 在我們的示例中,我們完全希望,如果用戶鍵入一個Word文檔內容中存在的單詞,則搜索將在搜索結果中返回該Word文檔。 為此,Lucene必須索引該字段。 首先,該術語有點讓人困惑,但是請注意,完全有可能在不使其可搜索的情況下將“字段”“存儲”在索引中。 換句話說,可以“存儲”一個字段,但不能“索引”它。 為什么? 您很快就會看到。
Lucene在將Field保留在索引中的方式之間的第一個區別是存儲還是索引。 如果我們期望某個字段的值匹配以使文檔被搜索擊中,那么我們必須為該字段建立索引。 如果僅存儲字段,則搜索查詢無法達到其值。 為什么要存儲一個字段? 很簡單,當我們通過索引字段之一命中Document時,Lucene將向我們返回整個Document對象。 所有存儲的字段將在該Document對象上可用; 被索引的字段將不在該對象上。 索引字段是用于查找文檔的信息,存儲的字段是與文檔一起返回的信息。 兩件事。
這意味著盡管我們可能無法基于給定字段的內容進行搜索,但是當搜索返回文檔時,我們仍然可以利用該字段的值。 我能想到的最明顯的用例是基于Web的文檔的“ url”字段。 搜索aURL的值沒有任何意義,但是您肯定希望知道搜索返回的文檔的URL。 您的結果頁面還可以如何將用戶引導到點擊頁面? 這是非常重要的一點:存儲的字段的值將在搜索返回的文檔上可用,但是實際上只有索引的字段的值可以用作搜索的目標。
從技術上講,存儲的字段保留在Lucene索引內。 但是,我們必須跟蹤索引的字段與存儲的字段不同的事實。 不幸的術語。 這就是單詞重要的原因。 他們可以避免很多混亂。
索引字段:已分析還是未分析?
對于下一個皺紋,我們必須指出,可以以兩種不同的方式對索引字段進行索引。 首先,我們可以在單個塊中索引字段的值。 換句話說,我們可能有一個“電話號碼”字段。 當我們搜索電話號碼時,我們需要匹配整個值或什么都不匹配。 這是很合理的。 因此,對于像電話號碼這樣的字段,我們將整個值ATOMICALLY索引到Lucene索引中。
但是,讓我們考慮一下Word文檔的“內容”字段。 我們是否希望用戶必須匹配整個字段? 當然不是。 我們希望將Word文檔的內容分解為可搜索的標記。 此過程稱為分析。 我們可以從丟棄所有不重要的詞開始,例如“ a”,“ the”,“ and”等。我們可以進行許多其他優化,但是最重要的是,字段的內容如“ contents” ”應該由Lucene分析。 這將產生目標輕量級索引。 這就是搜索變得有效和強大的方式。
在API中,這歸結為以下事實:創建字段時,我們必須指定
- 是否存儲
- 是否索引
- 如果建立索引,是否進行分析
現在,您應該清楚字段的詳細信息。 重要的是,我們可以存儲和索引給定的字段。 這不是一個選擇。
創建索引
將所有文檔添加到索引后,我們只需告訴索引編寫者即可創建索引。 從現在開始,我們可以根據索引的字段搜索任何文檔。 尋找即將到來的條目,以對在Lucene索引中搜索事物有一個高層次的概述。
分手筆記
回想一下,我們說過,假設我們的目標數據是一組Word文檔會更簡單。 現在我們已經完成了,請考慮您的目標數據可以是任何數據。 實際上,搜索的是Lucene文檔。 您可以根據需要創建任何內容。 它們可以并且經常來自現實世界中數據對象的集合。 同樣,將哪些數據放入Lucene文檔中取決于您的業務需求。 它可以像Word文檔到Lucene文檔的一對一映射一樣簡單,或者每個Lucene文檔可以是各種數據庫查詢以及您可能會發現的其他內容的集合。
索引愉快!
參考: Lucene概述第一部分:由我們的W4G合作伙伴 Chad Davis在zeroInsertionForce博客上創建索引 。
翻譯自: https://www.javacodegeeks.com/2012/04/lucene-overview-part-one-creating-index.html