新聞中心
引子

為璧山等地區(qū)用戶(hù)提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及璧山網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為做網(wǎng)站、成都網(wǎng)站制作、璧山網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專(zhuān)業(yè)、用心的態(tài)度為用戶(hù)提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶(hù)的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
時(shí)間回到20年前。
張大胖學(xué)校的圖書(shū)館網(wǎng)站上線了,張大胖去瀏覽了一番,發(fā)現(xiàn)竟然沒(méi)有按照關(guān)鍵字搜索圖書(shū)的功能,大為吃驚之余,又隱約覺(jué)得機(jī)會(huì)來(lái)了: 我剛學(xué)完Web開(kāi)發(fā),其中也有數(shù)據(jù)庫(kù)相關(guān)的知識(shí),也許我可以實(shí)現(xiàn)這個(gè)功能??!
想到此處,張大胖趕緊查找聯(lián)系方式,抱著試試看的態(tài)度給圖書(shū)館的管理員發(fā)了一封電子郵件,表達(dá)了能實(shí)現(xiàn)這個(gè)搜索功能的信心和決心。
沒(méi)想到真的收到回信了,管理員王老師讓他在周四的下午2點(diǎn)半到圖書(shū)館3樓307聊一聊。
周四下午,張大胖沐浴更衣以后,如約而至。 經(jīng)過(guò)一番寒暄和介紹,王老師正式進(jìn)入主題:你打算怎么實(shí)現(xiàn)這個(gè)全文檢索功能???
張大胖說(shuō):“我可以用SQL的 Like來(lái)實(shí)現(xiàn)?!?/p>
王老師笑了:“數(shù)據(jù)量小的時(shí)候Like還湊合,數(shù)據(jù)量一大,效率就非常低了?!?/p>
張大胖有點(diǎn)蒙:“那怎么辦?”
王老師說(shuō):“得用inverted index才行?!?/p>
張大胖知道什么是index, 但是從來(lái)沒(méi)有聽(tīng)說(shuō)過(guò)inverted index,這是什么鬼?
王老師看到他迷茫的臉色,就知道這小子雖然勇氣可嘉,但是技術(shù)還是有所欠缺,鼓勵(lì)到:“這樣吧,你回去研究研究inverted index, 然后再來(lái)實(shí)現(xiàn)這個(gè)全文檢索功能?!?/p>
Inverted Index
張大胖灰溜溜地回到宿舍,趕緊撥號(hào)上網(wǎng)去查這個(gè)inverted index。
張大胖發(fā)現(xiàn)有很多人把他翻譯成倒排索引,聽(tīng)起來(lái)雖然有點(diǎn)古怪,但實(shí)際上是一個(gè)非常簡(jiǎn)單的概念。 比如說(shuō)有兩篇文檔:
文檔1的內(nèi)容:A computer is a device that can execute operations
文檔2的內(nèi)容:Early computers are big devices
把這兩篇文章中的單詞都抽取出來(lái),并且記錄下這些單詞出現(xiàn)在哪個(gè)文檔中,這就形成了一個(gè)簡(jiǎn)單粗糙的倒排索引。
通過(guò)這個(gè)“倒排索引”,只要給出一個(gè)單詞,就可以迅速地定位到它在哪個(gè)文檔中。 用來(lái)做全文搜素非常合適。
但是上面的倒排索引有點(diǎn)“粗糙”,還可以在“精化”一下。
1. 對(duì)于 a, is , to ,that ,can ,the,are 這些詞對(duì)搜索來(lái)說(shuō)沒(méi)什么意義,用戶(hù)幾乎不會(huì)用他們搜索,可以過(guò)濾掉。
2. 用戶(hù)搜索的時(shí)候雖然輸入了computer,但是也希望搜出computers出來(lái),所以需要把復(fù)數(shù)單詞,過(guò)去式單詞等做還原。
3. 用戶(hù)雖然輸入了device , 但是也希望搜索出Device出來(lái),所以需要把大寫(xiě)都改成小寫(xiě)。
經(jīng)過(guò)這番轉(zhuǎn)換,文檔1和文檔2的關(guān)鍵字變成了這樣:
文檔1:[computer] [device] [execute] [operation]
文檔2:[early] [computer] [big] [device]
相應(yīng)地,倒排索引變成了這樣:
當(dāng)用戶(hù)想搜索device 的時(shí)候,我們就可以告訴它,在文檔1和文檔2中都有。
為了更好的統(tǒng)計(jì)和高亮顯示搜索結(jié)果,還可以記錄關(guān)鍵詞在文章中出現(xiàn)的次數(shù)和位置(例如:是第幾個(gè)單詞)
架構(gòu)
明白了inverted index是怎么回事兒, 張大胖覺(jué)得只要把那些書(shū)籍的標(biāo)題,介紹,作者等信息給提取出來(lái),形成inverted index,不就可以做關(guān)鍵字檢索了嗎?
可是轉(zhuǎn)眼一想,這個(gè)需求應(yīng)該是個(gè)通用的需求,不僅是圖書(shū)館有,很多互聯(lián)網(wǎng)應(yīng)用,例如網(wǎng)上商城也需要, 我完全可以設(shè)計(jì)一個(gè)類(lèi)庫(kù)出來(lái),讓大家去使用啊。
張大胖迅速畫(huà)出一個(gè)架構(gòu)圖出來(lái):
看看,不管你是什么類(lèi)型的文檔,HTML, PDF, Word,甚至是數(shù)據(jù)庫(kù)的數(shù)據(jù),只要能從中抽取出文本,就可以當(dāng)作我的數(shù)據(jù)源,對(duì)文本做了分析以后,就可以存入索引庫(kù)。
用戶(hù)可以發(fā)出各種查詢(xún),不僅僅是單個(gè)關(guān)鍵字,還支持關(guān)鍵字的組合: keyword1 AND keyword2等,對(duì)索引庫(kù)進(jìn)行搜索以后,把結(jié)果返回給用戶(hù)。
“中間用虛線框起來(lái)的部分就是我應(yīng)該實(shí)現(xiàn)的類(lèi)庫(kù)!” 張大胖對(duì)這個(gè)架構(gòu)很滿(mǎn)意。
抽象
接下來(lái)就要考慮這個(gè)類(lèi)庫(kù)對(duì)外提供的API了,這是個(gè)很煩人的事情。 張大胖的腦海中不由地想起來(lái)好基友Bill的諄諄教導(dǎo):“軟件設(shè)計(jì)就是一個(gè)不斷抽象的過(guò)程?!保?關(guān)鍵是要抽象?。?/p>
可是這個(gè)系統(tǒng)似乎有點(diǎn)復(fù)雜,張大胖絞盡腦汁想了兩天也沒(méi)有頭緒,對(duì)于一個(gè)剛學(xué)會(huì)Web開(kāi)發(fā)的同學(xué),立刻就要設(shè)計(jì)類(lèi)庫(kù),確實(shí)是有點(diǎn)勉為其難。
沒(méi)辦法,張大胖只好致電Bill前來(lái)幫忙。
Bill對(duì)張大胖的痛苦表示了親切的慰問(wèn), 又對(duì)架構(gòu)圖表示了適度的贊賞。 他說(shuō): “既然有HTML,PDF, Word文檔, 很自然,你可以做一個(gè)Document的抽象!”
“好像不行吧? 如果數(shù)據(jù)源是數(shù)據(jù)庫(kù),怎么變成Document? ”
“很簡(jiǎn)單, 比如一行數(shù)據(jù)就可以映射到一個(gè)Document。 當(dāng)然,這個(gè)轉(zhuǎn)化必須得有程序員來(lái)完成。程序員決定什么東西是Document?!?Bill說(shuō)。
“Document中有什么東西? ”
“嗯,Document可以有很多屬性,每個(gè)屬性都有名稱(chēng)和值, 我可以把屬性叫做Field。比如一個(gè)HTML文檔,可能有path, title,content等多個(gè)Field,其中path可以唯一地標(biāo)志這個(gè)文檔, title和content需要做進(jìn)行分詞,形成倒排索引,讓用戶(hù)搜索?!?Bill回答。
(一個(gè)包含多個(gè)Field的Document)
“用戶(hù)創(chuàng)建了Document和Field以后,就可以進(jìn)行分析了原始的內(nèi)容劃分成一個(gè)個(gè)Term,” 張大胖開(kāi)始開(kāi)竅,“這樣,我可以定義一個(gè)Analyzer的抽象類(lèi),讓別的程序可以擴(kuò)展它。”
“對(duì),分析的結(jié)果可以加入索引庫(kù),這個(gè)操作可以讓一個(gè)單獨(dú)的類(lèi),比如IndexWriter類(lèi)來(lái)完成?!?Bill 說(shuō)。
“可是IndexWriter如何知道索引應(yīng)該存在什么地方? 內(nèi)存? 文件系統(tǒng)?”
“那就再來(lái)一個(gè)抽象的概念:Directory,表示索引文件的存儲(chǔ)?!?/p>
張大胖怕忘記,趕緊畫(huà)類(lèi)圖:
“看起來(lái)還是挺漂亮的嘛!” 張大胖說(shuō)。
“好的設(shè)計(jì)一般都比較漂亮?!?Bill 來(lái)了一句至理名言。
“對(duì)于對(duì)于用戶(hù)搜索來(lái)說(shuō),肯定得有個(gè)叫做Query的東西,用來(lái)表達(dá)用戶(hù)的搜索要求。當(dāng)然,這個(gè)Query也應(yīng)該允許擴(kuò)展。 ” 張大胖嘗試著抽象。
“但是這些類(lèi)使用起來(lái)還是比較麻煩, 最好是支持用戶(hù)輸入字符串來(lái)表達(dá)搜索的意圖:(computer or phone) and price” Bill還是經(jīng)驗(yàn)老道,“必須得有個(gè)解析器來(lái)完成從字符串到Query的轉(zhuǎn)化,然后我們讓IndexSearcher 來(lái)接收Query,就可以實(shí)現(xiàn)搜索的功能了。 ”
張大胖很興奮,一個(gè)復(fù)雜的系統(tǒng),就這么被搞定了,雖然其中有很多細(xì)節(jié)沒(méi)有覆蓋,但大的方向已經(jīng)確定, 細(xì)節(jié)在具體的開(kāi)發(fā)中來(lái)處理吧。
他摩拳擦掌,準(zhǔn)備大干一場(chǎng),把這個(gè)設(shè)計(jì)給實(shí)現(xiàn)了。
可是Bill在網(wǎng)上搜索了一會(huì)兒,潑了一盆冷水:“大胖,好像有個(gè)叫做Lucene的開(kāi)源系統(tǒng),和我們的設(shè)計(jì)很像啊,功能更加強(qiáng)大,要不你就用它這個(gè)實(shí)現(xiàn)吧?!?/p>
張大胖趕緊跑到電腦前去看,果然,這個(gè)叫Lucene的家伙實(shí)現(xiàn)得非常完善,還有很多高級(jí)的功能,比如僅僅是“相似度”這個(gè)功能,非得對(duì)搜索有深入研究才行,自己是望塵莫及。
他嘆了一口氣說(shuō):“好吧,我去圖書(shū)館找王老師,就用這個(gè)Lucene吧!”
三年以后
張大胖已經(jīng)變成了利用Lucene做搜索的高手,各種細(xì)節(jié)和最佳實(shí)踐盡在掌握。隨著互聯(lián)網(wǎng)應(yīng)用的爆炸式增長(zhǎng),搜索變成了一個(gè)常見(jiàn)的需求,他甚至在業(yè)余時(shí)間專(zhuān)門(mén)去給人做Lucene的咨詢(xún),賺了不少外快。
但是做得多了,張大胖也覺(jué)得很煩,這個(gè)Lucene用起來(lái)實(shí)在是太“低級(jí)”,很多人向他抱怨: 我就想搜索一下我的商品描述,現(xiàn)在還得理解什么“Directory”,"Analyzer","Query",實(shí)在是太復(fù)雜了! 還有我們的數(shù)據(jù)越來(lái)越多,索引也越來(lái)占的空間也越來(lái)越大,怎么才能實(shí)現(xiàn)分布式的存儲(chǔ)?。?/p>
這樣的抱怨聽(tīng)多了,張大胖心想:是時(shí)候?qū)ucene做一層封裝,提供一個(gè)簡(jiǎn)單的API了......
后記:接下來(lái)還可以講一下Elastic Search ,也不知道大家是否感興趣,再加上這篇文章已經(jīng)很長(zhǎng)了,就停筆了。 如果各位感興趣的,留言告訴我一下,我會(huì)繼續(xù)寫(xiě)下去。
【本文為專(zhuān)欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過(guò)作者微信公眾號(hào)coderising獲取授權(quán)】
新聞名稱(chēng):如何實(shí)現(xiàn)全文檢索功能之搜索之路
文章位置:http://www.dlmjj.cn/article/cdohcji.html


咨詢(xún)
建站咨詢(xún)
