現在人們的網絡生活已經離不開搜索了,遇到不懂的問題,想知道的事情,搜索一下,就知道答案。html
在app中,最多見的搜索情景就是搜索用戶。僅僅有幾百,幾千的用戶量時。可以直接用用like這種模糊查詢,但是,假設數據有幾百萬,甚至上千萬的時候,一次like查詢數據庫就堵了。到了必定量級的時候。不得不考慮使用專門的搜索技術。mysql
有三行數據:web
(1)近2周8成股民虧損超10%。sql
(2)滿倉中國夢。數據庫
(3)股民兩天虧一套三居。apache
好比,有個需求,從上面的3行數據中。把包括「股民」這個關鍵詞的數據找出來。後端
依照通常的作法。就是分別查找上面的每一行數據:api
第一行數據從頭至尾查找一次。發現有「股民」這個關鍵詞。微信
第二行數據從頭至尾查找一次。沒有有「股民」這個關鍵詞。網絡
第三行數據從頭至尾查找一次,發現有「股民」這個關鍵詞。
依據查找結果,第一,第三行數據包括「股民」這個關鍵詞。
依照上面的過程,每次查找,都需要把每行數據從頭至尾查一次。
假設需要從上百萬,千萬的數據中查找一個關鍵詞,讀者可以想象一下效率有多低。
咱們看一下搜索引擎的樣例,在搜索引擎搜索「股民」這個關鍵詞的結果:
圖1
在搜索引擎的搜索結果中,是直接顯示了所有包括「股民」這個keyword的數據。
它是怎麼作到在海量的信息中,高速搜索中包括keyword的信息的呢?
實現搜索的關鍵,就是分詞和倒序索引。
假設咱們知道每行數據中包括多少個keyword,而後創建一個映射表,把每個keyword出現在哪行數據中記錄下來。搜索就變得很是輕鬆。當知道一個keyword的時候。僅僅需要查找這個映射表,找到這個關鍵詞。依據這個關鍵詞創建的映射關係就能查到包括這個關鍵詞的數據。
知道每行數據中包括多少個keyword的過程,就是分詞。
這裏有個問題,什麼是keyword?
keyword。事實上就是一個詞語或句子,好比,當我有需要的時候,「股民」可以是搜索的keyword。但是,「股」也可以是搜索的keyword,「民」也可以是搜索的keyword。
什麼是keyword。要看使用者的需求。所以,爲了能準確分析出一行數據究竟包括多少個keyword,就需要一個包括了所有詞語或句子的詞典,用來分析數據中有什麼keyword。
創建一個映射表,把每個keyword出現在哪行數據中記錄下來,這個過程就是建倒序搜引。
如下舉個實際的樣例,看看是怎麼分詞和創建倒序索引。
仍是用回上面舉例的三行數據,左邊的是數據的編號,右邊的是數據的內容。
(1)近2周8成股民虧損超10%。
(2)滿倉中國夢。
(3)股民兩天虧一套三居。
首先。把分析上面每行數據包括多少個關鍵詞(這裏爲了簡化分詞過程。沒有把每個漢字或數字當成一個關鍵詞,好比,」 民」應該是個關鍵詞,但爲了簡化分詞,沒有當成一個關鍵詞)。結果如表1所看到的。
表1
如下依據表1的結果創建一個映射表表2,把每個keyword出現在哪行數據中記錄下來
表2
用上面的表2。咱們很是easy得知。「股民」這個關鍵詞在數據1,3中出現過。假設需要知道「中國」這個關鍵詞出現在哪,經過查找表2也很是easy得知出現在數據2中。
在這麼幾行數據中,還不能體驗到倒序索引的高效。
假設數據量到了上百萬。千萬,甚至上億,倒序索引的效率就很明顯了。
歸根究竟,這樣的數據結構就是爲了實現高速搜索也創建的。
再進一步。表2的右側,除了記錄關鍵詞出現在哪行數據中,還能記錄在某行數據中出現的頻率,出現的位置等信息,假設有興趣繼續深刻了解搜索引擎的技術,可閱讀《這就是搜索引擎:核心技術具體解釋》(張俊林著),這篇文章僅僅是簡介搜索引擎的基本原理。
搜索技術一點都不簡單,假設要咱們從頭開始作。不知道要到哪年哪月才幹用給app用上搜索功能。幸虧,大牛們已經爲咱們開源大量的搜索軟件,僅僅要咱們會使用這些搜索軟件提供的api,就能給app後臺整合搜索技術。如下簡介一下常見的搜索軟件。
(1) Lucene
Lucene是apache軟件基金會4 jakarta項目組的一個子項目,是一個開放源碼的全文檢索引擎工具包,即它不是一個完整的全文檢索引擎,而是一個全文檢索引擎的架構,提供了完整的查詢引擎和索引引擎,部分文本分析引擎(英文與德文兩種西方語言)。
Lucene的目的是爲軟件開發者提供一個簡單易用的工具包,以方便的在目標系統中實現全文檢索的功能,或者是以此爲基礎創建起完整的全文檢索引擎。Lucene是一套用於全文檢索和搜尋的開源程式庫,由Apache軟件基金會支持和提供。Lucene提供了一個簡單卻強大的應用程式接口,能夠作全文索引和搜尋。
在Java開發環境裏Lucene是一個成熟的免費開源工具。
就其自己而言,Lucene是當前以及近期幾年最受歡迎的免費Java信息檢索程序庫。
(2) Solr
Solr是一個高性能,採用Java5開發,基於Lucene的全文搜索server。
同一時候對其進行了擴展。提供了比Lucene更爲豐富的查詢語言,同一時候實現了可配置、可擴展並對查詢性能進行了優化,並且提供了一個無缺的功能管理界面,是一款很優秀的全文搜索引擎。它對外提供相似於Web-service的API接口。用戶可以經過http請求,向搜索引擎server提交必定格式的XML文件,生成索引。也可以經過Http Get操做提出查找請求。並獲得XML格式的返回結果。
(3) Elasticsearch
ElasticSearch是一個基於Lucene的搜索server。它提供了一個分佈式多用戶能力的全文搜索引擎,基於RESTful web接口。Elasticsearch是用Java開發的,並做爲Apache許可條款下的開放源代碼公佈,是第二流行的企業搜索引擎。
(4) Sphinx
Sphinx是一個基於SQL的全文檢索引擎,可以結合MySQL,PostgreSQL作全文搜索,它可以提供比數據庫自己更專業的搜索功能。使得應用程序更easy實現專業化的全文檢索。
Sphinx特別爲一些腳本語言設計搜索API接口,如PHP,Python,Perl,Ruby等。同一時候爲MySQL也設計了一個存儲引擎插件。
(5) Coreseek
Coreseek 是一款中文全文檢索/搜索軟件。以GPLv2許可協議開源公佈,基於Sphinx研發並獨立公佈。專攻中文搜索和信息處理領域,適用於行業/垂直搜索、論壇/站內搜索、數據庫搜索、文檔/文獻檢索、信息檢索、數據挖掘等應用場景,用戶可以免費下載使用。
Coreseek之前在本人架構過兩個app後臺深度使用過,配置簡單。性能高效。整合了Sphinx和中文分詞。高速完畢了搜索模塊的開發。但最大的缺點是穩定版不支持實時索引,測試版是支持了,但沒在生產環境中用過。
Coreseek的原理例如如下圖3所看到的:
圖2
Coreseek有兩個核心模塊 Indexer和Search。
Indexer: 負責從mysql中拉取數據源,把數據源分詞,創建索引
Search:搜索模塊
整個project的流程例如如下:
1. Indexer模塊從mysql中拉取數據
2. Indexer模塊把數據通過中文分詞,創建索引
3. client向Search模塊發起搜索請求
4. Seach模塊查找索引中的數據
5. Seach模塊獲得索引中符合要求的數據的id等數據
6. 把數據返回給client
另外,有個小小的經驗分享,搜索的時候,有的用戶直接經過輸入拼音來取代漢字的。例如如下圖2:
圖3
這樣的狀況,就是要在記錄keyword的同一時候,也要記錄下keyword的拼音,把拼音也建索引,就能實現用拼音搜索。
參考資料:
1. http://baike.baidu.com/link?url=rNBW3tzH-oJYeBoPSUvWZPGz-stIkE5zFQsjAtV234HFFPJKyeyr3dJjJrbZKRSCBg2NGZv-lA7DFqHF5XBEoq
4. http://www.coreseek.cn/
----------------------------------------------------------
本人把網絡上發表的一系列「app後端」文章加以整理並添加了運維和架構方面的內容,出版了書籍《App 後臺開發運維和架構實踐》,該書已在京東,噹噹和亞馬遜上銷售。
-------------------------------------------------------------------------------------------------
打開連接 app後端系列文章總文件夾 總文件夾 ,能查看本人發表過的所有原創「app後端」文章。
【做者】曾健生