程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> JavaEye3.0開發手記之四 - ruby的全文檢索

JavaEye3.0開發手記之四 - ruby的全文檢索

編輯:關於JAVA

在Java平台上面,lucene是眾望所歸的全文檢索工具,lucene性能不俗,程序穩定,第三方擴展和分 詞算法眾多,但是在RoR方面,就沒有那麼幸運了,JavaEye網站要做全文檢索,怎麼來解決全文檢索的問 題呢?

在ruby平台上面,全文檢索有三個途徑:

1、solr, acts_as_solr

solr是apache開源組織的一個項目,完全基於lucene的最新版本,在lucene的上層提供了一個基於 HTTP/XML的Web Services。solr的發行包自己綁定了jetty6.0應用服務器,可以直接啟動,成為一個獨立 的全文檢索的web服務。

由於和solr的通訊方式是標准的基於HTTP的XML,所以你可以使用任何編程語言,Java,C++,Ruby, Python都不在話下。你通過向solr發送xml查詢請求,讓solr在後台運行lucene,返回結果也被封裝為xml ,當然你也可以讓solr去做索引。基本上solr就是 lucene的一個Web服務的封裝。solr的優勢在於為大規 模的全文檢索做了很多緩存優化,由於采用xml,也不限於客戶端的種類。

RoR有一個叫做acts_as_solr的插件,封裝了ruby對solr的訪問,如果你喜歡用solr作為全文檢索, acts_as_solr是一個不錯的選擇,他可以很方便的讓你的RoR應用添加全文檢索功能,考慮到lucene的穩 定性,這個方案是一個相當不錯的選擇。

但是這個方案的缺點也是顯而易見的,你的RoR應用所有的全文檢索都要依賴後台再次向solr服務器發 送web請求來獲取結果,單個頁面的執行速度肯定會受限於後台的跨http的web請求,這對於那些對全文檢 索功能依賴特別多的網站來說,恐怕很難接受。因此JavaEye3.0不采用solr方案。

2、sphinx

http://robbin.javaeye.com/blog/122696

我已經在上一篇博客當中介紹了sphinx。我個人非常青睐sphinx這種獨立的第三方全文檢索服務器, 而且能夠和MySQL結合的很好,更不用說其優異的性能了。但是sphinx的缺點在於沒有很好的分詞擴展的 接口,它是一個純C開發的服務。這對於中文分詞功能的支持來說,就很難實現了,因此不得不遺憾的放 棄。

3、ferret

ferret是ruby平台模仿lucene的一個移植軟件,但是ferret並非純ruby實現,而是基本上用C編寫而成 ,只有少量面向程序員的接口是ruby寫的。ferret雖然和lucene很像,連API也基本一致,但是ferret的 成熟度遠遠不及lucene,這表現在:

1) ferret不支持中文分詞

2) ferret用C編寫的,其索引格式和lucene不兼容

3) ferret的索引速度很慢,而且很不穩定

4) windows平台的ferret在search的時候會崩潰

盡管ferret有上面這些缺點,但是RoR平台可供選擇的余地卻不大,因此還是決定使用ferret。

------------------------------ ferret 分割線 ------------------------------

1、acts_as_ferret (AAF)

AAF是一個相當不錯的RoR插件,封裝對ferret的操作,但是經過我的考察,決定棄用AAF。這是因為 AAF是直接綁定到model上面的,這會帶來一些問題:

1) 每當model對象被insert/update/delete的時候,AAF會通過model的回調實時更新全文索引。在生 產環境這是一個很可怕的事情,多個ruby進程同時更新索引,就會出問題。所以AAF索性提供一個DRB方式 的ferret server讓你在生產環境去用。

但即便如此,如果多個ruby進程同時更新索引呢? 考慮到ruby的green thread性能,drb server也很 容易就被阻塞住。而且退一步來說,即便drb性能很好,每個全文檢索請求都去發起一次ruby遠程調用, 恐怕也是很難接受的事實

2) AAF索引每條model記錄,但我卻不想索引隱藏貼,況且我的索引機制也不想綁定在model上面。

2、中文分詞問題

如果只是簡單的中文單字拆分,到不難支持,只需要利用RegexpAnalysis寫個正則表達式去匹配UTF-8 編碼的中文就行了,目前JavaEye的全文檢索就是這樣處理的,貌似搜索結果還過得去。

但是如果要追求非常精確的搜索結果,則必然需要通過詞典的最大匹配算法去進行中文分詞。那就只 能自己用ruby來寫中文分詞算法了,這個是留待我們今後要做的工作。

2、ferret的索引穩定性問題

JavaEye網站有8萬topic,30萬post,由於ruby本身性能不佳,ferret又不很穩定,在服務器上面直接 做index,差點把服務器搞癱了,所以此路不通。

由於全文檢索並不需要很高的實時性,所以我們的解決辦法就是每天晚上把數據庫數據下載到本地的 台式機上面,然後在本地台式機上面導入數據庫,進行全量索引,然後在壓縮打包上傳到服務器上面去。 這樣每天的全文檢索結果只會遲後一天的時間,基本上可以滿足需求了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved