這個文章算是自己的一個總結,說是總結其實多借鑒互聯網的前輩的文章。
學習了一段時間的solr了,用自己的方式總結下目前學到的內容,這是個系列文章,這里面的有些說法可能不準確,也可能有問題
歡迎大家指正。
一、搜索引擎目的
搜索引擎在我們的生活中,已經無處不在,除了我們常用的baidu、Google等,還有一些電商的搜索 比如亞馬遜搜書等。除了網頁搜索外,企業內部可能涉及到知識庫搜索,一般稱為企業搜索。現在搜索要主要的目的是,在海量信息中,從非結構化數據中快速找到符合我們含義的信息。注意這里的幾個關鍵詞語。
"海量信息" ?:搜索引擎一般處理的數據量很大,普通數據庫在搜索的數據量非常大的時候,比如上億條數據的時候,就算建立索引,查詢速度也不是很快,不能滿足現實的需求。
“符合我們的含義”:我覺得這可以稱為語意搜索(還沒有看到過這個叫法:),第一條也許數據庫還可以勉強達到,但是數據庫搜索難以達到符合含義這個目的,這在搜索過程中要涉及到同義詞的轉換。比如你在亞馬遜中搜索solr,可以找到Lucene、搜索引擎相關的書籍,這里面就涉及到同義詞的轉換;我覺得這是搜索引擎最重要的特征。
一般的搜索引擎都會根據相關性對我們搜索的內容和現存的文檔進行匹配,對相似度進行打分,并且按照相似度的進行排序,相似的排在前面。
"非結構化數據": 這個是指沒有固定格式和固定長度的數據,比如一篇文章,這種數據也稱為全文數據。
二、搜索引擎原理
2.1 常用的非結構化數據檢索方法
按照上節所說,搜索引擎主要處理的是非結構化數據,故名思議,非結構化數據的特點就是沒有固定的結構,這也正是處理比較困難的原因;結構化數據可以通過數據庫等方式處理。非結構化數據如何處理,據說有兩種方法:
一種是順序搜索,比如在linux下用grep方式來搜索包含特定字符串的文檔,這在文檔數量少的時候比較有效。
二種是全文檢索,它是通過對非結構化數據進行結構化轉化,對非結構化數據進行抽取(從文檔中抽取詞),然后重新組合,再利用它進行搜索。
這個被抽取出來重新組織的信息稱為索引。
第二種方法是搜索引擎中用的主要方法了。
2.2 全文檢索的三大問題
這就涉及到三個問題:1、索引里面保存什么信息?2、索引如何建立? 3、如何利用索引進行搜索?
索引保存的是什么
讓我們思考下,既然全文搜索是通過建立索引的方式進行搜索的,那么我們的索引內容必然是為了方便查找到我們要的信息的。
以搜索文章為例,假如我們需要海量的文章,為了方便管理我們給這些文章進行編號,
搜索就是要找到搜索關鍵詞和文章編號的對應關系,然后通過編號再找到對應的文檔。那么很自然的存儲的索引的內容必然有和關鍵字匹配的部分,還有文章編號的部分。
實際情況也是如此,全文搜索建立的索引簡單來說就是詞和文章編號的對應關系,由于一個詞可以放在多個文章中,所以這種索引一般就是一個個詞后面對應一串文章編號(文檔編號鏈表)。
從文章對應詞比較自然,所以從詞對應文檔是文檔對應詞的反過程,保存這種信息的索引稱為反向索引(倒排索引)。
盜用一張網上說明Lucene的倒排索引原理圖,solr是基于Lucene的,所以solr的索引也是倒排索引。
這里面,關鍵詞一般叫詞典,后面對應的一串文檔號文章號叫做倒排表。
索引如何建立
創建索引的過程盜用個網上圖,索引過程如下:
我們來思考下,我們要建立的索引為倒排索引即是詞典和倒排表。
我們首先要從文檔中得到詞,所以我們首要工作是分詞,這里面用到的就是分詞組件(Tokenizer)本次得到的結果是詞元(Token)。
其次從詞元(Token)經過語言處理組件(Linguistic Processor)的處理,輸出為詞(Term)。這一部分主要完成的是詞義轉化等
詞邊變的更純碎些。最后一步就是將詞傳遞給相關的索引組件,建立索引。
1、分詞做的主要工作
1)切詞,英語比較好拆分就是按照空格分隔,漢字要涉及到利用詞典進行切詞或單獨按照字來進行切詞。
2)去掉標點符號。
3)去掉停詞,停詞是指語言中沒有特殊含義的副詞,比如英語中的this、is、a、漢語中的“的”等。
在solr中有專門的配置文件配置停詞,stopwords_開頭的配置文件。
使得到的詞更有意義,減少索引的長度,因為停詞在很多文檔中都有,如果加到索引里面,后面的文檔號要排很長,專業名詞叫拉鏈過長。
不光占用過多的空間,而且還會導致搜索變慢。
中文由于沒有明顯的詞語直接的間隔,所以中文分詞要復雜的多。solr中默認StandardTokenizerFactory是按照字來分隔,好處是實現字級匹配,壞處索引變大。
也可以利用網上開源的分詞組件,比如:庖丁分詞、IK分詞等。
效率solr默認的分詞的建索引效率大概是IK分詞的1倍,但是查詢效率卻慢4倍原因,是按字分詞拉鏈過長原因。
2、語言處理主要工作
1)對英語來說是大小寫轉換。
2)將詞縮減或簡化為詞根。(比如cars轉成car、running轉成run)
語言處理組件得到的結果是為Term(詞)。
3、將此傳遞給索引組件
1)利用詞創建詞典和文檔ID的對應關系表。
2)按照字典順序對詞典進行排序。
3)合并相同的詞典,文檔ID變成文檔ID鏈表。
實際建立的倒排索引,還包含詞在文檔中的位置、出現的頻次等信息。
搜索過程
1)我們利用搜索引擎的語法輸入查詢的語句。我們常用的搜索引擎百度
常用語法舉例子如下:
1. ?如果你想讓百度作為整體搜索而不進行分詞,用雙引號包括。
2. ?如果你不想要一些信息可以用-號,比如手機-推廣,將不會顯示百度的推廣廣告。
3. ?比如搜索關鍵詞之間是或者關系,可以通過搜索xxx|yyy方式搜索。
2) 對查詢的語句進行詞法分析、語法分析和語義處理。
類似建索引的過程,需要進行分詞、轉化后,還有多一個內容要區分關鍵字和搜索詞、
關鍵字代表搜索詞之間的邏輯關系,在solr搜索中是op標示,比如AND標示邏輯與、
OR標示或關系,經過這種語法分析后形成一個語法樹。
3)搜索
在solr中大概分為三步完成:
1、在反向索引表中查找符合要求的文檔ID。第一次查詢返回的是文檔ID和匹配度得分。
2、根據語法樹進行邏輯與或或等操作,得到最終符合要求的文檔ID列表。
3、通過這些文檔ID列表,結合要求查詢的內容去查詢具體到具體的內容信息返回。
4)排序返回
文檔列表查到之后,把查詢的語句當做一個文檔,來計算被查詢的文檔和查詢到的文檔之間的相關度,并進行打分,
相關度高的排在前面。
相關度得分的計算比較復雜,主要涉及有:
詞頻TF: 即詞在文檔中出現的次數。
DF: 即這個詞在多少個文檔中出現。
詞的權重:詞在文檔中的重要性。