許祥,余立毅
(景德鎮(zhèn)陶瓷大學(xué)信息工程學(xué)院,景德鎮(zhèn)333403)
Solr;Lucene;商品搜索;HanLP;布隆過濾器
網(wǎng)絡(luò)購物已經(jīng)成為了人們?nèi)粘5南M習(xí)慣,在這些購物應(yīng)用中,產(chǎn)品搜索是它們的必備功能,搜索能夠幫助用戶更快更準(zhǔn)確地找到自己需要的物品,保障購物體驗。Solr是一個獨立的企業(yè)級搜索引擎服務(wù)器,它是以Lucene全文檢索技術(shù)為基礎(chǔ)構(gòu)建的Web應(yīng)用,能夠快速地提供檢索服務(wù)。Lucene是一個成熟的信息檢索程序庫,它在全文檢索領(lǐng)域、文本相似度計算領(lǐng)域以及構(gòu)建搜索引擎方面都有廣泛的應(yīng)用。由于使用傳統(tǒng)數(shù)據(jù)庫的應(yīng)用系統(tǒng)在商品搜索效率和結(jié)果上都無法滿足日益增長的數(shù)據(jù)訪問量,因此針對商品搜索所需要的快速、精準(zhǔn)、高效的設(shè)計需求,通過對全文檢索[1-4]尤其是垂直搜索技術(shù)[5-6]的研究,利用關(guān)鍵詞過濾、中文分詞器和改進(jìn)商品默認(rèn)排序,實現(xiàn)一個能夠滿足小型商品搜索的通用化引擎。
本文利用Solr將商品數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行索引,構(gòu)建索引庫,搭建初始Web應(yīng)用系統(tǒng)。使用布隆過濾器減少直接查找索引庫的索引詞次數(shù),優(yōu)化索引效率。根據(jù)設(shè)計需求修改Lucene的排序[7-8]機(jī)制,簡化內(nèi)部搜索過程,自定義商品排序,進(jìn)一步加快檢索速度。在最后的實驗環(huán)節(jié),系統(tǒng)能夠快速地提供商品搜索服務(wù),取得了不錯的效果。
布隆過濾器(Bloom Filter)[9]是1970年由布隆提出的。它實際上是一個很長的二進(jìn)制向量bitarray和一系列隨機(jī)映射函數(shù)Hash,用于解決單個Hash的沖突問題。假設(shè)一種bitarray長度為m,有k個哈希函數(shù),且每個哈希函數(shù)的輸出范圍都大于m,接著將輸出值對m取余(%m),就會得到k個[0,m-1]的值,由于每個哈希函數(shù)之間相互獨立,因此這k個數(shù)也相互獨立,最后將這k個數(shù)對應(yīng)到bitarray上并標(biāo)記為1。等判斷時,將輸入對象經(jīng)過這k個哈希函數(shù)計算得到k個值,然后判斷對應(yīng)bitarray的k個位置是否都為1,如果有一個不為1,那么這個輸入對象則不在這個集合中;如果都是1,那說明在集合中,但有可能會誤,由于當(dāng)輸入對象過多,而集合也就是bitarray過小,則會出現(xiàn)大部分為1的情況,那樣就容易發(fā)生誤判。所以它的優(yōu)點是空間效率和查詢時間都比一般的算法要好的多,缺點是有一定的誤識別率和刪除困難。
假設(shè)輸入對象個數(shù)為n,bitarray大?。ㄒ簿褪遣悸∵^濾器大?。閙,所容忍的誤判率p和哈希函數(shù)的個數(shù)k。計算公式如下:
使用布隆過濾器預(yù)先判斷單詞是不是在該索引庫里。在系統(tǒng)啟動之后,讀取Lucene索引庫中的所有詞條,將它們加載進(jìn)布隆過濾器對象中,完成BloomFilter對象初始化。在每次搜索關(guān)鍵詞時,都會先使用BloomFilter判斷關(guān)鍵詞是否在Lucene索引庫中。
這里設(shè)定布隆過濾器的誤判率p為0.01%,商品信息個數(shù)n為1100000,經(jīng)過計算得出哈希函數(shù)個數(shù)k為14,布隆過濾器bitarray大小m為2574.11KB。
中文分詞是中文文本處理的一個基礎(chǔ)步驟,也是全文搜索技術(shù)的核心關(guān)鍵之一,分詞效果的好壞以及效率直接關(guān)系到搜索引擎的綜合表現(xiàn)。目前,常見的中文分詞器[10]大致可歸納為:詞典分詞方法、理解分詞方法、統(tǒng)計分詞方法、組合分詞方法。其中,組合分詞方法[11]是利用各個方法的優(yōu)點,彌補(bǔ)方法的不足,組合部分方法以更好地解決分詞問題。
Lucene自帶的中文分詞器,包括StandardAnalyzer和CJKAnalyzer。前者是單字分詞,就是按照中文一個字一個字地進(jìn)行分詞;后者是二分法分詞,即按兩個字進(jìn)行切分。上邊兩個分詞器無法滿足對中文的需求。
HanLP中文分詞器具備功能完善、性能高效、架構(gòu)清晰、語料時新、可自定義的特點。默認(rèn)模型訓(xùn)練自全世界最大規(guī)模的中文語料庫,同時自帶一些語料處理工具,幫助用戶訓(xùn)練自己的模型。目前支持包括Solr(7.x)在內(nèi)的任何基于Lucene(7.x)的系統(tǒng)。
商品排序其實就是計算搜索關(guān)鍵詞和所有物品的相關(guān)程度,關(guān)聯(lián)程度計算就是排序,Lucene會對分詞列的精確查詢條件進(jìn)行打分。打分排序[7-8]是搜索引擎重要一部分,能夠評判查詢條件和文檔的匹配度,提高檢索質(zhì)量。打分過程會消耗額外I/O、需要更多CPU計算、加載整個倒排表,拖累了查詢速度,特別是在文檔數(shù)非常多的情況下。而在商品搜索的需求中,用戶只關(guān)心那些和搜索關(guān)鍵詞高度相關(guān)的商品信息,對于相似度低的商品并不需要顯示出來,所以系統(tǒng)過濾掉低相似度的商品,減少參與排序的商品數(shù)量,降低時間復(fù)雜度。在系統(tǒng)查詢開始階段,設(shè)定相似度最低閾值score。
目前對于相似度最低閾值的設(shè)定沒有可供參考的資料,而且相似度值會根據(jù)不同的關(guān)鍵詞、關(guān)鍵詞數(shù)量、文檔長度、文檔內(nèi)容等因素得到0-1之間的任意數(shù)值,所以最低閾值score設(shè)定為固定值顯然不合適,必須是一個動態(tài)的值。參考Lucene在計算相關(guān)度得分的算法BM25[12],算法公式如下,可以針對不同查詢關(guān)鍵詞利用該公式計算出得分的最大值和最小值,取20%作為相似度最低閾值score。
其中N為索引中的全部文檔數(shù),n(qi)為包含了qi的文檔數(shù),這兩個值都是可以從索引庫讀取的;k1、b為調(diào)節(jié)因子,通常根據(jù)經(jīng)驗設(shè)置,一般k1=2,b=0.75;fi為qi在d中的出現(xiàn)頻率,也就是關(guān)鍵詞在商品名稱中出現(xiàn)的次數(shù),取值一般是0-3;dl為文檔d的長度,avgdl為所有文檔的平均長度,這兩者商的取值區(qū)間如下公式所示,取值一般是在0.6-1.5。
其中m表示文檔d長度的最大值,n表示文檔d長度的最小值,根據(jù)分析,m大約是n的2倍左右。
數(shù)據(jù)庫中的商品表products結(jié)構(gòu)如表1所示,其中選取字段pid、name、catalog_name、price、description和picture映射為索引庫字段id、prod_pname、prod_catalog_name、prod_price、prod_description和prod_picture,根據(jù)這6個字段將數(shù)據(jù)從數(shù)據(jù)庫導(dǎo)入到索引庫中。
表1 products表結(jié)構(gòu)
為了實現(xiàn)通過索引庫加快商品搜索效率的需求,將關(guān)系數(shù)據(jù)庫中的數(shù)據(jù)導(dǎo)入到Solr,從而構(gòu)建起商品數(shù)據(jù)索引庫,由查詢數(shù)據(jù)庫轉(zhuǎn)變?yōu)闄z索索引庫。構(gòu)建索引庫過程中,考慮到數(shù)據(jù)庫搜索的結(jié)果就是“表”中若干“元組”的集合,可以把“元組”的集合看作是倒排表中的文件鏈表,這樣通過關(guān)鍵詞找出對應(yīng)的文件集合,也就是過濾出符合關(guān)鍵詞條件的“元組”集合。
使用Solr服務(wù)器的dataimport工具將MySQL數(shù)據(jù)庫中的商品表products導(dǎo)入到索引庫。一般來說,商品搜索關(guān)鍵詞只出現(xiàn)在商品的名稱信息當(dāng)中,所以對“商品名稱”字段進(jìn)行索引。
商品搜索系統(tǒng)是基于Tomcat服務(wù)器、SpringMVC框架、MySQL數(shù)據(jù)庫和Solr搜索引擎等。設(shè)計結(jié)構(gòu)主要由數(shù)據(jù)層、業(yè)務(wù)層和客戶層組成,數(shù)據(jù)層包括存儲原始數(shù)據(jù)的MySQL數(shù)據(jù)庫和存儲索引文件的Lucene索引庫;業(yè)務(wù)層主要是由Solr Core實現(xiàn)的索引和搜索兩個功能,預(yù)先構(gòu)建、更新索引庫,搜索時先將查詢關(guān)鍵詞經(jīng)過布隆過濾器的預(yù)判,然后查詢索引庫,獲取商品信息;客戶層也就是系統(tǒng)界面,接受用戶的查詢請求,并將查詢結(jié)果展現(xiàn)在頁面當(dāng)中。整個系統(tǒng)的運行流程都由SpringMVC進(jìn)行控制管理,構(gòu)建索引庫以及分析搜索語句都需要HanLP中文分詞器的參與。
用戶除了能夠通過搜索框查詢商品之外,還可以點擊分類瀏覽特定類型商品,選擇一定價格區(qū)間的商品,對商品價格排序等。
為了分析比較基于Solr搜索服務(wù)器的本系統(tǒng)和基于MySQL數(shù)據(jù)庫的傳統(tǒng)SQL模糊查詢的性能差異,預(yù)先準(zhǔn)備了11萬條商品記錄的測試數(shù)據(jù)集,還有用于搜索的7個存在的商品詞和1個不存在的商品詞,針對這8個商品詞分別使用本系統(tǒng)進(jìn)行直接搜索和使用SQL語句“select*from products where pname like'%關(guān)鍵詞%';”進(jìn)行模糊查詢,對比兩者的檢索時間和檢索數(shù)量,實驗硬件環(huán)境Intel Core i5 2.3GHz、8GB內(nèi)存,得出如表2所示的實驗數(shù)據(jù)。
表2 基于Solr檢索和數(shù)據(jù)庫模糊檢索的結(jié)果對比
對比基于Solr搜索和基于MySQL數(shù)據(jù)庫模糊查詢的實驗結(jié)果,發(fā)現(xiàn)兩者在檢索時間方面差別較大,結(jié)果數(shù)量上差別較小?;赟olr搜索的時間基本在100毫秒以內(nèi),完全能滿足用戶對實時性的要求,而基于MySQL數(shù)據(jù)庫模糊查詢的時間大約在20000毫秒上下,兩者在檢索時間上相差200多倍,所以通過利用Lucene全文檢索索引庫技術(shù),商品搜索效率得到了極大提高。觀察實驗結(jié)果,發(fā)現(xiàn)搜索關(guān)鍵詞“襪子”、“眼鏡”和“牙膏”,雖然兩種方式的搜索結(jié)果數(shù)量一致,但是Solr檢索速度快很多。通過對比各關(guān)鍵詞的Solr檢索時間,當(dāng)檢索詞是最小分詞時,其搜索時間會比較短;當(dāng)檢索詞包含多個最小分詞,如“智能手機(jī)”、“碗綠色”,其搜索時間相對會長些。而對比各關(guān)鍵詞的模糊查詢時間,其檢索時間與檢索詞長短關(guān)系并不大,這其實是由于模糊查詢是對數(shù)據(jù)庫所有商品信息記錄進(jìn)行逐字匹配,所以耗時基本相差不大。最后,對于不存在的商品進(jìn)行檢索,兩者的結(jié)果數(shù)量都為0,但是本系統(tǒng)采用了布隆過濾器,預(yù)先判斷商品不存在,避免查詢索引庫,減少了檢索時間??偟膩碚f,基于Solr搜索服務(wù)器的檢索性能比基于數(shù)據(jù)庫的檢索性能要高出很多。
通過對Solr搜索引擎和底層的Lucene檢索庫的研究,并根據(jù)商品搜索的實際需求分別對排序、關(guān)鍵詞過濾實現(xiàn)了優(yōu)化,構(gòu)建出較為完整的商品搜索系統(tǒng)。經(jīng)過實驗的對比分析,得出系統(tǒng)實現(xiàn)了正常運行,更為重要的是性能較傳統(tǒng)數(shù)據(jù)庫的查詢性能提升非常明顯,說明系統(tǒng)的設(shè)計達(dá)到了最初的目的。