天天看點

app後端搜尋入門 1.    一個簡單的搜尋例子 2.    搜尋技術的基本原理 3.    常見的開源搜尋軟體介紹

 現在人們的網絡生活已經離不開搜尋了,遇到不懂的問題,想知道的事情,搜尋一下,就知道答案。

在app中,最常見的搜尋情景就是搜尋使用者。隻有幾百,幾千的使用者量時,可以直接用用like這樣的模糊查詢,但是,如果資料有幾百萬,甚至上千萬的時候,一次like查詢資料庫就堵了。到了一定量級的時候,不得不考慮使用專門的搜尋技術。

有三行資料:

(1)近2周8成股民虧損超10%。

(2)滿倉中國夢。

(3)股民兩天虧一套三居。

例如,有個需求,從上面的3行資料中,把包含“股民”這個關鍵詞的資料找出來。

按照一般的做法,就是分别查找上面的每一行資料:

第一行資料從頭到尾查找一次,發現有“股民”這個關鍵詞。

第二行資料從頭到尾查找一次,沒有有“股民”這個關鍵詞。

第三行資料從頭到尾查找一次,發現有“股民”這個關鍵詞。

         根據查找結果,第一,第三行資料包含“股民”這個關鍵詞。

按照上面的過程,每次查找,都需要把每行資料從頭到尾查一次。

如果需要從上百萬,千萬的資料中查找一個關鍵詞,讀者可以想象一下效率有多低。

我們看一下搜尋引擎的例子,在搜尋引擎搜尋“股民”這個關鍵詞的結果:

app後端搜尋入門 1.    一個簡單的搜尋例子 2.    搜尋技術的基本原理 3.    常見的開源搜尋軟體介紹

                                                                           圖1

在搜尋引擎的搜尋結果中,是直接顯示了所有包含“股民”這個關鍵字的資料。

它是怎麼做到在海量的資訊中,快速搜尋中包含關鍵字的資訊的呢?

        實作搜尋的關鍵,就是分詞和倒序索引。

         如果我們知道每行資料中包含多少個關鍵字,然後建立一個映射表,把每個關鍵字出現在哪行資料中記錄下來,搜尋就變得很輕松。當知道一個關鍵字的時候,隻需要查找這個映射表,找到這個關鍵詞,根據這個關鍵詞建立的映射關系就能查到包含這個關鍵詞的資料。

         知道每行資料中包含多少個關鍵字的過程,就是分詞。這裡有個問題,什麼是關鍵字?

        關鍵字,其實就是一個詞語或句子,例如,當我有需要的時候,“股民”可以是搜尋的關鍵字,但是,“股”也可以是搜尋的關鍵字,“民”也可以是搜尋的關鍵字。什麼是關鍵字,要看使用者的需求。是以,為了能準确分析出一行資料到底包含多少個關鍵字,就需要一個包含了所有詞語或句子的詞典,用來分析資料中有什麼關鍵字。

         建立一個映射表,把每個關鍵字出現在哪行資料中記錄下來,這個過程就是建倒序搜引。

         下面舉個實際的例子,看看是怎麼分詞和建立倒序索引。

         還是用回上面舉例的三行資料,左邊的是資料的編号,右邊的是資料的内容。

首先,把分析上面每行資料包含多少個關鍵詞(這裡為了簡化分詞過程,沒有把每個漢字或數字當成一個關鍵詞,例如,” 民”應該是個關鍵詞,但為了簡化分詞,沒有當成一個關鍵詞),結果如表1所示。

app後端搜尋入門 1.    一個簡單的搜尋例子 2.    搜尋技術的基本原理 3.    常見的開源搜尋軟體介紹

                                                                                           表1 

         下面根據表1的結果建立一個映射表表2,把每個關鍵字出現在哪行資料中記錄下來

app後端搜尋入門 1.    一個簡單的搜尋例子 2.    搜尋技術的基本原理 3.    常見的開源搜尋軟體介紹

表2

用上面的表2,我們很容易得知,“股民”這個關鍵詞在資料1,3中出現過。如果需要知道“中國”這個關鍵詞出現在哪,通過查找表2也很容易得知出現在資料2中。

在這麼幾行資料中,還不能體驗到倒序索引的高效。如果資料量到了上百萬,千萬,甚至上億,倒序索引的效率就非常明顯了。歸根到底,這種資料結構就是為了實作快速搜尋也建立的。

再進一步,表2的右側,除了記錄關鍵詞出現在哪行資料中,還能記錄在某行資料中出現的頻率,出現的位置等資訊,如果有興趣繼續深入了解搜尋引擎的技術,可閱讀《這就是搜尋引擎:核心技術詳解》(張俊林著),這篇文章隻是簡單介紹搜尋引擎的基本原理。

搜尋技術一點都不簡單,如果要我們從頭開始做,不知道要到哪年哪月才能用給app用上搜尋功能。幸好,大牛們已經為我們開源大量的搜尋軟體,隻要我們會使用這些搜尋軟體提供的api,就能給app背景整合搜尋技術。下面簡單介紹一下常見的搜尋軟體。

(1) Lucene

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

Lucene的目的是為軟體開發人員提供一個簡單易用的工具包,以友善的在目标系統中實作全文檢索的功能,或者是以此為基礎建立起完整的全文檢索引擎。Lucene是一套用于全文檢索和搜尋的開源程式庫,由Apache軟體基金會支援和提供。Lucene提供了一個簡單卻強大的應用程式接口,能夠做全文索引和搜尋。在Java開發環境裡Lucene是一個成熟的免費開源工具。就其本身而言,Lucene是目前以及最近幾年最受歡迎的免費Java資訊檢索程式庫。

(2) Solr

Solr是一個高性能,采用Java5開發,基于Lucene的全文搜尋伺服器。同時對其進行了擴充,提供了比Lucene更為豐富的查詢語言,同時實作了可配置、可擴充并對查詢性能進行了優化,并且提供了一個完善的功能管理界面,是一款非常優秀的全文搜尋引擎。它對外提供類似于Web-service的API接口。使用者可以通過http請求,向搜尋引擎伺服器送出一定格式的XML檔案,生成索引;也可以通過Http Get操作提出查找請求,并得到XML格式的傳回結果。

(3) Elasticsearch

ElasticSearch是一個基于Lucene的搜尋伺服器。它提供了一個分布式多使用者能力的全文搜尋引擎,基于RESTful web接口。Elasticsearch是用Java開發的,并作為Apache許可條款下的開放源碼釋出,是第二流行的企業搜尋引擎。

(4) Sphinx

Sphinx是一個基于SQL的全文檢索引擎,可以結合MySQL,PostgreSQL做全文搜尋,它可以提供比資料庫本身更專業的搜尋功能,使得應用程式更容易實作專業化的全文檢索。Sphinx特别為一些腳本語言設計搜尋API接口,如PHP,Python,Perl,Ruby等,同時為MySQL也設計了一個存儲引擎插件。

(5) Coreseek

Coreseek 是一款中文全文檢索/搜尋軟體,以GPLv2許可協定開源釋出,基于Sphinx研發并獨立釋出,專攻中文搜尋和資訊處理領域,适用于行業/垂直搜尋、論壇/站内搜尋、資料庫搜尋、文檔/文獻檢索、資訊檢索、資料挖掘等應用場景,使用者可以免費下載下傳使用。

Coreseek曾經在本人架構過兩個app背景深度使用過,配置簡單,性能高效,整合了Sphinx和中文分詞,快速完成了搜尋子產品的開發。但最大的缺點是穩定版不支援實時索引,測試版是支援了,但沒在生産環境中用過。

Coreseek的原理如下圖3所示:

app後端搜尋入門 1.    一個簡單的搜尋例子 2.    搜尋技術的基本原理 3.    常見的開源搜尋軟體介紹

                                                                   圖2

Coreseek有兩個核心子產品 Indexer和Search。

Indexer: 負責從mysql中拉取資料源,把資料源分詞,建立索引

Search:搜尋子產品

整個工程的流程如下:

1.      Indexer子產品從mysql中拉取資料

2.      Indexer子產品把資料經過中文分詞,建立索引

3.      用戶端向Search子產品發起搜尋請求

4.      Seach子產品查找索引中的資料

5.      Seach子產品得到索引中符合要求的資料的id等資料

6.      把資料傳回給用戶端

另外,有個小小的經驗分享,搜尋的時候,有的使用者直接通過輸入拼音來代替漢字的,如下圖2:

app後端搜尋入門 1.    一個簡單的搜尋例子 2.    搜尋技術的基本原理 3.    常見的開源搜尋軟體介紹

                              圖3

這種情況,就是要在記錄關鍵字的同時,也要記錄下關鍵字的拼音,把拼音也建索引,就能實作用拼音搜尋。

參考資料:

1.      http://baike.baidu.com/link?url=rNBW3tzH-oJYeBoPSUvWZPGz-stIkE5zFQsjAtV234HFFPJKyeyr3dJjJrbZKRSCBg2NGZv-lA7DFqHF5XBEoq

4.      http://www.coreseek.cn/

如何聯系我:【萬裡虎】www.bravetiger.cn

【QQ】3396726884 (咨詢問題100元起,幫助解決問題500元起)

【部落格】http://www.cnblogs.com/kenshinobiy/

繼續閱讀