1. 程式人生 > >全文搜尋引擎Elasticsearch6.x 入門

全文搜尋引擎Elasticsearch6.x 入門

   全文搜尋的需求非常大。而開源的解決辦法Elasricsearch(Elastic)就是一個非常好的工具。目前是全文搜尋引擎的首選。


   Elastic 的底層是開源的Lucene。Elastic提供了REST API的操作介面。是Lucene的擴充套件。底層依舊是索引,但是可以把大索引切成n片,放到不同的節點,所以就實現了分散式。也就理所當然的是讀寫負載均衡。此外,他還是一個分散式實時文件儲存,其中每個field可被搜尋。 ES 可以自動將海量資料分佈到多臺伺服器上去儲存和檢索海量資料。可以在秒級別在每臺伺服器上分析資料。

   下面簡單的介紹一下Elastic並且從零開始搭建一個Elastic。

一、簡介

    基本元件: (1).索引(index):文件容器,類似於關係型資料庫中的庫。索引名必須是小寫字母。

(2).型別(type):型別是索引內部的邏輯分割槽。其意義完全取決與使用者需求,一個索引內部可定義多個型別。類似於關係型資料庫中的表結構,欄位。

(3).文件(document):文件是Lucene索引和搜尋的原子單位。它包含多個域。基於JSON格式儲存。每個域的格式類似於字典

(4).對映(mapping):原始內容儲存為文件之前的分析,對映就是定義此對映過程該如何實現。(例如切詞,過濾)

   叢集元件:(1)Cluster:ES的叢集標識為叢集名稱。預設為“elasticsearch”,節點靠此名字決定加入到哪一個叢集中。一個節點只能屬於一個叢集。

 (2).Node:執行單個ES例項的主機。節點的標識靠節點名。

 (3).Shard:將索引切割成為的物理儲存元件,但每一個shared都是一個獨立且完整的索引,建立索引時,ES預設分割為5個shard。使用者也可以按需自定義,建立完成後不可修改。shard有兩種,primary和replica。用於負載均衡。

ES Cluster啟動過程。通過多播(或單播)在9300/tcp查詢同一叢集中的其他節點,並建立通訊。叢集中所有節點會選舉出一個主節點負責管理整個叢集狀態。以及在叢集範圍內決定shared的分佈。

二、安裝

     安裝環境 Linux centos7.3 3臺. 直接就安裝成叢集。Elastic 的安裝需要Java環境。不會配置Java環境的請參考

這篇文章

    這裡也簡單的演示一下JAVA的環境配置。首先準備好jdk的tar包。下載網頁

# mkdir /usr/java
# tar xf jdk-8u151-linux-i586.tar.gz -C /usr/java
# vim /etc/profile
JAVA_HOME=/usr/java/jdk1.8.0_151
export JRE_HOME=/usr/java/jdk1.8.0_151/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
# update-alternatives --install /usr/bin/java java /usr/java/jdk1.8.0_151/bin/java 300
# update-alternatives --install /usr/bin/javac javac /usr/java/jdk1.8.0_151/bin/javac 300
# update-alternatives --config java

共有 3 個程式提供“java”。

  選擇    命令
-----------------------------------------------
*+ 1           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
   2           /usr/lib/jvm/jre-1.6.0-openjdk.x86_64/bin/java
   3           /usr/java/jdk1.8.0_151/bin/java

按 Enter 來儲存當前選擇[+],或鍵入選擇號碼:3

    若出現 -bash: /usr/java/jdk1.8.0_151/bin/java: /lib/ld-linux.so.2: bad ELF interpreter: 沒有那個檔案或目錄  這個錯誤, 則執行 yum install glibc.i686  即可。

至此,安裝成功jdk。下來安裝Elasticsearch。下載頁面

    下載好rpm包。執行 

# rpm -ivh elasticsearch-6.1.1.rpm 
warning: elasticsearch-6.1.1.rpm: Header V4 RSA/SHA512 Signature, key ID d88e42b4: NOKEY
Preparing...                ########################################### [100%]
Creating elasticsearch group... OK
Creating elasticsearch user... OK
   1:elasticsearch          ########################################### [100%]
### NOT starting on installation, please execute the following statements to configure elasticsearch service to start automatically using chkconfig
 sudo chkconfig --add elasticsearch
### You can start elasticsearch service by executing
 sudo service elasticsearch start
啟動Elasticsearch。
# systemctl start elasticsearch
接下來修改配置檔案。

# vim /etc/elasticsearch/elasticsearch.yml

cluster.name:  my-elastic
# 叢集名字,相同叢集名字的節點會放到同一個叢集下

node.name: "node-1"
# 節點名字

discovery.zen.minimum_master_nodes: 2
#指定叢集中的節點中有幾個有master資格的節點。
#對於大叢集可以寫3個以上。

discovery.zen.ping.timeout: 3s
#預設是3s,這是設定叢集中自動發現其它節點時ping連線超時時間

discovery.zen.ping.multicast.enabled: false
#設定是否開啟多播發現節點,預設是true。

network.bind_host: 192.168.40.129
#設定繫結的ip地址,這是我的虛擬機器的IP。

network.publish_host: 192.168.40.129
#設定其它節點和該節點互動的ip地址。

network.host: 0.0.0.0
#同時設定bind_host和publish_host上面兩個引數。

transport.tcp.port: 9300
#設定參與叢集的埠

http.port: 9200
#接收請求埠

#discovery.zen.ping.unicast.hosts:["節點1的 ip","節點2 的ip","節點3的ip"]
#指明叢集中其它可能為master的節點ip,以防es啟動後發現不了叢集中的其他節點。
啟動後,發現9200,9300埠處於監聽狀態。 如果發現,network.host不能繫結到0.0.0.0上。(一啟動就出錯,則可能的原因如下)


接下來給其餘的兩個節點同樣的步驟安裝Elasticsearch。

三、核心概念

        首先,elasticsearch 是基於lucene開發,lucene的開發十分複雜,api複雜(需要大量的java程式碼才能完成一個簡單的功能)。     (1) Near RealTime(NRT):近實時。基於es的搜尋在秒級別。     (2) Index (索引):包含一堆相似結構的文件資料。比如客戶索引,商品索引,訂單索引,索引有一個名稱,一個index包含很多個document。
    (3) Documents (文件): es的最小資料單元。一個document可以是一條客戶資料,一條商品分類資料,一條訂單資料,通常是JSON資料表示,每個index下的type中,都可以去儲存多個document。一個document裡面有多個field。每個field就是一個數據欄位。     
{
  "id" : "qWAEoJU",
  "product_name" : "蒂花之秀",
  "product_desc" : "烏黑亮麗",
  "category" : "2",
  "category_name" : "日化用品"
}

    (4) Type (型別):每個索引裡有一個或者多個type。type是index中的一個邏輯資料分類。一個type下的document都有相同的field。
       比如商品index。裡面存放了所有的商品資料。商品document。但商品的種類很多。每個種類的document的field可能不太一樣。比如電器商品和生鮮商品。(生鮮商品type,電器商品type,日化商品type)       日化商品type:id ,product_name ,product_desc,category_id,category_name       電器商品type:id ,product_name ,product_desc,category_id,category_name,service_period       生鮮商品type:id ,product_name ,product_desc,category_id,category_name,eat_period
然後每一個type內又有一堆的document。就不舉例了。        (5) Shard:單臺伺服器無法儲存大量的資料,es可以將一個索引中的資料分為多個shard。分佈在很多臺伺服器上,有了shard就實現了橫向擴充套件。儲存更多的資料。讓搜尋和分析操作分佈到多臺伺服器上去執行。
    (6) replica:為了防止某一臺伺服器上的shard丟失。因此可以為每個shared建立多個replica副本。多個replica可以提升搜尋操作的吞吐和效能。primary shard(建立索引時一次性建立,預設5個)replica shard(隨時修改,預設一個)。
下圖詳細的介紹了 shard和replica。


四、安裝後相關簡介

     通過rpm包安裝之後。會安裝上很多的檔案。除了/etc/elasticsearch 下的配置檔案外,還有很多。
# pwd
/usr/share/elasticsearch/bin
# ls
elasticsearch  elasticsearch-env  elasticsearch-keystore  elasticsearch-plugin  elasticsearch-translog
 這些命令是es的外掛,日誌等管理工具。plugins 是放es相關外掛的。

接下來下載和安裝解壓縮Kibana。使用裡面的開發介面,去操作Elasticsearch。
# yum -y install kibana-6.1.1-x86_64.rpm
安裝完成後、可簡單修改其配置檔案 /etc/kibana/kibana.yml 改變其監聽埠(預設是localhost)。 通過  systemctl  start  kibana 啟動。而後通過瀏覽器訪問。

  之後就可以通過kibana 的dev tool去操作

  叢集狀態:     green: 每個索引的primary shard和replica shard 都是active狀態     yellow:每個索引的primary shard 都是active 但是 部分索引的replica不是active的     red:有部分索引的primary shard 不是active的。

五、簡單操作

     索引操作 (1)、檢視叢集中都有哪些索引。
curl -X GET localhost:9200/_cat/indices
 (2)、建立索引。   
# curl -X PUT localhost:9200/test_index?pretty
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "test_index"
}
 (3)、刪除索引。   
# curl -X DELETE localhost:9200/test_index?pretty
{
  "acknowledged" : true
}

六、入門案例實戰

   模擬場景:電商網站。需要基於ES構建的後臺系統。提供以下功能。  (1)、對商品進行CRUD(增刪改查)操作  (2)、執行簡單的結構化查詢  (3)、可以執行全文檢索,以及複雜的phrase(短語)檢索  (4)、對於全文檢索內容可以進行高亮顯示  (5)、對資料進行局和分析             一、新增商品,新增文件,新增索引。
PUT /ecommerce/product/1
{
  "name" : "xiaomi6",
  "desc" : "wei fashao ersheng",
  "price" : "2300",
  "producer" : "xiaomi keji",
  "tags" : ["heikeji","fashao"]
}

PUT /ecommerce/product/2
{
  "name" : "iphoneX",
  "desc" : "gaoduan daqi",
  "price" : "8300",
  "producer" : "apple",
  "tags" : ["qianwei","shishang"]
}
二、檢索商品。
# curl -XGET localhost:9200/ecommerce/product/1
{"_index":"ecommerce","_type":"product","_id":"1","_version":1,"found":true,"_source":{
  "name" : "xiaomi6",
  "desc" : "wei fashao ersheng",
  "price" : "2300",
  "producer" : "xiaomi keji",
  "tags" : ["heikeji","fashao"]
}

三、修改,替換商品
可以直接替換,也可以修改。
POST /ecommerce/product/1/_update
{
  "doc":{
  "price": "2400"
  }
}
四、刪除商品
DELETE /ecommerce/product/1

高階操作

 搜尋所有的商品。
GET ecommerce/product/_search
查詢結果: took: 消耗了幾毫秒。 timed_out:是否超時 _shards:資料拆分成了5個分片。所以對於搜尋請求。會打到所有的primary shard 或 replica shard  hits.total:查詢結果的數量。2個 hits.max_score:score的含義,就是document對於一個search相關度的分配分數。越相關,就越匹配。
{
  "took": 90,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 1,
    "hits": [
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "2",
        "_score": 1,
        "_source": {
          "name": "iphoneX",
          "desc": "gaoduan daqi",
          "price": "8300",
          "producer": "apple",
          "tags": [
            "qianwei",
            "shishang"
          ]
        }
      },
      {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "1",
        "_score": 1,
        "_source": {
          "name": "xiaomi6",
          "desc": "wei fashao ersheng",
          "price": "2400",
          "producer": "xiaomi keji",
          "tags": [
            "heikeji",
            "fashao"
          ]
        }
      }
    ]
  }
}

查詢名字裡帶 xiaomi 的商品。
GET /ecommerce/product/_search?q=name:xiaomi
GET /ecommerce/product/_search
{
  "query" : {
    "match" : {
       "name" :"xiaomi"
    }
  }
}
分頁查詢商品,總共3條商品。假設每頁就顯示一條。現在顯示第2頁。
GET ecommerce/product/_search
{
  "query":{
    "match_all": {}},
    "from":1,
    "size":1
}
只查出名稱和價格
GET ecommerce/product/_search
{
  "query":{
    "match_all": {}
  },
  "_source": ["name","price"]
}

查出商品包含xiaomi且價格大於2000元的。
GET ecommerce/product/_search
{
  "query":{
    "bool":{
      "must":{
        "match":{
          "name":"xiaomi"
        }
      },
      "filter":{
        "range":{
          "price":{
            "gt": 2000
          }
        }
      }
    }
  }
}
短語搜尋,與全文搜尋相對應。短語搜尋是必須匹配。
GET ecommerce/product/_search
{
  "query":{
    "match_phrase":{
      "producer": "keji"
    }
  }
}
搜尋高亮顯示。
GET ecommerce/product/_search
{
  "query":{
    "match":{
      "producer": "keji"
    }
  },
  "highlight": {
    "fields": {
      "producer": {}
    }  
  }
}

更多詳細的查詢語法或其他內容   


































Text-to-speech function is limited to 200 characters
Options :History :Feedback :Donate Close