使用Elasticsearch快速實現(xiàn)社區(qū)/博客文章全文搜索

這是一篇結(jié)合實戰(zhàn)教同學快速入門使用Elasticsearch 解決實際業(yè)務場景的問題.

如果你還在用 sql like %xxx%的方式進行內(nèi)容的全文搜索,很可能DBA或者老大就要找你去聊天了, 以mysql innodb引擎為例, 這種寫法將會進行十分低效全文檢索,而且不會使用索引.

接下來全文將 elasticsearch 簡稱為ES.

那么,本文將通過將之前在Flask框架上使用的社區(qū)搜索接口從like %xxx%的寫法改成ES做全文索引,觀察是否會存在顯著的性能提升(如果不能提升,是否還有其他改進的方式),先看下從0-1怎么快速實現(xiàn).

看了其他的講實現(xiàn)的文章中都是把相關(guān)組件或者ES的文檔代碼直接貼過來,個人認為這些都是會存在升級以及文檔變更的可能,為了使用最新的api以及特性還是建議讀者花幾分鐘讀完文章中的外鏈文檔地址.

  • ES是什么? 怎么玩?
  • 地域問題,中文文章的分詞怎么整?
  • 業(yè)務的實現(xiàn)
  • 線上環(huán)境的部署與監(jiān)控(服務的穩(wěn)定性)

ES是什么? 怎么玩?

ES簡單的中文入門,在上線之前需要現(xiàn)在本地以及測試環(huán)境跑的溜,筆者本機是MacOS系統(tǒng),所以采用比較快捷的Homebrew的安裝方式
brew install elasticsearch
再根據(jù)文檔安裝了瀏覽器級的control工具sense,按著教程稍微跑一下教程之后就可以進入了正題. 有些朋友想吐槽ES快速入門太簡單了,畢竟是實戰(zhàn)導向的快速入門,把重點放在ES與業(yè)務結(jié)合的實現(xiàn).

地域問題,中文文章的分詞怎么整

如果筆者讀了上段寫的中文入門教程,會發(fā)現(xiàn)ES已經(jīng)提供英文搜索模糊匹配的功能,至于ES是怎么實現(xiàn)的,感興趣的讀者可以再深入查閱資料.這時候為了支持中文搜索我們需要安裝插件到ES目錄中的plugins文件夾中$ES_HOME/plugins/ . ik插件的github地址,按著文檔安裝之后可以跑一下里面的測試請求,驗證中國的分詞查詢是有效的.ik插件的在analyzer和search_analyzer上有兩種配置:

  • ik_max_word: 會將文本做最細粒度的拆分,比如會將“中華人民共和國國歌”拆分為“中華人民共和國,中華人民,中華,華人,人民共和國,人民,人,民,共和國,共和,和,國國,國歌”邮丰,會窮盡各種可能的組合梆靖;
  • ik_smart: 會做最粗粒度的拆分,比如會將“中華人民共和國國歌”拆分為“中華人民共和國,國歌”焚碌。

核心的分詞問題就這樣解決了,在大批量的文章中是否會存在性能問題需要在實戰(zhàn)中驗證,接下來我們要做的事情就是將之前有的文章導入到ES中以及為新的文章建立文檔,這些要做的事情都將通過調(diào)用ES提供的api完成.

業(yè)務的實現(xiàn)

Elasticsearch 集群可以包含多個索引(Index),每個索引可以包含多個類型(Type),每個類型可以包含多個文檔(Document)育苟,每個文檔可以包含多個字段(Field)筹裕。以下是 MySQL 和 Elasticsearch 的術(shù)語類比圖鸠按,幫助理解:

MySQL Elasticsearch
Database Index
Table Type
Row Document
Column Field
Schema Mappping
Index Everything Indexed by default
SQL Query DSL

就像使用 MySQL 必須指定 Database 一樣,要使用 Elasticsearch 首先需要創(chuàng)建 Index,這邊我們?yōu)樯鐓^(qū)文章創(chuàng)建index: forum-index,以及type:post

ES提供了一套增刪改查的api,我們可以在SENSE模板中使用簡化API來測試驗證有效性,但是在后端開發(fā)中根據(jù)不同語言以及框架一般有已經(jīng)封裝好的庫可以直接配置使用,筆者這邊使用的是python的庫elasticsearch-dsl-py,如果您使用的是其他語言或者框架,上github上搜索一下有沒有封裝過的框架(記得要看是否版本匹配).在進行下一步之前,我們捋一下我們要做的事情,將原有的社區(qū)文章導入type,根據(jù)提供給客戶端以及后臺的查詢功能加入對應匹配的字段,新增文章時需要加入ES中,編輯文章后需要修改ES中對應文檔的內(nèi)容,以及文章下架后要將文章從ES中移除.增刪改這些額外的ES操作會有額外的時間消耗以及失敗的可能,為了不影響接口可以將操作封裝放入隊列異步執(zhí)行,保證最終一致執(zhí)行便可.ES查詢性能與穩(wěn)定性的優(yōu)化等先調(diào)通基礎(chǔ)功能與接口后再考慮.

這是導入原有帖子數(shù)據(jù)后在sense console上執(zhí)行以下模糊查詢語句與對應的返回:

GET /forum-index/post/_search
{
   "query": {
    "bool": {
      "should": [
        { "match": { "content":  "客戶端" }},
         { "match": { "title":  "客戶端" }},
        { "match": { "summary": "客戶端"   }}
      ]
    }
  }
}
{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 19,
    "max_score": 25.630516,
    "hits": [
      {
        "_index": "forum-index",
        "_type": "post",
        "_id": "60000000012672",
        "_score": 25.630516,
        "_source": {
          "user_id": 10144,
          "title": "客戶端發(fā)帖測試",
          "summary": "客戶端發(fā)帖測試內(nèi)容",
          "content": """
客戶端發(fā)帖測試內(nèi)容
<img data-src="3f2b7dd51ddcb7d66b22f0f06645f16e.png" src="http://img-cn-hangzhou.aliyuncs.com/nb-imgs/3f2b7dd51ddcb7d66b22f0f06645f16e.png">
 <br/>
</img>
""",
          "last_modify": 1480665329,
          "id": 60000000012672
        }
      },
...

返回json格式的數(shù)據(jù)中,took,_score,...等等很多字段這個是什么意思呢?
可以參考官文說明.這邊也簡單說明下:

  • took – time in milliseconds for Elasticsearch to execute the search
  • timed_out – tells us if the search timed out or not
  • _shards – tells us how many shards were searched, as well as a count of the successful/failed searched shards
  • hits – search results
  • hits.total – total number of documents matching our search criteria
  • hits.hits – actual array of search results (defaults to first 10 documents)
  • hits.sort - sort key for results (missing if sorting by score)
  • hits._score and max_score - ignore these fields for now

這邊可以看到,在本地環(huán)境5000+的帖子文檔分詞查詢,消耗時間為4ms,算是一個非常不錯的結(jié)果了.將復雜的查詢功能使用ES來實現(xiàn),可以有效減少數(shù)據(jù)庫的請求壓力,接下來我們可以致力于優(yōu)化ES的使用以及查詢.按目前評估ES可以勝任生產(chǎn)級別的全文檢索服務.

線上環(huán)境的部署與監(jiān)控(服務的穩(wěn)定性)

由于工作調(diào)用的原因筆者很遺憾的沒有去實現(xiàn)完成最后這一步,但是可以大致說一下思路,線上部署配置后,可以使用supervisor等服務守護程序去保證服務的穩(wěn)定性,并做好性能壓測,為保證服務的持續(xù)可用建議部署上ES的集群.單個節(jié)點異常的時候也能保證線上服務的持續(xù).

總結(jié)

通過這次的學習發(fā)現(xiàn)ES是個強大好用的工具,目前比較流行的有用ELK進行日志分析(ElasticSearch + Logstash + Kibana),這邊僅僅是為讀者們打開了冰山的一角,繼續(xù)學習,與君共勉!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末饶碘,一起剝皮案震驚了整個濱河市目尖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌扎运,老刑警劉巖瑟曲,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異豪治,居然都是意外死亡洞拨,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門负拟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烦衣,“玉大人,你說我怎么就攤上這事掩浙』ㄒ鳎” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵厨姚,是天一觀的道長衅澈。 經(jīng)常有香客問我,道長谬墙,這世上最難降的妖魔是什么今布? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮拭抬,結(jié)果婚禮上部默,老公的妹妹穿的比我還像新娘。我一直安慰自己造虎,他們只是感情好傅蹂,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著累奈,像睡著了一般贬派。 火紅的嫁衣襯著肌膚如雪急但。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天搞乏,我揣著相機與錄音波桩,去河邊找鬼。 笑死请敦,一個胖子當著我的面吹牛镐躲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播侍筛,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼萤皂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了匣椰?” 一聲冷哼從身側(cè)響起裆熙,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎禽笑,沒想到半個月后入录,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡佳镜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年僚稿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蟀伸。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡蚀同,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出啊掏,到底是詐尸還是另有隱情蠢络,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布脖律,位于F島的核電站谢肾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏小泉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一冕杠、第九天 我趴在偏房一處隱蔽的房頂上張望微姊。 院中可真熱鬧,春花似錦分预、人聲如沸兢交。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽配喳。三九已至酪穿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間晴裹,已是汗流浹背被济。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留涧团,地道東北人只磷。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像泌绣,于是被迫代替她去往敵國和親钮追。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Elasticsearch默認提供的分詞器阿迈,會把每個漢字分開元媚,而不是我們想要的根據(jù)關(guān)鍵詞來分詞,我是中國人 不能簡...
    歡醉閱讀 1,279評論 0 3
  • 1.Search Engine 目前主流的開源搜索引擎主要有兩個苗沧,一個是基于Java的Apache Lucene刊棕,...
    秦漢郵俠閱讀 844評論 0 1
  • Elasticsearch是一個基于Apache Lucene(TM)的開源搜索引擎鞠绰。無論在開源還是專有領(lǐng)域,Lu...
    初秋夏末閱讀 578評論 0 0
  • 啟明星大學生領(lǐng)袖第一期特訓營 2017/2/20 3天感覺就像走了一生一般…… 收獲 關(guān)鍵點: 做人要一諾千金飒焦,做...
    尹澤Rancho閱讀 239評論 0 1
  • 早上聽了一個育兒音頻蜈膨,關(guān)于樂觀,對其觀點深以為然牺荠,決定總結(jié)內(nèi)化翁巍。 孩子都會犯錯誤,批評吧休雌,怕打擊他...
    海星_love閱讀 306評論 0 1