搜尋引擎入門 心臟

2021-09-30 05:42:40 字數 3114 閱讀 1083

拋開"評分"(sore)的那一部分不算,從本質上講搜尋引擎就是一全文檢索系統。全文檢索的核心就是要如何快速的找到要找的內容,所以,如何組織資料的儲存就是關鍵所以。說了那麼一長串話的意思就是,index是搜尋引擎的核心。這部分將決定處理查詢的速度有多快,要是這麼部分慢了,那你查出來的結果再精確也是白搭。lucene就是一顆很好的心臟,讓我們一起來解剖這顆心臟,來看看這顆心臟裡都有些什麼?

lucene專案始於2023年,現在(2010/09)的版本是3.0.2。說白了,lucene就是全文檢索引擎,所以,我們有必要把全文檢索介紹一下先。所謂的全文檢索就是使用者根據自己的需要輸入一串文字,檢索系統在某種資料庫中找到與使用者輸入的字串相匹配的資料。最傻瓜的做法就是"順序掃瞄"(serial scanning),就是從一堆檔案中乙個個的去開啟這些檔案,然後乙個乙個字的去比對其中的內容。這樣的做法存在三個明顯的問題: 速度,只要待查詢資料一多,速度一定是人不能接受的;結果數量太多,如果在大量的資料中查詢乙個比較常用的關鍵字,那得到的結果也是大量的;正確性,在某些語言中,詞和詞的匹配不是順序掃瞄可以解決的,特別是東方語言,例如中文。

如何解決字詞匹配的問題?分詞引擎可以解決這個問題。對類似英語的語言分詞是比較簡單的。把所有標點符號先替換成空格(或視為空格),然後,以空格為標識,把單詞乙個乙個的抓出來就可以了。但中文就麻煩了,如果把乙個個的漢字抓出來,那詞就沒有了。漢語詞比字更重要,但是漢語詞的組成沒有規律,並不是任意兩個或多個字就能組成乙個詞,乙個比較長的詞裡還會包含乙個或多個短的詞。所以,需要建立一張字典, 分詞引擎根據字典來分詞。lucene自身是帶英文的分詞引擎,因為英文的引擎比較簡單。中文的開源分詞引擎也有好幾個,其中最早的且最有影響力的就是"庖丁"(

下面來舉個例子:

原文:今天真熱,是游泳的好日子。

分出來的詞可能是這樣的:

今天 | 天真 | 熱 | 是 | 游泳 | 的 | 好 | 日子 |

這是乙個"庖丁"的實際的例子,從這個例子裡可以看出來,雖然有分詞,但智慧型的對中文進行分詞相當有挑戰性。(google使用的是這家公司提供的分詞引擎,www.basistech.com)。分出來的詞,並不能都加到索引庫中去,例如英文的"the", "a", "this"...,中文的"的","是","了"...。這些字/詞太常用了,以至於對這些詞進行索引會變的沒有意義。所以,這些高頻詞多數搜尋引擎,不會對它們進行索引。很顯然,用這些常用字來做關鍵字是搜不到有效的結果的,因為幾乎每份文件裡都會包含一堆這些常用字/詞。而且,也很少會有人來用這些字來進行查詢。但是,萬事沒有絕對呀,比如"how to",這兩個字拆開來常用吧?但,我們經常會以'how to"開頭來查一些資料不是?我記得2023年以前,如果用"how to"在google里查的話,它會提示你,你要查的關鍵字裡有"to",所以,查到的結果會很多,它已經把"to"過濾掉了,當然,現在的google已經沒這個問題了。所以,僅僅是乙個分詞,不管是針對哪一種語言的,要做到比較好,都相當有挑戰。lucene在這方面做的不是很好,只預設支援英文,而且也只支援比較基本的分詞,智慧型度並不高。

如果解決快速查詢的問題?答案是空間換時間。其實很多問題解決方案的基本方法都是很基本的,搜尋引擎提高速度的最基本思路就是以空間換時間。檔案經過分詞後,就會變成我們不能理解的字/詞表。假設,我們有兩檔案a和b,它們的原文是a: 今天真熱,是游泳的好日子。b: 今天天氣真熱,今天我一定要去海邊游泳。那經過分詞處理後,將會得到:

a --> |今天|天真|熱|游泳|好|日子|

b --> |今天|天氣|真|熱|今天|我|一定|要|去|海邊|游泳| 。

得到這兩個張表後(我們暫且反這兩張表稱為正向表,這張表可能通過檔名來得到它所包含的所有字詞),索引器就開始構造反向表,所謂反向表就是可能通過字詞來得到檔名。

a的反向表:

今天 --> a [1]

天真 --> a [1]

熱    --> a [1]

游泳 --> a [1]

好    --> a [1]

日子 --> a [1]

b的反向表:

今天  --> b [2]

天氣  --> b [1]

真     --> b [1]

熱     --> b [1]

我     --> b [1]

一定  --> b [1]

要     --> b [1]

去     --> b [1]

海邊  --> b [1]

游泳  --> b [1]

方括號""裡存的數字表示這個詞在這份檔案**現的次數。

索引庫里當然不會為每份檔案存一張反向表,這樣即浪費空間,也不能快速的查。所以,a和b的反向表就會合併到索引庫的反向表中。假設索引庫里只有a和b,那麼,索引庫里的反向表就會是這樣的。

今天 --> a [1]  --> b [2]

天氣  --> b [1]

天真 --> a [1]

真     --> b [1]

熱    --> a [1]  --> b [1]

我      --> b [1]

一定  --> b [1]

要      --> b [1]

去      --> b [1]

海邊  --> b [1]

游泳 --> a [1]  --> b [1]

好     --> a [1]

日子 --> a [1]

花括號"{}"裡的數字表示有多少檔案包含這個詞。s

這樣,如果進行簡單的查詢,那就是一目了然了。如果我們查"天氣",那馬上可以知道是檔案a;查"今天"馬上可以知道是檔案a和b。但是,人們並不會總是進行簡單的查詢,也有可能查這樣的"天氣真熱"。如果是查詢比較複雜的查詢字串,那麼查詢器會先進行分詞,得到 |天氣|真|熱|,然後,在反向表裡查到,b,b,a,b,把結果b,a,顯示出來。查詢還可以支援查詢語言例如, "天氣 and 熱 not 海邊", 查詢的結果是 天氣 --> b, 熱 --> a,b, 海邊 --> b,結果就是ab - b,得到a,顯示結果a。因為索引庫里只有兩個檔案,所以,你查到的結果總也不會超過兩個,這個問題不大。但是,實際的情況,索引庫里可能會有成千萬上億份檔案,如果只是查詢"海邊"可能會得到成百上千個結果。(在google上就能查出將近700萬個結果),總之,在一頁上,肯定是顯示不下了,那如果來對這些結果排序,就是下面要講的乙個問題了。

下面這張圖里,深色的框,就是lucene實現的部分。

搜尋引擎 索引

正排索引 文件編號,單詞編號,單詞的數量,單詞出現的位置。倒排索引 1,單詞詞典,儲存單詞以及統計資訊,單詞在記錄表中的便宜,可常駐記憶體,用雜湊表儲存。2,記錄表,單詞對應的文件集合,記錄單詞出現的數目 位置。文件採用差分變長編碼。其中文件可按編號公升序排列 可利用差分編碼 也可按出現次數排列,可...

MySQL搜尋引擎程式 mysql搜尋引擎

mysql是我們比較常用的一種資料庫軟體。它有著諸多的優點,如開源的,免費的等等。其實它還有乙個很好的特點,那就是有多種引擎可以供你選擇。如果賽車手能根據不同的路況,地形隨手更換與之最適宜的引擎,那麼他們將創造奇蹟。然而目前他們還做不到那樣便捷的更換引擎,但是我們卻可以 所謂知己知彼方可百戰不殆,要...

搜尋引擎 倒排索引

本節通過引入簡單例項,介紹與搜尋引擎索引有關的一些基礎概念,了解這些基礎概念對於後續深入了解索引的工作機制非常重要。3.1.1單詞 文件矩陣 單詞 文件矩陣是表達兩者之間所具有的一種包含關係的概念模型,圖3 1展示了其含義。圖3 1的每列代表乙個文件,每行代表乙個單詞,打對勾的位置代表包含關係。圖3...