solr基本原理
場(chǎng)景:小時(shí)候我們都使用過(guò)新華字典,媽媽叫你翻開第38頁(yè),找到“坑爹”所在的位置,此時(shí)你會(huì)怎么查呢?毫無(wú)疑問(wèn),你的眼睛會(huì)從38頁(yè)的第一個(gè)字開始從頭至尾地掃描,直到找到“坑爹”二字為止。這種搜索方法叫做順序掃描法。對(duì)于少量的數(shù)據(jù),使用順序掃描是夠用的。但是媽媽叫你查出坑爹的“坑”字在哪一頁(yè)時(shí),你要是從第一頁(yè)的第一個(gè)字逐個(gè)的掃描下去,那你真的是被坑了。此時(shí)你就需要用到索引。索引記錄了“坑”字在哪一頁(yè),你只需在索引中找到“坑”字,然后找到對(duì)應(yīng)的頁(yè)碼,答案就出來(lái)了。因?yàn)樵谒饕胁檎摇翱印弊质欠浅?斓?#xff0c;因?yàn)槟阒浪钠?#xff0c;因此也就可迅速定位到這個(gè)字。
那么新華字典的目錄(索引表)是怎么編寫而成的呢?首先對(duì)于新華字典這本書來(lái)說(shuō),除去目錄后,這本書就是一堆沒(méi)有結(jié)構(gòu)的數(shù)據(jù)集。但是聰明的人類善于思考總結(jié),發(fā)現(xiàn)每個(gè)字都會(huì)對(duì)應(yīng)到一個(gè)頁(yè)碼,比如“坑”字就在第38頁(yè),“爹”字在第90頁(yè)。于是他們就從中提取這些信息,構(gòu)造成一個(gè)有結(jié)構(gòu)的數(shù)據(jù)。類似數(shù)據(jù)庫(kù)中的表結(jié)構(gòu):
word page_no --------------- 坑 38 爹 90 ... ... 這樣就形成了一個(gè)完整的目錄(索引庫(kù)),查找的時(shí)候就非常方便了。對(duì)于全文檢索也是類似的原理,它可以歸結(jié)為兩個(gè)過(guò)程:1.索引創(chuàng)建(Indexing)2. 搜索索引(Search)。那么索引到底是如何創(chuàng)建的呢?索引里面存放的又是什么東西呢?搜索的的時(shí)候又是如何去查找索引的呢?帶著這一系列問(wèn)題繼續(xù)往下看。
索引
Solr/Lucene采用的是一種反向索引,所謂反向索引:就是從關(guān)鍵字到文檔的映射過(guò)程,保存這種映射這種信息的索引稱為反向索引
- 左邊保存的是字符串序列
- 右邊是字符串的文檔(Document)編號(hào)鏈表,稱為倒排表(Posting List)
字段串列表和文檔編號(hào)鏈表兩者構(gòu)成了一個(gè)字典。現(xiàn)在想搜索”lucene”,那么索引直接告訴我們,包含有”lucene”的文檔有:2,3,10,35,92,而無(wú)需在整個(gè)文檔庫(kù)中逐個(gè)查找。如果是想搜既包含”lucene”又包含”solr”的文檔,那么與之對(duì)應(yīng)的兩個(gè)倒排表去交集即可獲得:3、10、35、92。
索引創(chuàng)建
假設(shè)有如下兩個(gè)原始文檔:
文檔一:Students should be allowed to go out with their friends, but not allowed to drink beer.
文檔二:My friend Jerry went to school to see his students but found them drunk which is not allowed.
創(chuàng)建過(guò)程大概分為如下步驟:
一:把原始文檔交給分詞組件(Tokenizer)
分詞組件(Tokenizer)會(huì)做以下幾件事情(這個(gè)過(guò)程稱為:Tokenize),處理得到的結(jié)果是詞匯單元(Token)
- 所謂停詞(Stop word)就是一種語(yǔ)言中沒(méi)有具體含義,因而大多數(shù)情況下不會(huì)作為搜索的關(guān)鍵詞,這樣一來(lái)創(chuàng)建索引時(shí)能減少索引的大小。英語(yǔ)中停詞(Stop word)如:”the”、”a”、”this”,中文有:”的,得”等。不同語(yǔ)種的分詞組件(Tokenizer),都有自己的停詞(stop word)集合。經(jīng)過(guò)分詞(Tokenizer)后得到的結(jié)果稱為詞匯單元(Token)。上例子中,便得到以下詞匯單元(Token): "Students","allowed","go","their","friends","allowed","drink","beer","My","friend","Jerry","went","school","see","his","students","found","them","drunk","allowed"
二:詞匯單元(Token)傳給語(yǔ)言處理組件(Linguistic Processor)
語(yǔ)言處理組件(linguistic processor)主要是對(duì)得到的詞元(Token)做一些語(yǔ)言相關(guān)的處理。對(duì)于英語(yǔ),語(yǔ)言處理組件(Linguistic Processor)一般做以下幾點(diǎn):
語(yǔ)言處理組件(linguistic processor)處理得到的結(jié)果稱為詞(Term),例子中經(jīng)過(guò)語(yǔ)言處理后得到的詞(Term)如下:
"student","allow","go","their","friend","allow","drink","beer","my","friend","jerry","go","school","see","his","student","find","them","drink","allow"。經(jīng)過(guò)語(yǔ)言處理后,搜索drive時(shí)drove也能被搜索出來(lái)。Stemming 和 lemmatization的異同:
- 相同之處:
- Stemming和lemmatization都要使詞匯成為詞根形式。
- 兩者的方式不同:
- Stemming采用的是”縮減”的方式:”cars”到”car”,”driving”到”drive”。
- Lemmatization采用的是”轉(zhuǎn)變”的方式:”drove”到”drove”,”driving”到”drive”。
- 兩者的算法不同:
- Stemming主要是采取某種固定的算法來(lái)做這種縮減,如去除”s”,去除”ing”加”e”,將”ational”變?yōu)椤盿te”,將”tional”變?yōu)椤眛ion”。
- Lemmatization主要是采用事先約定的格式保存某種字典中。比如字典中有”driving”到”drive”,”drove”到”drive”,”am, is, are”到”be”的映射,做轉(zhuǎn)變時(shí),按照字典中約定的方式轉(zhuǎn)換就可以了。
- Stemming和lemmatization不是互斥關(guān)系,是有交集的,有的詞利用這兩種方式都能達(dá)到相同的轉(zhuǎn)換。
三:得到的詞(Term)傳遞給索引組件(Indexer)
- Document Frequency:文檔頻次,表示多少文檔出現(xiàn)過(guò)此詞(Term)
- Frequency:詞頻,表示某個(gè)文檔中該詞(Term)出現(xiàn)過(guò)幾次
對(duì)詞(Term) “allow”來(lái)講,總共有兩篇文檔包含此詞(Term),詞(Term)后面的文檔鏈表總共有兩個(gè),第一個(gè)表示包含”allow”的第一篇文檔,即1號(hào)文檔,此文檔中,”allow”出現(xiàn)了2次,第二個(gè)表示包含”allow”的第二個(gè)文檔,是2號(hào)文檔,此文檔中,”allow”出現(xiàn)了1次
至此索引創(chuàng)建完成,搜索”drive”時(shí),”driving”,”drove”,”driven”也能夠被搜到。因?yàn)樵谒饕?#xff0c;”driving”,”drove”,”driven”都會(huì)經(jīng)過(guò)語(yǔ)言處理而變成”drive”,在搜索時(shí),如果您輸入”driving”,輸入的查詢語(yǔ)句同樣經(jīng)過(guò)分詞組件和語(yǔ)言處理組件處理的步驟,變?yōu)椴樵儭眃rive”,從而可以搜索到想要的文檔。
搜索步驟
搜索”microsoft job”,用戶的目的是希望在微軟找一份工作,如果搜出來(lái)的結(jié)果是:”Microsoft does a good job at software industry…”,這就與用戶的期望偏離太遠(yuǎn)了。如何進(jìn)行合理有效的搜索,搜索出用戶最想要得結(jié)果呢?搜索主要有如下步驟:
一:對(duì)查詢內(nèi)容進(jìn)行詞法分析、語(yǔ)法分析、語(yǔ)言處理
二:搜索索引,得到符合語(yǔ)法樹的文檔集合
三:根據(jù)查詢語(yǔ)句與文檔的相關(guān)性,對(duì)結(jié)果進(jìn)行排序
我們把查詢語(yǔ)句也看作是一個(gè)文檔,對(duì)文檔與文檔之間的相關(guān)性(relevance)進(jìn)行打分(scoring),分?jǐn)?shù)高比較越相關(guān),排名就越靠前。當(dāng)然還可以人工影響打分,比如百度搜索,就不一定完全按照相關(guān)性來(lái)排名的。
如何評(píng)判文檔之間的相關(guān)性?一個(gè)文檔由多個(gè)(或者一個(gè))詞(Term)組成,比如:”solr”, “toturial”,不同的詞可能重要性不一樣,比如solr就比toturial重要,如果一個(gè)文檔出現(xiàn)了10次toturial,但只出現(xiàn)了一次solr,而另一文檔solr出現(xiàn)了4次,toturial出現(xiàn)一次,那么后者很有可能就是我們想要的搜的結(jié)果。這就引申出權(quán)重(Term weight)的概念。
權(quán)重表示該詞在文檔中的重要程度,越重要的詞當(dāng)然權(quán)重越高,因此在計(jì)算文檔相關(guān)性時(shí)影響力就更大。通過(guò)詞之間的權(quán)重得到文檔相關(guān)性的過(guò)程叫做空間向量模型算法(Vector Space Model)
影響一個(gè)詞在文檔中的重要性主要有兩個(gè)方面:
- Term Frequencey(tf),Term在此文檔中出現(xiàn)的頻率,ft越大表示越重要
- Document Frequency(df),表示有多少文檔中出現(xiàn)過(guò)這個(gè)Trem,df越大表示越不重要
物以希為貴,大家都有的東西,自然就不那么貴重了,只有你專有的東西表示這個(gè)東西很珍貴,權(quán)重的公式:
空間向量模型
文檔中詞的權(quán)重看作一個(gè)向量
Document = {term1, term2, …… ,term N} Document Vector = {weight1, weight2, …… ,weight N}把欲要查詢的語(yǔ)句看作一個(gè)簡(jiǎn)單的文檔,也用向量表示:
Query = {term1, term 2, …… , term N} Query Vector = {weight1, weight2, …… , weight N} 把搜索出的文檔向量及查詢向量放入N維度的空間中,每個(gè)詞表示一維:
夾角越小,表示越相似,相關(guān)性越大
總結(jié)
- 上一篇: 如何获取服务器的地理位置,如何获取Res
- 下一篇: 天猫整站SSM-分页-herf(做个人学