1. 程式人生 > >彈性搜尋(elasticsearch)最新入門攻略

彈性搜尋(elasticsearch)最新入門攻略

elassticsearch

能做什麼

elasticsearch是一個專用的站內全文搜尋引擎,基於開源的lucene實現,本身也是開源的產品,允許進行修改和再發布。

elasticsearch採用lucene作為它的索引和檢索核心,並且,提供了restful api進行服務管理和資料檢索,部署和使用都十分便捷。

更好的是,elasticsearch原生的支援叢集化和分散式,能夠很好的適應當前DT的潮流,做到高可用和易擴充套件。

什麼時候用

資料庫能夠很好的支援索引和搜尋,一般來說,如果公司剛剛起步,那麼沒有必要上來就弄一個es做搜尋服務。

如果,產品的基礎服務已經搭建好了,需要向更好的使用者體驗方面發展那麼這時候可以使用es這類的全文搜尋引擎了。

es不支援資料庫連表查詢功能,所以,es應該是搜尋的的輔助,原始資料應該仍然是儲存在資料庫裡面的。同步,要麼相關介面更新es索引,要麼採用阿里canal這樣的資料庫binlog同步工具。

es的搜尋方式是和baidu、360、神馬這些搜尋引擎的搜尋方式一樣的,搜尋的過程中首先會對搜尋詞條進行分詞,每一個分詞都會被作為匹配條件,最終所有分詞的匹配度加和給出所有命中項的匹配度分值,也就是相關度。

es返回的結果按照的就是相關度由大到小的順序。

好了,接下來我們看一下入門es的完整步驟,如果想了解更多關於es的高階功能,請參見最後推薦閱讀一章,尤其是其中的《elasticsearch權威指南》。

安裝部署

es有三種安裝方式:1.使用官方版本安裝,這種方式安裝需要自己安裝相關外掛;2.使用rtf版本安裝,這種方式已經添加了必要的中文分詞和索引外掛;3.使用docker映象安裝,這種方式直接安裝的是包含了es的虛擬機器。

使用rtf版本安裝

我使用的是2.2.0版本的rtf,下載後把壓縮包放到/usr/local中,執行以下命令解壓:

unzip elasticsearch-rtf-2.2.0.zip

cd到conf目錄,修改如下兩項:

cluster.name: 你的工程名
network.host: 區域網網絡卡地址

修改第一項,是因為es是採用廣播的方式尋找區域網內的其他es,如果叢集名相同則自動加入到叢集中。如果不修改,叢集名預設是elasticsearch,很容易被其他人部署的es,或者自己測試的es干擾,造成不可預測的問題。

修改第二項,是因為,es預設繫結的ip是127.0.0.1,不修改的話其他機器無法訪問這個es節點。

修改後,執行以下命令啟動es:

./elasticsearch -d

-d命令是指定es作為後臺程式執行,如果不加-d,當你遠端ssh連線伺服器,啟動es之後,一旦關閉了本季的命令列視窗,es也將自動關閉。

好了,啟動好只好,我們來和es打個招呼。es提供了restful的介面,所以這裡我們用curl請求,檢視一下es是否安裝成功。在命令列輸入命令:

安裝正確,應該可以得到如下形式的反饋:

{
  "name" : "Margali Szardos",
  "cluster_name" : "nggirl-es",
  "version" : {
    "number" : "2.2.0",
    "build_hash" : "8ff36d139e16f8720f2947ef62c8167a888992fe",
    "build_timestamp" : "2016-01-27T13:32:39Z",
    "build_snapshot" : false,
    "lucene_version" : "5.4.1"
  },
  "tagline" : "You Know, for Search"
}

錄入索引資料

可以使用如下命令建立一個索引

curl -XPUT http://ip:9200/myIndex -d ‘{“settings” :{“number_of_shards” :3,”number_of_replicas” : 1}}’

該索引的名稱是myIndex,共有3個分片,每隔分片有一個副本。

執行如下命令,在上述索引中插入資料

curl -XPUT http://ip:9200/myIndex/employee/1 -d ‘{“first_name” : “John”,”last_name” : “Smith”,”age” : 25,”about” : “I love to go rock climbing”, “interests”:[ “sports”, “music” ]}

上述命令在myIndex索引中的employee型別,插入了一個_id為1的員工資料。

也可以在沒有建立索引的情況下,直接執行插入資料的操作,那麼索引的設定會採用預設設定,即5個分片,每個分片1個副本。

要獲取上述資料可以執行如下命令

或者用更復雜的查詢,具體可參見推薦閱讀。

spring+elasticsearch整合

新增配置檔案

這裡不預設大家已經知道如何建立spring-mvc 的web工程。 以下的內容,均在spring-mvc工程中新增。這裡使用的spring版本是4.2.6、pring-data-elasticsearch 2.0.0.RELEASE、elasticsearch 2.2.0、所以elasticsearch-rtf必須使用2.2.0,否則連線失敗。

新增一個spring-elasticsearch.xml檔案,內容如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/data/elasticsearch
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">

    <elasticsearch:repositories base-package="com.pumpkin.carriage.repository.elasticsearch" />

    <!-- 本地檔案儲存,無需部署elasticsearch -->
    <!-- <elasticsearch:node-client id="client" local="true" /> -->
    <!-- 遠端elasticsearch服務 -->
    <elasticsearch:transport-client id="client" cluster-nodes="${application.parameter.elasticsearch.cluster.nodes}"  cluster-name="nggirl-es"/>

    <bean name="elasticsearchTemplate"
          class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
        <constructor-arg name="client" ref="client" />
    </bean>
</beans>

elasticsearch:repositories是repository介面檔案的包目錄,用於自動掃描例項化repository介面。

client是叢集bean物件,cluster-nodes是叢集中的節點ip列表,埠號用9300。因為client是作為一個叢集節點連結的,不是採用的restful介面。

elasticsearchTemplate是es的模板bean,會被自動注入到例項化的repository中。

說下node-client和transport-client。node-client是會儲存資料的節點,但是不參與資料獲取;transport-client是不儲存資料的節點,僅用來支援增刪改查。

當node-client的local設定為true時,會在tomcat相同的jvm中建立本地的es服務,隨tomcat一同啟動。

新增域模型

定義自己的業務模型,這裡以常見的使用者為例:

package com.pumpkin.carriage.model.elasticsearch;

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

@Document(indexName= "myIndex", type= "user", shards = 1, replicas = 0, refreshInterval = "-1")
public class ESUser {
    @Id
    private String userId;
    @Field(type = FieldType.String)
    private String profile;
    @Field(type = FieldType.String)
    private String nickName;
    @Field(type = FieldType.String)
    private String userRole;
    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    public String getProfile() {
        return profile;
    }
    public void setProfile(String profile) {
        this.profile = profile;
    }
    public String getNickName() {
        return nickName;
    }
    public void setNickName(String nickName) {
        this.nickName = nickName;
    }
    public String getUserRole() {
        return userRole;
    }
    public void setUserRole(String userRole) {
        this.userRole = userRole;
    }
}

其中的@Id欄位必須要有,該欄位會自動被設定成es中該物件的_id,也就是可以通過GET命令的id獲取方式獲得,也就是可以用:

方式獲得資料物件。

新增訪問介面(repository)

package com.pumpkin.carriage.repository.elasticsearch;

import java.util.List;

import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository;

import com.pumpkin.carriage.model.elasticsearch.ESUser;

public interface UserRepositry   extends ElasticsearchCrudRepository<ESUser, String>{
    List<ESUser> findByNickName(String nickName,Pageable pageable);

    List<ESUser> findByNickNameLike(String nickName,Pageable pageable);
}

findByNickName方法的作用是,獲取使用者名稱為nickName的使用者列表,Pageabel可以傳入一個PageRequest物件,包含頁數和每頁的大小。

findByNickNameLike方法的作用是,獲取使用者名稱模糊等於nickName的使用者列表。

要理解這裡,需要看推薦閱讀中的spring-data-jpa相關文件。

好了,這樣就可以把你的repository註冊給任何service了,配置和使用方式和mybatis如出一轍,十分相像。

使用web管理外掛

要檢視es叢集的狀態可以使用命令檢視

會返回如下形式的結果:

{
"cluster_name":"nggirl-es",
"status":"green",
"timed_out":false,
"number_of_nodes":1,
"number_of_data_nodes":1,
"active_primary_shards":2,
"active_shards":2,
"relocating_shards":0,
"initializing_shards":0,
"unassigned_shards":0,
"delayed_unassigned_shards":0,
"number_of_pending_tasks":0,
"number_of_in_flight_fetch":0,
"task_max_waiting_in_queue_millis":0,
"active_shards_percent_as_number":100.0
}

這樣不是很方便,也不是很全面,es有兩個外掛可以做到叢集資訊檢視和叢集管理,一個是官方的marvel,這個是收費的,一個是head,這個是免費的。接下來說一下head的安裝。

首先cd到elasticsearch/bin目錄,執行如下命令:

./plugin -install mobz/elasticsearch-head

這裡還缺少一些關於es安全防護和後期維護的問題,後續有機會再增加。

推薦閱讀