如何基于solr實現(xiàn)全文檢索

這篇文章將為大家詳細講解有關(guān)如何基于solr實現(xiàn)全文檢索,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

我們提供的服務(wù)有:成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、懷柔ssl等。為上千家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的懷柔網(wǎng)站制作公司

Solr是一個獨立的企業(yè)級搜索應(yīng)用服務(wù)器,它對外提供類似于Web-service的API接口。用戶可以通過http請求,向搜索引擎服務(wù)器提交一定格式的XML文件,生成索引;也可以通過Http Get操作提出查找請求,并得到XML/Json格式的返回結(jié)果。采用Java5開發(fā),基于Lucene。

Lucene是apache軟件基金會4 jakarta項目組的一個子項目,是一個開放源代碼的全文檢索引擎工具包,即它不是一個完整的全文檢索引擎,而是一個全文檢索引擎的架構(gòu),提供了完整的查詢引擎和索引引擎,部分文本分析引擎(英文與德文兩種西方語言)。

一、總論

根據(jù)http://lucene.apache.org/java/docs/index.html定義:

Lucene是一個高效的,基于Java的全文檢索庫。

所以在了解Lucene之前要費一番工夫了解一下全文檢索。

那么什么叫做全文檢索呢?這要從我們生活中的數(shù)據(jù)說起。

我們生活中的數(shù)據(jù)總體分為兩種:結(jié)構(gòu)化數(shù)據(jù)和非結(jié)構(gòu)化數(shù)據(jù)。

?結(jié)構(gòu)化數(shù)據(jù):指具有固定格式或有限長度的數(shù)據(jù),如數(shù)據(jù)庫,元數(shù)據(jù)等。

?非結(jié)構(gòu)化數(shù)據(jù):指不定長或無固定格式的數(shù)據(jù),如郵件,word文檔等。

當(dāng)然有的地方還會提到第三種,半結(jié)構(gòu)化數(shù)據(jù),如XML,HTML等,當(dāng)根據(jù)需要可按結(jié)構(gòu)化數(shù)據(jù)來處理,也可抽取出純文本按非結(jié)構(gòu)化數(shù)據(jù)來處理。

非結(jié)構(gòu)化數(shù)據(jù)又一種叫法叫全文數(shù)據(jù)。

按照數(shù)據(jù)的分類,搜索也分為兩種:

?對結(jié)構(gòu)化數(shù)據(jù)的搜索:如對數(shù)據(jù)庫的搜索,用SQL語句。再如對元數(shù)據(jù)的搜索,如利用windows搜索對文件名,類型,修改時間進行搜索等。

?對非結(jié)構(gòu)化數(shù)據(jù)的搜索:如利用windows的搜索也可以搜索文件內(nèi)容,Linux下的grep命令,再如用Google和百度可以搜索大量內(nèi)容數(shù)據(jù)。

對非結(jié)構(gòu)化數(shù)據(jù)也即對全文數(shù)據(jù)的搜索主要有兩種方法:

一種是順序掃描法(Serial Scanning):所謂順序掃描,比如要找內(nèi)容包含某一個字符串的文件,就是一個文檔一個文檔的看,對于每一個文檔,從頭看到尾,如果此文檔包含此字符串,則此文檔為我們要找的文件,接著看下一個文件,直到掃描完所有的文件。如利用windows的搜索也可以搜索文件內(nèi)容,只是相當(dāng)?shù)穆?。如果你有一個80G硬盤,如果想在上面找到一個內(nèi)容包含某字符串的文件,不花他幾個小時,怕是做不到。Linux下的grep命令也是這一種方式。大家可能覺得這種方法比較原始,但對于小數(shù)據(jù)量的文件,這種方法還是最直接,最方便的。但是對于大量的文件,這種方法就很慢了。

有人可能會說,對非結(jié)構(gòu)化數(shù)據(jù)順序掃描很慢,對結(jié)構(gòu)化數(shù)據(jù)的搜索卻相對較快(由于結(jié)構(gòu)化數(shù)據(jù)有一定的結(jié)構(gòu)可以采取一定的搜索算法加快速度),那么把我們的非結(jié)構(gòu)化數(shù)據(jù)想辦法弄得有一定結(jié)構(gòu)不就行了嗎?

這種想法很天然,卻構(gòu)成了全文檢索的基本思路,也即將非結(jié)構(gòu)化數(shù)據(jù)中的一部分信息提取出來,重新組織,使其變得有一定結(jié)構(gòu),然后對此有一定結(jié)構(gòu)的數(shù)據(jù)進行搜索,從而達到搜索相對較快的目的。

這部分從非結(jié)構(gòu)化數(shù)據(jù)中提取出的然后重新組織的信息,我們稱之索引。

這種說法比較抽象,舉幾個例子就很容易明白,比如字典,字典的拼音表和部首檢字表就相當(dāng)于字典的索引,對每一個字的解釋是非結(jié)構(gòu)化的,如果字典沒有音節(jié)表和部首檢字表,在茫茫辭海中找一個字只能順序掃描。然而字的某些信息可以提取出來進行結(jié)構(gòu)化處理,比如讀音,就比較結(jié)構(gòu)化,分聲母和韻母,分別只有幾種可以一一列舉,于是將讀音拿出來按一定的順序排列,每一項讀音都指向此字的詳細解釋的頁數(shù)。我們搜索時按結(jié)構(gòu)化的拼音搜到讀音,然后按其指向的頁數(shù),便可找到我們的非結(jié)構(gòu)化數(shù)據(jù)——也即對字的解釋。

這種先建立索引,再對索引進行搜索的過程就叫全文檢索(Full-text Search)。

下面這幅圖來自《Lucene in action》,但卻不僅僅描述了Lucene的檢索過程,而是描述了全文檢索的一般過程。

如何基于solr實現(xiàn)全文檢索

全文檢索大體分兩個過程,索引創(chuàng)建(Indexing)和搜索索引(Search)。

?索引創(chuàng)建:將現(xiàn)實世界中所有的結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù)提取信息,創(chuàng)建索引的過程。

?搜索索引:就是得到用戶的查詢請求,搜索創(chuàng)建的索引,然后返回結(jié)果的過程。

于是全文檢索就存在三個重要問題:

1. 索引里面究竟存些什么?(Index)

2. 如何創(chuàng)建索引?(Indexing)

3. 如何對索引進行搜索?(Search)

下面我們順序?qū)γ總€個問題進行研究。

二、索引里面究竟存些什么

索引里面究竟需要存些什么呢?

首先我們來看為什么順序掃描的速度慢:

其實是由于我們想要搜索的信息和非結(jié)構(gòu)化數(shù)據(jù)中所存儲的信息不一致造成的。

非結(jié)構(gòu)化數(shù)據(jù)中所存儲的信息是每個文件包含哪些字符串,也即已知文件,欲求字符串相對容易,也即是從文件到字符串的映射。而我們想搜索的信息是哪些文件包含此字符串,也即已知字符串,欲求文件,也即從字符串到文件的映射。兩者恰恰相反。于是如果索引總能夠保存從字符串到文件的映射,則會大大提高搜索速度。

由于從字符串到文件的映射是文件到字符串映射的反向過程,于是保存這種信息的索引稱為反向索引。

反向索引的所保存的信息一般如下:

假設(shè)我的文檔集合里面有100篇文檔,為了方便表示,我們?yōu)槲臋n編號從1到100,得到下面的結(jié)構(gòu)

如何基于solr實現(xiàn)全文檢索

左邊保存的是一系列字符串,稱為詞典。

每個字符串都指向包含此字符串的文檔(Document)鏈表,此文檔鏈表稱為倒排表(Posting List)。

有了索引,便使保存的信息和要搜索的信息一致,可以大大加快搜索的速度。

比如說,我們要尋找既包含字符串“l(fā)ucene”又包含字符串“solr”的文檔,我們只需要以下幾步:

1. 取出包含字符串“l(fā)ucene”的文檔鏈表。

2. 取出包含字符串“solr”的文檔鏈表。

3. 通過合并鏈表,找出既包含“l(fā)ucene”又包含“solr”的文件。

如何基于solr實現(xiàn)全文檢索

看到這個地方,有人可能會說,全文檢索的確加快了搜索的速度,但是多了索引的過程,兩者加起來不一定比順序掃描快多少。的確,加上索引的過程,全文檢索不一定比順序掃描快,尤其是在數(shù)據(jù)量小的時候更是如此。而對一個很大量的數(shù)據(jù)創(chuàng)建索引也是一個很慢的過程。

然而兩者還是有區(qū)別的,順序掃描是每次都要掃描,而創(chuàng)建索引的過程僅僅需要一次,以后便是一勞永逸的了,每次搜索,創(chuàng)建索引的過程不必經(jīng)過,僅僅搜索創(chuàng)建好的索引就可以了。

這也是全文搜索相對于順序掃描的優(yōu)勢之一:一次索引,多次使用。

三、如何創(chuàng)建索引

全文檢索的索引創(chuàng)建過程一般有以下幾步:

第一步:一些要索引的原文檔(Document)。

為了方便說明索引創(chuàng)建過程,這里特意用兩個文件為例:

文件一: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.

第二步:將原文檔傳給分次組件(Tokenizer)。

分詞組件(Tokenizer)會做以下幾件事情(此過程稱為Tokenize):

1. 將文檔分成一個一個單獨的單詞。

2. 去除標(biāo)點符號。

3. 去除停詞(Stop word)。

所謂停詞(Stop word)就是一種語言中最普通的一些單詞,由于沒有特別的意義,因而大多數(shù)情況下不能成為搜索的關(guān)鍵詞,因而創(chuàng)建索引時,這種詞會被去掉而減少索引的大小。

英語中挺詞(Stop word)如:“the”,“a”,“this”等。

對于每一種語言的分詞組件(Tokenizer),都有一個停詞(stop word)集合。

經(jīng)過分詞(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)傳給語言處理組件(Linguistic Processor)。

語言處理組件(linguistic processor)主要是對得到的詞元(Token)做一些同語言相關(guān)的處理。

對于英語,語言處理組件(Linguistic Processor)一般做以下幾點:

1. 變?yōu)樾?Lowercase)。

2. 將單詞縮減為詞根形式,如“cars”到“car”等。這種操作稱為:stemming。

3. 將單詞轉(zhuǎn)變?yōu)樵~根形式,如“drove”到“drive”等。這種操作稱為:lemmatization。

Stemming 和 lemmatization的異同:

?相同之處:Stemming和lemmatization都要使詞匯成為詞根形式。

?兩者的方式不同:

?Stemming采用的是“縮減”的方式:“cars”到“car”,“driving”到“drive”。

?Lemmatization采用的是“轉(zhuǎn)變”的方式:“drove”到“drove”,“driving”到“drive”。

?兩者的算法不同:

?Stemming主要是采取某種固定的算法來做這種縮減,如去除“s”,去除“ing”加“e”,將“ational”變?yōu)椤癮te”,將“tional”變?yōu)椤皌ion”。

?Lemmatization主要是采用保存某種字典的方式做這種轉(zhuǎn)變。比如字典中有“driving”到“drive”,“drove”到“drive”,“am, is, are”到“be”的映射,做轉(zhuǎn)變時,只要查字典就可以了。

?Stemming和lemmatization不是互斥關(guān)系,是有交集的,有的詞利用這兩種方式都能達到相同的轉(zhuǎn)換。

語言處理組件(linguistic processor)的結(jié)果稱為詞(Term)。

在我們的例子中,經(jīng)過語言處理,得到的詞(Term)如下:

“student”,“allow”,“go”,“their”,“friend”,“allow”,“drink”,“beer”,“my”,“friend”,“jerry”,“go”,“school”,“see”,“his”,“student”,“find”,“them”,“drink”,“allow”。

也正是因為有語言處理的步驟,才能使搜索drove,而drive也能被搜索出來。

第四步:將得到的詞(Term)傳給索引組件(Indexer)。

索引組件(Indexer)主要做以下幾件事情:

1. 利用得到的詞(Term)創(chuàng)建一個字典。

在我們的例子中字典如下:

Term

Document ID

student

1

allow

1

go

1

their

1

friend

1

allow

1

drink

1

beer

1

my

2

friend

2

jerry

2

go

2

school

2

see

2

his

2

student

2

find

2

them

2

drink

2

allow

2

2. 對字典按字母順序進行排序。

Term

Document ID

allow

1

allow

1

allow

2

beer

1

drink

1

drink

2

find

2

friend

1

friend

2

go

1

go

2

his

2

jerry

2

my

2

school

2

see

2

student

1

student

2

their

1

them

2

?Document Frequency 即文檔頻次,表示總共有多少文件包含此詞(Term)。

?Frequency 即詞頻率,表示此文件中包含了幾個此詞(Term)。

所以對詞(Term) “allow”來講,總共有兩篇文檔包含此詞(Term),從而詞(Term)后面的文檔鏈表總共有兩項,第一項表示包含“allow”的第一篇文檔,即1號文檔,此文檔中,“allow”出現(xiàn)了2次,第二項表示包含“allow”的第二個文檔,是2號文檔,此文檔中,“allow”出現(xiàn)了1次。

到此為止,索引已經(jīng)創(chuàng)建好了,我們可以通過它很快的找到我們想要的文檔。

而且在此過程中,我們驚喜地發(fā)現(xiàn),搜索“drive”,“driving”,“drove”,“driven”也能夠被搜到。因為在我們的索引中,“driving”,“drove”,“driven”都會經(jīng)過語言處理而變成“drive”,在搜索時,如果您輸入“driving”,輸入的查詢語句同樣經(jīng)過我們這里的一到三步,從而變?yōu)椴樵儭癲rive”,從而可以搜索到想要的文檔。

三、如何對索引進行搜索?

到這里似乎我們可以宣布“我們找到想要的文檔了”。

然而事情并沒有結(jié)束,找到了僅僅是全文檢索的一個方面。不是嗎?如果僅僅只有一個或十個文檔包含我們查詢的字符串,我們的確找到了。然而如果結(jié)果有一千個,甚至成千上萬個呢?那個又是您最想要的文件呢?

打開Google吧,比如說您想在微軟找份工作,于是您輸入“Microsoft job”,您卻發(fā)現(xiàn)總共有22600000個結(jié)果返回。好大的數(shù)字呀,突然發(fā)現(xiàn)找不到是一個問題,找到的太多也是一個問題。在如此多的結(jié)果中,如何將最相關(guān)的放在最前面呢?

如何基于solr實現(xiàn)全文檢索

當(dāng)然Google做的很不錯,您一下就找到了jobs at Microsoft。想象一下,如果前幾個全部是“Microsoft does a good job at software industry…”將是多么可怕的事情呀。

如何像Google一樣,在成千上萬的搜索結(jié)果中,找到和查詢語句最相關(guān)的呢?

如何判斷搜索出的文檔和查詢語句的相關(guān)性呢?

這要回到我們第三個問題:如何對索引進行搜索?

搜索主要分為以下幾步:

第一步:用戶輸入查詢語句。

查詢語句同我們普通的語言一樣,也是有一定語法的。

不同的查詢語句有不同的語法,如SQL語句就有一定的語法。

查詢語句的語法根據(jù)全文檢索系統(tǒng)的實現(xiàn)而不同。最基本的有比如:AND, OR, NOT等。

舉個例子,用戶輸入語句:lucene AND learned NOT hadoop。

說明用戶想找一個包含lucene和learned然而不包括hadoop的文檔。

第二步:對查詢語句進行詞法分析,語法分析,及語言處理。

由于查詢語句有語法,因而也要進行語法分析,語法分析及語言處理。

1. 詞法分析主要用來識別單詞和關(guān)鍵字。

如上述例子中,經(jīng)過詞法分析,得到單詞有l(wèi)ucene,learned,hadoop, 關(guān)鍵字有AND, NOT。

如果在詞法分析中發(fā)現(xiàn)不合法的關(guān)鍵字,則會出現(xiàn)錯誤。如lucene AMD learned,其中由于AND拼錯,導(dǎo)致AMD作為一個普通的單詞參與查詢。

2. 語法分析主要是根據(jù)查詢語句的語法規(guī)則來形成一棵語法樹。

如果發(fā)現(xiàn)查詢語句不滿足語法規(guī)則,則會報錯。如lucene NOT AND learned,則會出錯。

如上述例子,lucene AND learned NOT hadoop形成的語法樹如下:

如何基于solr實現(xiàn)全文檢索

3. 語言處理同索引過程中的語言處理幾乎相同。

如learned變成learn等。

經(jīng)過第二步,我們得到一棵經(jīng)過語言處理的語法樹。

如何基于solr實現(xiàn)全文檢索

第三步:搜索索引,得到符合語法樹的文檔。

此步驟有分幾小步:

1.首先,在反向索引表中,分別找出包含lucene,learn,hadoop的文檔鏈表。

2.其次,對包含lucene,learn的鏈表進行合并操作,得到既包含lucene又包含learn的文檔鏈表。

3.然后,將此鏈表與hadoop的文檔鏈表進行差操作,去除包含hadoop的文檔,從而得到既包含lucene又包含learn而且不包含hadoop的文檔鏈表。

4.此文檔鏈表就是我們要找的文檔。

第四步:根據(jù)得到的文檔和查詢語句的相關(guān)性,對結(jié)果進行排序。

雖然在上一步,我們得到了想要的文檔,然而對于查詢結(jié)果應(yīng)該按照與查詢語句的相關(guān)性進行排序,越相關(guān)者越靠前。

如何計算文檔和查詢語句的相關(guān)性呢?

不如我們把查詢語句看作一片短小的文檔,對文檔與文檔之間的相關(guān)性(relevance)進行打分(scoring),分?jǐn)?shù)高的相關(guān)性好,就應(yīng)該排在前面。

那么又怎么對文檔之間的關(guān)系進行打分呢?

這可不是一件容易的事情,首先我們看一看判斷人之間的關(guān)系吧。

首先看一個人,往往有很多要素,如性格,信仰,愛好,衣著,高矮,胖瘦等等。

其次對于人與人之間的關(guān)系,不同的要素重要性不同,性格,信仰,愛好可能重要些,衣著,高矮,胖瘦可能就不那么重要了,所以具有相同或相似性格,信仰,愛好的人比較容易成為好的朋友,然而衣著,高矮,胖瘦不同的人,也可以成為好的朋友。

因而判斷人與人之間的關(guān)系,首先要找出哪些要素對人與人之間的關(guān)系最重要,比如性格,信仰,愛好。其次要判斷兩個人的這些要素之間的關(guān)系,比如一個人性格開朗,另一個人性格外向,一個人信仰佛教,另一個信仰上帝,一個人愛好打籃球,另一個愛好踢足球。我們發(fā)現(xiàn),兩個人在性格方面都很積極,信仰方面都很善良,愛好方面都愛運動,因而兩個人關(guān)系應(yīng)該會很好。

我們再來看看公司之間的關(guān)系吧。

首先看一個公司,有很多人組成,如總經(jīng)理,經(jīng)理,首席技術(shù)官,普通員工,保安,門衛(wèi)等。

其次對于公司與公司之間的關(guān)系,不同的人重要性不同,總經(jīng)理,經(jīng)理,首席技術(shù)官可能更重要一些,普通員工,保安,門衛(wèi)可能較不重要一點。所以如果兩個公司總經(jīng)理,經(jīng)理,首席技術(shù)官之間關(guān)系比較好,兩個公司容易有比較好的關(guān)系。然而一位普通員工就算與另一家公司的一位普通員工有血海深仇,怕也難影響兩個公司之間的關(guān)系。

因而判斷公司與公司之間的關(guān)系,首先要找出哪些人對公司與公司之間的關(guān)系最重要,比如總經(jīng)理,經(jīng)理,首席技術(shù)官。其次要判斷這些人之間的關(guān)系,不如兩家公司的總經(jīng)理曾經(jīng)是同學(xué),經(jīng)理是老鄉(xiāng),首席技術(shù)官曾是創(chuàng)業(yè)伙伴。我們發(fā)現(xiàn),兩家公司無論總經(jīng)理,經(jīng)理,首席技術(shù)官,關(guān)系都很好,因而兩家公司關(guān)系應(yīng)該會很好。

分析了兩種關(guān)系,下面看一下如何判斷文檔之間的關(guān)系了。

首先,一個文檔有很多詞(Term)組成,如search, lucene, full-text, this, a, what等。

其次對于文檔之間的關(guān)系,不同的Term重要性不同,比如對于本篇文檔,search, Lucene, full-text就相對重要一些,this, a , what可能相對不重要一些。所以如果兩篇文檔都包含search, Lucene,fulltext,這兩篇文檔的相關(guān)性好一些,然而就算一篇文檔包含this, a, what,另一篇文檔不包含this, a, what,也不能影響兩篇文檔的相關(guān)性。

因而判斷文檔之間的關(guān)系,首先找出哪些詞(Term)對文檔之間的關(guān)系最重要,如search, Lucene, fulltext。然后判斷這些詞(Term)之間的關(guān)系。

找出詞(Term)對文檔的重要性的過程稱為計算詞的權(quán)重(Term weight)的過程。

計算詞的權(quán)重(term weight)有兩個參數(shù),第一個是詞(Term),第二個是文檔(Document)。

詞的權(quán)重(Term weight)表示此詞(Term)在此文檔中的重要程度,越重要的詞(Term)有越大的權(quán)重(Term weight),因而在計算文檔之間的相關(guān)性中將發(fā)揮更大的作用。

判斷詞(Term)之間的關(guān)系從而得到文檔相關(guān)性的過程應(yīng)用一種叫做向量空間模型的算法(Vector Space Model)。

下面仔細分析一下這兩個過程:

1. 計算權(quán)重(Term weight)的過程。

影響一個詞(Term)在一篇文檔中的重要性主要有兩個因素:

?Term Frequency (tf):即此Term在此文檔中出現(xiàn)了多少次。tf 越大說明越重要。

?Document Frequency (df):即有多少文檔包含次Term。df 越大說明越不重要。

容易理解嗎?詞(Term)在文檔中出現(xiàn)的次數(shù)越多,說明此詞(Term)對該文檔越重要,如“搜索”這個詞,在本文檔中出現(xiàn)的次數(shù)很多,說明本文檔主要就是講這方面的事的。然而在一篇英語文檔中,this出現(xiàn)的次數(shù)更多,就說明越重要嗎?不是的,這是由第二個因素進行調(diào)整,第二個因素說明,有越多的文檔包含此詞(Term), 說明此詞(Term)太普通,不足以區(qū)分這些文檔,因而重要性越低。

這也如我們程序員所學(xué)的技術(shù),對于程序員本身來說,這項技術(shù)掌握越深越好(掌握越深說明花時間看的越多,tf越大),找工作時越有競爭力。然而對于所有程序員來說,這項技術(shù)懂得的人越少越好(懂得的人少df?。?,找工作越有競爭力。人的價值在于不可替代性就是這個道理。

道理明白了,我們來看看公式:

如何基于solr實現(xiàn)全文檢索

如何基于solr實現(xiàn)全文檢索

這僅僅只term weight計算公式的簡單典型實現(xiàn)。實現(xiàn)全文檢索系統(tǒng)的人會有自己的實現(xiàn),Lucene就與此稍有不同。

2. 判斷Term之間的關(guān)系從而得到文檔相關(guān)性的過程,也即向量空間模型的算法(VSM)。

我們把文檔看作一系列詞(Term),每一個詞(Term)都有一個權(quán)重(Term weight),不同的詞(Term)根據(jù)自己在文檔中的權(quán)重來影響文檔相關(guān)性的打分計算。

于是我們把所有此文檔中詞(term)的權(quán)重(term weight) 看作一個向量。

Document = {term1, term2, …… ,term N}

Document Vector = {weight1, weight2, …… ,weight N}

同樣我們把查詢語句看作一個簡單的文檔,也用向量來表示。

Query = {term1, term 2, …… , term N}

Query Vector = {weight1, weight2, …… , weight N}

我們把所有搜索出的文檔向量及查詢向量放到一個N維空間中,每個詞(term)是一維。

如圖:

如何基于solr實現(xiàn)全文檢索

我們認(rèn)為兩個向量之間的夾角越小,相關(guān)性越大。

所以我們計算夾角的余弦值作為相關(guān)性的打分,夾角越小,余弦值越大,打分越高,相關(guān)性越大。

有人可能會問,查詢語句一般是很短的,包含的詞(Term)是很少的,因而查詢向量的維數(shù)很小,而文檔很長,包含詞(Term)很多,文檔向量維數(shù)很大。你的圖中兩者維數(shù)怎么都是N呢?

在這里,既然要放到相同的向量空間,自然維數(shù)是相同的,不同時,取二者的并集,如果不含某個詞(Term)時,則權(quán)重(Term Weight)為0。

相關(guān)性打分公式如下:

如何基于solr實現(xiàn)全文檢索

舉個例子,查詢語句有11個Term,共有三篇文檔搜索出來。其中各自的權(quán)重(Term weight),如下表格。

t1

t2

t3

t4

t5

t6

t7

t8

t9

t10

t11

D1

0

0

.477

0

.477

.176

0

0

0

.176

0

D2

0

.176

0

.477

0

0

0

0

.954

0

.176

D3

0

.176

0

0

0

.176

0

0

0

.176

.176

Q

0

0

0

0

0

.176

0

0

.477

0

.176

于是計算,三篇文檔同查詢語句的相關(guān)性打分分別為:

如何基于solr實現(xiàn)全文檢索

如何基于solr實現(xiàn)全文檢索

如何基于solr實現(xiàn)全文檢索

于是文檔二相關(guān)性最高,先返回,其次是文檔一,最后是文檔三。

到此為止,我們可以找到我們最想要的文檔了。

說了這么多,其實還沒有進入到Lucene,而僅僅是信息檢索技術(shù)(Information retrieval)中的基本理論,然而當(dāng)我們看過Lucene后我們會發(fā)現(xiàn),Lucene是對這種基本理論的一種基本的的實踐。所以在以后分析Lucene的文章中,會常常看到以上理論在Lucene中的應(yīng)用。

在進入Lucene之前,對上述索引創(chuàng)建和搜索過程所一個總結(jié),如圖:

此圖參照http://www.lucene.com.cn/about.htm中文章《開放源代碼的全文檢索引擎Lucene》

如何基于solr實現(xiàn)全文檢索

1. 索引過程:

1) 有一系列被索引文件

2) 被索引文件經(jīng)過語法分析和語言處理形成一系列詞(Term)。

3) 經(jīng)過索引創(chuàng)建形成詞典和反向索引表。

4) 通過索引存儲將索引寫入硬盤。

2. 搜索過程:

a) 用戶輸入查詢語句。

b) 對查詢語句經(jīng)過語法分析和語言分析得到一系列詞(Term)。

c) 通過語法分析得到一個查詢樹。

d) 通過索引存儲將索引讀入到內(nèi)存。

e) 利用查詢樹搜索索引,從而得到每個詞(Term)的文檔鏈表,對文檔鏈表進行交,差,并得到結(jié)果文檔。

f) 將搜索到的結(jié)果文檔對查詢的相關(guān)性進行排序。

g) 返回查詢結(jié)果給用戶。

2. 對字典按字母順序進行排序。

Term

Document ID

allow

1

allow

1

allow

2

beer

1

drink

1

drink

2

find

2

friend

1

friend

2

go

1

go

2

his

2

jerry

2

my

2

school

2

see

2

student

1

student

2

their

1

them

2

3. 合并相同的詞(Term)成為文檔倒排(Posting List)鏈表。

如何基于solr實現(xiàn)全文檢索

關(guān)于“如何基于solr實現(xiàn)全文檢索”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

本文名稱:如何基于solr實現(xiàn)全文檢索
文章網(wǎng)址:http://muchs.cn/article6/jcjeog.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、定制開發(fā)、小程序開發(fā)、營銷型網(wǎng)站建設(shè)、手機網(wǎng)站建設(shè)、企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)