Solr In Action 中文版 第一章(一),solraction
1.1我到底需要一個搜尋引擎嗎?
第一章 Solr 簡介
本章預覽:
·搜尋引擎處理的資料特性
·常見搜尋引擎用例
·Solr核心模組介紹
·選擇Solr的理由
·功能概述
伴隨著社交媒體、雲端運算、移動互連網和大資料等技術的高速發展,我們正迎來一個令人激動的計算時代。軟體架構師們開始面對的主要挑戰之一,便是如何處理全球巨大的使用者基數所產生及使用的海量資料。此外,使用者們開始期待線上軟體應用永遠都是穩定可用的,並且能夠一直保持響應,這對應用就提出了更高的可擴充性和穩定性需求。為了滿足這些需求,一些專用的非關係型資料存放區及處理技術,統稱為NoSQL(Not Only SQL)技術,開始獲得越來越多的青睞。這些系統並不強制要求將所有的資料都儲存在曾經成為事實上標準的關係型資料模型當中,而是共用了一個通用的設計模式,在資料存放區處理引擎和特定的資料類型之間進行匹配。換句話說,NoSQL技術為處理特定資料類型的特定類別問題做了效能最佳化。由於對可擴充性的需求和效能的需求不斷增加,導致各種NoSQL技術和傳統關係型資料庫開始混合使用,這種跨界架構變得越來越流行。過去那種一種資料處理方案就能吃遍天下的時代已經一去不複返了。
本書主要討論一種特殊的NoSQL技術,即Apache Solr。和她的其他非關係型兄弟們一樣,Solr也為一類特定問題的處理做了最佳化。具體來說,Solr 是一個可擴充的,可快速部署的,對搜尋海量文本中心的資料和對返回結果做相關性排序方面做了最佳化的企業級搜尋引擎。
這句話讀上去有點拗口,不過沒關係,我們把這個定義中的亮點分解出來看:
·可擴充性:Solr可以把建立索引和查詢處理的運算分布到一個叢集內的多台伺服器上。
·快速部署:Solr是開源軟體,安裝和配置都很方便,可以根據安裝包內的Sample配置直接上手。
·最佳化的搜尋功能:Solr搜尋夠快。對於複雜的搜尋查詢,Solr可以做到亞秒級的處理,通常幾十毫秒就能處理完一次複雜查詢
·海量文本:Solr是針對百萬級以上的海量文本處理而設計的,可以很好地處理海量資料。
·文本中心的資料:Solr為搜尋包含自然語言的常值內容做了最佳化,比如電子郵件,網頁,簡曆,PDF文檔,或是推特、微博、部落格這些社交內容等等,都適合用Solr來處理。
·結果是按相關性排序的:Solr的搜尋返回結果是按照結果文檔與使用者查詢之間的相關程度度做排序的,保證最相關的結果會優先返回。
在本書中,你將學到如何使用Solr來設計實現一個可擴充的搜尋方案。我們的學習旅程從瞭解Solr支援的資料類型和典型用例開始。這樣你能更好的理解在整個現代軟體應用架構全景中Solr所處的位置,以及Solr到底是設計來處理哪些問題的。
1.1我到底需要一個搜尋引擎嗎?
我們猜測你已經有了些想法要準備使用搜尋引擎了,否則你也不會翻開這本書。因此,我們就不浪費時間來揣度你到底是為什麼開始考慮用Solr的了,我們直接來討論點乾貨,看看關於你的資料和用例方面, 有哪些問題是你在決定是否使用搜尋引擎之前所必須要回答的。這最終會歸結為如何深刻理解你的資料和你的使用者,以選用一個合適的技術來同時滿足二者的需求。我們先從討論一下哪些資料屬性是搜尋引擎適合處理的。
1.1.1 管理文本中心的資料
合理選用同資料匹配的儲存及處理引擎,是現代軟體應用架構的標誌性要求之一。如果你是一個優秀的程式員,那麼你應該知道要根據在演算法中使用資料的方式來選取最合適的資料結構。比如,如果你需要實現快速隨機尋找,你就不會使用鏈表結構來儲存資料。同樣的道理也適用於搜尋引擎的選取。這裡列出了適合用類似Solr這樣的搜尋引擎來處理的資料的4種主要特點:
文本中心的資料
讀取遠多於寫入的資料
面向文檔的資料
靈活的Schema
也許在這兒應該加上第五個資料特性,即:海量數的據量,也就是”大資料“,但是我們主要關注的是Solr區別於其他NoSQL技術的主要特性,而可以處理海量的資料並不是它們的主要區別之一。
雖然這裡列出了類似Solr這樣的搜尋引擎可以有效處理的資料類型的4個主要特點,但是這隻是一個粗略的準則,並不是一個嚴格的標準。我們來深入的討論一下這些資料特性,看看為什麼它們對於搜尋來說這麼重要。我們現在只關注概念,具體的實現細節在稍後的章節討論。
文本中心的資料
你肯定見過有人用“非結構化資料“這個術語來描述搜尋引擎處理的資料。我們認為“非結構化”這個詞有些模糊不清,因為任何一個基於人類語言產生的文檔都是隱含有一定的結構的。要理解“非結構化”這個術語你可以認為這是從電腦的角度來看的。在電腦眼中,文字文件就是一個字元流。這個字元流必須通過特定的語言規則解析出語義結構,才能被檢索到。而這正是搜尋引擎的工作所在。
我們認為“文本中心的資料”這個詞更適合用來描述Solr處理的資料類型。因為搜尋引擎的設計初衷就是用來提取文本資料的隱含結構,並產生相關索引以提高查詢檢索的效率。“文本中心的資料”這個詞隱含表明了文檔中的文本資訊包含使用者感興趣的查詢內容。當然,搜尋引擎也支援非文本資料,比如數字類型的資料,但是其主要強項,還是在於處理基於自然語言的文本資料。
前面說的都是“文本”,其實“中心”這個部分也很重要,因為如果你的使用者對於文本部分的內容不感興趣,那麼搜尋引擎可能就不是處理你的問題的最佳選擇。舉個例子,對於一個給員工用來建立差旅支出報告的應用,每份報告都包括一些結構化的資料,比如日期,費用類型,匯率,數量等等,另外每項費用後面可能會包含一些備忘資訊,用於描述該項費用的大致情況。這樣一個應用就是一個包含文本資訊,但並不是“文本中心的資料”的一個例子,因為會計部門在使用這些員工的支出費用報告來產生月度支出報告時,並不會通過尋找備忘裡的文本資訊來做,文本在這裡並不是其關心的主要內容。簡單來說,就是不是所有包含文本資訊的資料都適合搜尋引擎來處理。
所以現在先花幾分鐘好好想想你的資料是否是“文本中心的資料”。考慮的重點主要就是資料中的文本資訊使用者是不是會拿來做檢索。如果答案是YES,那麼搜尋引擎很可能是一個好的方案選擇。我們在第5章和第6章會討論如何利用Solr的文本分析來提取文本資料的結構的細節。
讀取遠多於寫入的資料:
另外一個搜尋引擎可以高效處理的資料特性是“讀取遠多於寫入的資料”。首先,需要聲明的是Solr是允許你更新索引中的現有文檔內容的。你可以把“讀取遠多於寫入”解讀為對於文檔的讀取操作頻率要遠遠高於建立文檔和更新文檔的頻率。但是別狹隘的理解為你就完全不能寫入資料了,或是你會被限制在一個特定頻率之下更新資料。事實上Solr4的一個關鍵特性就是“近乎即時的查詢”,這個功能可以允許你每秒鐘為數千的文檔建立索引並且幾乎立刻就能查詢到這些新加入的文檔。
“讀取遠多於寫入的資料”背後的關鍵點是你的資料在寫入Solr後,在其生命週期內應該是要被重複讀取很多次的。你可以理解為搜尋引擎並不是主要用來儲存資料的,而是主要用於查詢儲存的資料的(查詢請求是一種讀取操作)。所以如果你需要很頻繁的更新資料,那麼搜尋引擎可能不太適合你的需求,其他的NoSQL技術,比如Cassandra,可能更適合你的快速隨機寫入的需求。
面向文檔的資料
到目前為止,我們一直使用更通用的“資料”這一術語,但是實際中搜尋引擎處理的都是文檔資料。在搜尋引擎中,一個文檔是由值域(field)組成的獨立集合,每一個值域都只儲存資料值,不能再嵌套包含其他值域。換句話說,在Solr這樣的搜尋引擎中,文檔都是扁平結構的,文檔之間不存在相互依賴關係。Solr中“扁平”的概念是比較寬鬆的,一個值域可以儲存多個資料值,但是值域不能再嵌套包含子值域。也就是說你可以在一個值域裡儲存多個資料值,但是你不能往值域裡頭嵌套別的值域。
Solr中這種扁平化的、面向文檔的方式可以很好的處理已經文檔化的資料,比如網頁,部落格,pdf文檔等等。那麼如果要用solr來處理關係型資料庫中已經結構化好的資料應該怎麼辦呢?這種情況下你需要先把關係型資料庫中跨表格儲存體的資料取出來,去結構化,然後放到扁平化的自包含文檔結構裡。我們會在第三章學習怎麼處理這樣的問題。
你還需要考慮你的文檔資料中的哪些值域需要儲存在Solr中,哪些值域需要儲存在其他系統中(比如資料庫中)。簡單來說,搜尋引擎只儲存需要被檢索到的資料,以及用於顯示檢索結果的資料。舉個例子,如果你有一個線上視頻的搜尋索引,你應該不會希望把視頻檔案本身儲存在Solr中,合理的方案應該是把大的視頻檔案都放在內容分髮網絡(CDN)中。通常你只需要在搜尋引擎中儲存滿足搜尋需求的最少資料即可。剛才這個線上視頻的例子清楚的說明了不要把Solr當成通用資料存放區技術,Solr的工作是找到使用者感興趣的視頻檔案,而不是儲存視頻檔案本身。
靈活的Schema
最後一個搜尋引擎資料的主要特性是有靈活的schema。這意味著查詢索引中的文檔不需要擁有統一的結構。在關係型資料庫中,表中的每一行資料都必須擁有相同的結構。而在Solr中,文檔們可以有不同的值域。當然同一個索引中的文檔們至少應該擁有一部分大家都有的值域以便於檢索,但是並不要求所有文檔中的值域結構完全一樣。
舉個例子,假如要做一個用於尋找出租和出售房源的搜尋應用。顯然每條房來源文件都會有地段,房間數,衛生間數等一些共有的值域,但是根據類型是出租還是出售的不同,不同的房來源文件會有不同的值域。一條出售的房源會有售價值域,財產稅值域,而一條出租的房來源文件則會有月租金和寵物政策等等不同的值域。
總結一下,Solr這樣的搜尋引擎是專門最佳化用於處理文本中心的,讀取遠多於寫入的,面向文檔的,擁有靈活Schema的資料用的。Solr並不是一種通用資料存放區處理技術,這也是區別於其他NoSQL技術的主要因素。
有眾多不同的資料存放區和處理方案可供選擇的好處是你不再需要費勁腦汁地尋找一種可以滿足所有需求的通用技術方案。搜尋引擎在某些特定任務上表現出色,但是在其他一些方面效能很差。這意味著在大多數情況下,你可以用Solr來作為關係型資料庫和其他NoSQL技術的有力補充,而並不是要取代後者。
既然我們已經談到了Solr所針對最佳化處理的資料類型,那我們就接著來討論一下像solr這樣的搜尋引擎主要是設計來解決哪些實際用例的。理解這些用例可以協助你理解搜尋引擎技術是如何區別於其他資料處理技術的。
1.1.2 常見的搜尋引擎用例
在這一節中,我們來看看Solr這樣的搜尋引擎都能幹些什麼。正如我們在1.1.1節中所提到的那樣,這些討論只是一種指南性質的建議,不要把它們當成嚴格的使用規則來看。在我們開始之前,你需要意識到想做出一個優秀的搜尋服務,其門檻是很高的。現在的使用者都習慣於使用像Google和Bing這樣又快又高效的網路搜尋引擎,而很多受歡迎的網站也有自己強大的搜尋方案來協助使用者快速的擷取想要的資訊, 所以使用者對搜尋服務並不陌生並且會非常的挑剔。當你在評估像Solr這樣的搜尋引擎時,或是在設計你自己的搜尋方案時,一定要有根弦兒,要把使用者體驗放在高優先順序上來考慮。
基本的關鍵字查詢
很明顯,作為一個搜尋引擎來說, 首先必須要能夠支援基本的關鍵詞查詢。這也是搜尋引擎的主要功能之一。不過關鍵詞查詢功能還是值得在這裡強調一下的,因為這是使用者使用搜尋引擎最典型的方式。很少有使用者想要會一上來就填寫一個很完整的複雜搜尋表單來進行搜尋的。考慮到關鍵詞搜尋功能將會是使用者和你的搜尋引擎之間最常見的互動方式,這個準系統必須能夠提供給使用者以非常好的使用者體驗才行。
一般來說,使用者希望只輸入幾個簡單的關鍵詞就能擷取到很好的搜尋結果。這也許聽上去像是一個簡單的匹配任務:把查詢字串和文檔進行匹配即可。不過請考慮一下要實現良好的使用者體驗所必須解決的幾個問題:
· 相關結果必須迅速返回,大多數情況下要求一秒鐘之內就能夠返回
· 使用者的查詢字串出現拼字錯誤時能夠自動錯誤修正
· 使用者輸入時通過自動補全建議來減少使用者的輸入負擔,這在行動裝置 App中很常見
· 處理查詢字串中的同義字近義詞
· 對包含查詢字串的語言變異的文檔進行匹配(譯者註:語言變異是語意學術語,即用詞不完全一樣的近似表達)
· 短語處理,使用者是希望匹配短語中所有的單詞,還是只要匹配短語中的部分單詞就行
· 對一些通用介詞的處理,比如“a,” “an”, “of”, “the”等等
· 如果最靠前的查詢結果使用者不滿意, 如何給使用者返回更多的查詢結果
就像你看到的那樣,不使用特定的處理方法的話,這樣一堆問題會使得看上去如此簡單的功能實現起來變得很困難。然而利用像Solr這樣的搜尋引擎,這些功能就能立等可取,實現起來變得很簡單。當你給使用者提供了一個強大的關鍵詞搜尋工具之後,接下來你就需要考慮如何去展示查詢的結果,這就引出了下一個用例,按照結果同查詢請求之間的相關性順序,對搜尋返回的查詢結果進行排序。
排序的檢索結果
搜尋引擎為查詢返回“最靠前“的結果。在SQL查詢關係型資料庫的時候,某一行資料記錄要麼匹配查詢被返回,要麼不匹配查詢被忽略,查詢結果也是按照資料記錄的某一列屬性來排序的。而對於搜尋引擎來說,返回的結果文檔是按照得分做降序排列的,該得分表示文檔和查詢的匹配程度。匹配程度得分依據一系列的因子來計算,不過一般說來得分越高,表明結果文檔同查詢之間的相關度越高。
有好幾個因素決定了將結果文檔按照相關度排序的方式很重要。首先,現代搜尋引擎一般都儲存著海量的文檔,都是上百萬甚至數十億記的。如果不對查詢結果進行相關度排序,那使用者就會被海量的返回結果所淹沒,無法清晰有效瀏覽搜尋的結果。其次,使用者使用其他搜尋引擎的經驗使得使用者已經習慣於使用少數的幾個關鍵詞就能獲得不錯的查詢結果,也使得使用者普遍比較缺乏耐心。他們會期待搜尋引擎按照他們想要的意思來工作,而不管其所輸入的資訊是否完全正確。比如對於行動裝置 App的後台搜尋服務來說,使用者會期待在輸入了簡短的幾個可能還包含有拼字錯誤的查詢詞之後,搜尋服務就能夠返回正確的搜尋結果。
如果要人工幹預排序的結果,你可以給特定的文檔、值域、或者查詢字串增加權重,或著直接提高某個文檔的相關度分值。比如你如果希望把新加入的文檔推送到最靠前的位置,就可以通過按照建立時間來提高文檔排序的方式實現。我們在第三章中會學習關於文檔排序的知識。
除了關鍵詞查詢之外
利用像Solr這樣的搜尋引擎,使用者可以輸入少數幾個關鍵詞就能擷取到一些搜尋結果。然而對於很多使用者來說這僅僅是一個查詢互動的第一步。他們需要在查詢結果中能夠繼續地瀏覽。驅動一個資訊發現的互動會話過程也是搜素引擎的一個主要應用情境。通常使用者在搜尋前並不是很精確的知道想要查詢的資訊什麼樣的,他們事先也不知道你的系統中到底儲存了哪些資訊。一個好的搜尋引擎可以協助使用者不斷地細化資訊需求,一步步到達最需要的資訊。
這裡的核心思想是在返回使用者最初的查詢所對應的文檔結果的同時,提供給使用者一個工具,使其能夠不斷地改進查詢以獲得更需要的資訊。換句話說,在返回匹配的文檔之外,你應該返回一個工具讓使用者知道下一步該怎麼辦。舉個例子,你可以對查詢結果按照屬性進行分類,便於使用者根據需求做進一步的瀏覽。這種功能稱之為分類檢索(Faceted-Search),這也是Solr的功能亮點之一。我們會在1.2節中看到一個關於房地產的分類檢索執行個體,在第八章中會詳細介紹分類檢索功能的細節。
搜尋引擎不適合做的事…
最後,我們來討論一下不適合應用搜尋引擎的一些用例情境。首先,搜尋引擎一般的設計是,為每個查詢返回一個小的文檔集,通常包含10個到100個的結果文檔。更多的結果文檔可以通過Solr內建的結果分頁功能來擷取。對於一個查詢結果有好幾百萬個文檔的情況,如果你要求所有的匹配文檔都要能夠一次返回,那麼你會等待很長的時間。查詢本身會執行的很快,但是從索引結構中重建上百萬的文檔絕對是一件很耗時間的事情。因為Solr這樣的搜尋引擎在硬碟上儲存值域的方式只適用於快速產生少量的文檔結果,如果需要一次產生大量的查詢結果,在這種儲存方式之下產生大量文檔結果就會耗費大量的時間。
另一個不適合應用搜尋引擎的使用情境是需要讀取索引檔案的大部分子集的才能完成的深度分析任務情境。即使你通過結果分頁技術避免了剛剛說的那個問題,如果一次分析需要讀取索引檔案中的大量資料,你也會遇到很大的效能問題,因為索引檔案的底層資料結構就不是為一次大量讀取來設計的。
我們前面有提到過一點,但是在這裡還是要再次強調一下,那就是搜尋引擎技術並不適合用於在文檔的相互關係之間進行查詢。Solr確實是可以支援基於父子關係的查詢,但是並不支援在複雜的關係型資料結構之間查詢。在第三章,你會學習到如何將關係型資料結構適配到適合solr處理的扁平型文檔結構中進行查詢。
最後,絕大多數搜尋引擎都沒有直接的文檔級安全支援,至少Solr是沒有。如果你需要嚴格管理文檔的許可權,那你只能在搜尋引擎之外來想辦法。
到這裡我們已經瞭解了適合搜尋引擎處理的用例情境和資料類型,下一步該是時候討論Solr到底能做些什麼,以及這些功能是如何?的了。在下一節中,你將學習到Solr到底有哪些主要功能,以及她是如何?外部系統整合、可擴充性、以及高可用性等軟體設計原則的。
ibatis in action 中文版
百度一下,想飛社區,在資源裡有。ibatis in action 英文版+中文版。在“JAVA開發-J2EE文檔”分類下面。
Struts In Action與Struts In Action中文版2有什不同
Apache Struts 2即是之前大家所熟知的WebWork 2。在經曆了幾年的各自發展後,WebWork和Struts社區決定合二為一,也即是Struts 2
Action 類:
Struts1要求Action類繼承一個抽象基類。Struts1的一個普遍問題是使用抽象類別編程而不是介面。
Struts 2 Action類可以實現一個Action介面,也可實現其他介面,使可選和定製的服務成為可能。Struts2提供一個ActionSupport基類去實現 常用的介面。Action介面不是必須的,任何有execute標識的POJO對象都可以用作Struts2的Action對象。
線程模式:
Struts1 Action是單例模式並且必須是安全執行緒的,因為僅有Action的一個執行個體來處理所有的請求。單例策略限制了Struts1 Action能作的事,並且要在開發時特別小心。Action資源必須是安全執行緒的或同步的。
Struts2 Action對象為每一個請求產生一個執行個體,因此沒有安全執行緒問題。(實際上,servlet容器給每個請求產生許多可丟棄的對象,並且不會導致效能和記憶體回收問題)
Servlet 依賴:
Struts1 Action 依賴於Servlet API ,因為當一個Action被調用時HttpServletRequest 和 HttpServletResponse 被傳遞給execute方法。
Struts 2 Action不依賴於容器,允許Action脫離容器單獨被測試。如果需要,Struts2 Action仍然可以訪問初始的request和response。但是,其他的元素減少或者消除了直接存取HttpServetRequest 和 HttpServletResponse的必要性。
可測性:
測試Struts1 Action的一個主要問題是execute方法暴露了servlet API(這使得測試要依賴於容器)。一個第三方擴充--Struts TestCase--提供了一套Struts1的類比對象(來進行測試)。
Struts 2 Action可以通過初始化、設定屬性、調用方法來測試,“依賴注入”支援也使測試更容易。
捕獲輸入:
Struts1 使用ActionForm對象捕獲輸入。所有的ActionForm必須繼承一個基類。因為其他JavaBean不能用作ActionForm,開發人員經常建立多餘的類捕獲輸入。動態Bean(DynaBeans)可以作為建立傳統ActionForm的選擇,但是,開發人員可能是在重新描述(建立)已經存在的JavaBean(仍然會導致有冗餘的javabean)。
Struts 2直接使用Action屬性作為輸入屬性,消除了對第二個輸入對象的需求。輸入屬性可能是有自己(子)屬性的rich物件類型。Action屬效能夠通過web頁面上的taglibs訪問。Struts2也支援ActionForm模式。rich物件類型,包括業務對象,能夠用作輸入/輸出對象。這種ModelDriven 特性簡化了taglib對POJO輸入對象的引用。
運算式語言:
Struts1 整合了JSTL,因此使用JSTL EL。這種EL有基本對象圖遍曆,但是對集合和索引屬性的支援很弱。
Struts2可以使用JSTL,但是也支援一個更強大和靈活的運算式語言--"Object Graph Notation Language" (OGNL).
綁定值到頁面(view):
S......餘下全文>>