Elasticsearch,爲了搜索

Elasticsearch是一個基於Apache Lucene(TM)的開源搜索引擎。不管在開源仍是專有領域,Lucene能夠被認爲是迄今爲止最早進、性能最好的、功能最全的搜索引擎庫。html

可是,Lucene只是一個庫。想要使用它,你必須使用Java來做爲開發語言並將其直接集成到你的應用中,更糟糕的是,Lucene很是複雜,你須要深刻了解檢索的相關知識來理解它是如何工做的。java

Elasticsearch也使用Java開發並使用Lucene做爲其核心來實現全部索引和搜索的功能,可是它的目的是經過簡單的RESTful API來隱藏Lucene的複雜性,從而讓全文搜索變得簡單。laravel

若是沒有搜索引擎,單單憑藉Mysql提供的簡單搜索功能,不管在性能仍是效果上都不盡如人意,繼承程序猿的折騰屬性,決定將本身的博客插上Elasticsearch的翅膀。git

安裝 Oracle JDK

sudo apt-get update
sudo apt-get install openjdk-8-jdk

安裝 Elasticsearch

  • 下載github

    wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-2.3.4.deb    
    sudo dpkg -i elasticsearch-2.3.4.deb

    目前ElasticSearch的中文分詞插件IK最高版本爲1.9.4,兼容Elasticsearch的2.3.4版本。web

  • 安裝sql

    sudo dpkg -i elasticsearch-2.3.4.deb
  • 開機自啓動數據庫

    sudo update-rc.d elasticsearch defaults 95 10
    sudo service elasticsearch start
  • 測試服務器

    curl http://localhost:9200

你若是你看到如下信息,說明你的ElasticSearch已安裝成功。app

{
    "name" : "Peter Petruski",
    "cluster_name" : "elasticsearch",
    "version" : {
        "number" : "2.3.4",
        "build_hash" : "...(隱藏)",
        "build_timestamp" : "2016-06-30T11:24:31Z",
        "build_snapshot" : false,
        "lucene_version" : "5.5.0"
    },
      "tagline" : "You Know, for Search"
}

默認狀況下 Elasticsearch 的 RESTful 服務只有本機才能訪問,也就是說沒法從主機訪問虛擬機中的服務。爲了方便調試,能夠修改 /etc/elasticsearch/config/elasticsearch.yml 文件,加入如下兩行:

network.bind_host: 「0.0.0.0"
network.publish_host: \_non_loopback:ipv4_

安裝中文分詞插件 IK

Elasticsearch原裝分詞器會簡單地拆分每一個漢字,沒有根據詞庫來分詞,這樣的後果就是搜索結果極可能不是你想要的。這裏推薦使用elasticsearch-analysis-ik,支持自定義詞庫。

  • 下載

    wget https://github.com/medcl/elasticsearch-analysis-ik/archive/v1.9.4.tar.gz
  • 解壓

    tar -xvf elasticsearch-analysis-ik.tar.gz
  • 使用maven打包該java項目

    cd elasticsearch-analysis-ik-1.9.4
    mvn package
  • 在plugins目錄下建立ik目錄,並將打包好的IK插件解壓到其中

    mkdir /usr/share/elasticsearch/plugins/ik
    unzip target/releases/elasticsearch-analysis-ik-1.9.4.zip -d /usr/share/elasticsearch/plugins/ik/

    elasticsearch-analysis-ik 的配置文件在 ~/{es_root}/plugins/ik/config/ik/ 目錄,不少都是詞表,直接用文本編輯器打開就能夠修改,改完記得保存爲 utf-8 格式。

如今再啓動 Elasticsearch 服務,若是看到相似下面這樣的信息,說明 IK Analysis 插件已經裝好了

plugins [analysis-ik]

使用 Elasticsearch

在使用以前,先大概瞭解下ES的特色:

網上一般會將Elasticsearch和傳統關係型數據庫Mysql作一下類比:

MySQL Elasticsearch
Database(數據庫) Index (索引)
Table(表) Type (類型)
Row (行) Document (文檔)
Column (列) Field (字段)
Schema (方案) Mapping (映射)
Index (索引) Everything Indexed by default (全部字段都被索引)
SQL (結構化查詢語言) Query DSL (查詢專用語言)

Elasticsearch不只僅是全文搜索:

  • 分佈式的實時文件存儲,每一個字段都被索引並可被搜索

  • 分佈式的實時分析搜索引擎

  • 能夠擴展到上百臺服務器,處理PB級結構化或非結構化數據

分佈式實時每一個字段PB級,有點不明覺厲~ 不要慌,剛認識不熟悉很正常,慢慢接觸,天然就熟絡了,stop getting off track(迴歸正題),想要詳細認識ES,請移步Elasticsearch權威指南,接下來就是一步步將ES集成進項目當中:

1. 使用package

能夠直接使用官方提供的package,因爲不想花時間重複造輪子,我直接使用進一步封裝的第三方package。在github上有好幾個可用的,我選了Elasticquent,部分是由於名字和laravel的Eloquent比較搭(笑...)。Elasticquent提供了簡潔好用的trait,直接集成進你的Model裏,例如Article:

...
use Elasticquent\ElasticquentTrait;

class Article extends Model
{
    use ElasticquentTrait;
        ...
}

而後就能夠優雅的使用Elasticsearch了,具體如何安裝使用,請參考Elasticquent的說明文檔。

2. 配置Mapping

關於Mapping(映射),我找到了一篇專門介紹它的文章(傳送們),通俗易懂。

文章中提到,mapping不只告訴ES一個field中是什麼類型的值, 它還告訴ES如何索引數據以及數據是否能被搜索到。

Got it! 也就是說,若是咱們不配置mapping,那ES就不會知道咱們是想讓它按照IK的分詞方式來進行索引咯~

到這裏,不得不說這是一個坑,目前網上的不少資料由於使用的是老版本的ES和IK,因此index和mapping的配置通常都放在es的配置文件yml當中。但我按照那種配置方法,並無達到預期的分詞效果,ES仍是簡單粗暴的將漢字一個個的切開,屢敗屢戰折騰兩天以後,終於想到試着使用Elasticquent說明文檔裏在Model中配置mapping的方式,果真,豁然開朗:

curl -XGET 'http://localhost:9200/_analyze?analyzer=ik&pretty=true&text=%e4%bd%a0%e5%a5%bd%e9%ba%a6%e8%82%af%e5%85%88%e7%94%9f'
{   
    "tokens" : [ {
        "token" : "你好",
           "start_offset" : 0,
        "end_offset" : 2,
        "type" : "CN_WORD",
        "position" : 0
    },
    {
        "token" : "麥",
        "start_offset" : 2,
        "end_offset" : 3,
        "type" : "CN_WORD",
        "position" : 1
    }, {
        "token" : "肯",
        "start_offset" : 3,
        "end_offset" : 4,
        "type" : "CN_WORD",
    "position" : 2
    }, {
        "token" : "先生",
        "start_offset" : 4,
        "end_offset" : 6,
        "type" : "CN_WORD",
        "position" : 3
    }]
}

附上個人mapping配置代碼

protected $mappingProperties = array(
   'title' => array(
        'type' => 'string',
        'analyzer' => 'ik_max_word'
    ),
   'content' => array(
        'type' => 'string',
        'analyzer' => 'ik_max_word'
    )
);

能夠看出,我告訴ES,個人title和content字段是string類型並且請按照ik的分詞方式幫我檢索。

3. 建立索引

直接使用Elasticquent提供的createIndex方法建立,若是想把現有文檔所有索引,可使用addAllToIndex方法,簡單愉快。

Article::createIndex($shards = null, $replicas = null);
Article::addAllToIndex();

4. 增刪改查

在你的控制器裏的增刪改查方法中,將Elasticquent提供的相應操做索引的方法依次加上便可,完成以後,那麼你對文檔的操做就會同步ES的索引了。具體代碼請直接移步Elasticquent開源項目中trait裏的代碼就好,這裏再也不貼出。

寫在最後

在此以前,瞭解過sphinx,使用過配置好的xunsearch,但真正本身從零開始研究全文搜索引擎仍是頭一次,中間遇到了許多坑,雖然被坑鬱悶,但也感謝這些坑,畢竟越過去就會有快感。寫這篇文章一來做爲記念和起點,二來但願能多少對別人有點幫助,由於我也是看過好多相關的文章才一點點將ES搭建完成,在這裏感謝那些樂於分享的前輩。

固然,Elasticsearch功能很強大,各類插件各類配置,這篇文章須要完善的地方還有不少,後期會不斷更新,若是文中有錯誤或者不嚴謹的地方,歡迎留言交流。

PS. 最後貼出我項目中的Dockerfile,方便感興趣的同窗使用。

原文連接:https://macken.me/article/elasticsearch-for-search

參考資料

相關文章
相關標籤/搜索