1. 程式人生 > >Elastic Search 新手筆記(1)——入門篇

Elastic Search 新手筆記(1)——入門篇

前言

之前寫過一個關於Elastic Search的文章,當時的我還不會使用markdown,還不知道怎麼好好把自己所想的,總結成一個有條理的文章,所以我就想寫下了這一篇新文章,幫助自己消化所學的東西,也可以把知識分享給大家。

使用 版本
作業系統 MacOS
ES版本 6.3.0
視覺化外掛 Head

安裝

1.單例項安裝

elasticSearch 的安裝我覺得相對簡單一些,我們可以在官網或者是別的途徑,下載到它,官網的下載地址為https://www.elastic.co/downloads/elasticsearch,當前最新的版本為6.4.2。而我使用的版本是6.3.0,如果想要下載到原來版本的ES,可以進入以下網址進行下載

https://www.elastic.co/downloads/past-releases。 下載好後,執行bin目錄下的elasticsearch即可。 啟動後,在瀏覽器輸入http://localhost:9200/即可,效果如下: image.png

2.Head外掛安裝

Head外掛是依託於node環境的,我們在使用外掛之前需要先下載node.js。node.js下載好後,通過node -v 檢視是否安裝成功,然後就可以通過以下網址下載Head外掛。Head 外掛地址。下載好Head外掛以及elasticsearch後,需要修改在elasticsearch 中的config的elasticsearch.yml中加上以下配置內容:

http.cors.enabled: true 
http.cors.allow-original: "*"

保證了Es以及Head外掛的連通性。 Head外掛的啟動 1.npm install [email protected] --ignore-scripts(之所以不使用npm install 是因為這個包,一直都取不到,但是它也不怎麼影響使用。) 2.npm install 3.npm run start 啟動後,在瀏覽器輸入http://localhost:9100,如果顯示了相關內容即可。

3.分散式安裝

分散式的安裝和單例項安裝大同小異,把下載下來的ElasticSearch複製兩個副本,放在新建立的目錄ES_slave(slave為隨從奴隸的意思,在這裡把我們之前安裝好的當做一個master,然後其他的slave配合master形成一套分散式)中,如下圖所示: image.png

這裡是建立了兩個,如果有需求,可以根據需求繼續拓展。 然後把兩個slave中的elasticsearch.yml檔案進行修改,加入以下配置:

#配置ElasticSearch的叢集名稱
cluster.name: harry
#節點的名稱(另一個節點名稱可以使用slave2)
node.name: slave1
#設定繫結的IP地址
network.host: 127.0.0.1
#設定對外服務的埠號,預設情況下為9200(這裡只要使用沒被使用的埠號即可)
http.port: 8200
#設定是否開啟多播發現節點,如果不進行配置,不會被主節點發現。
discovery.zen.ping.unicast.hosts: ["127.0.0.1"]

配置好後,啟動slave的elasticsearch即可。 Tips:我啟動的時候報了一個錯誤。

[2018-10-07T11:57:44,907][INFO ][o.e.d.z.ZenDiscovery     ] [slave1] failed to 
send join request to master [{master}{dLNpAPsSTvCFgzow1nuM6g}
{lZIG2Xm3Sx-4Y4eHU5x9CA}{127.0.0.1}{127.0.0.1:9300}
{ml.machine_memory=8589934592, ml.max_open_jobs=20, 
xpack.installed=true, ml.enabled=true}], reason 
[RemoteTransportException[[master][127.0.0.1:9300]
[internal:discovery/zen/join]]; nested: IllegalArgumentException[can't add node 
{slave1}{dLNpAPsSTvCFgzow1nuM6g}{4NUyj79cSxuaJL8BMtGejw}{127.0.0.1}
{127.0.0.1:9301}{ml.machine_memory=8589934592, ml.max_open_jobs=20, 
xpack.installed=true, ml.enabled=true}, found existing node {master}
{dLNpAPsSTvCFgzow1nuM6g}{lZIG2Xm3Sx-4Y4eHU5x9CA}{127.0.0.1}
{127.0.0.1:9300}{ml.machine_memory=8589934592, xpack.installed=true, 
ml.max_open_jobs=20, ml.enabled=true} with the same id but is a different 
node instance]; ]

因為我是把master的Es複製過來,作為slave,但是data中還有原來的資料,所以報了這個錯,只要把,Es中的data資料夾中的東西都刪除就行。 我們現在把master 的ES啟動,slave1的ES啟動,slave2的ES啟動,最後把Head也啟動起來,然後瀏覽器輸入http://localhost:9100,效果如下,證明成功。 image.png

基本概念

1.索引,型別,文件

Elastic Search 與關係型資料庫對比

Elastic Search 關係型資料庫
索引 資料庫
型別
文件

這裡的Elastic Search 泛指的是全文檢索。一個索引中,包含多個型別,一個型別中包含著多個文件。 在剛接觸的時候,我想過這樣一個問題,在關係型資料庫mysql的like進行模糊查詢的效果,與Elastic Search這樣的全文檢索,效果幾乎就是一樣的,那為什麼還要用全文檢索呢? 原因我覺得一共有兩個: 第一個是查詢的速度特別快。在關係型資料庫中,資料是結構化的,我們當要進行模糊查詢的時候,會從想要查詢的表的第一條資料開始比對,如果不是,繼續下一條,如果再不是,繼續去查,就這樣一直查下去,直到查到了,自己想要的那條資料。而Elastic Search呢?它其實使用了倒排索引。大概意思其實是這樣的:現在一個有三篇文章

id content
文章1 Java是世界上最好的 .
文章2 人生苦短,快學python
文章3 C++是世界上最難的 .

這也是儲存在關係型資料庫中的儲存形式,查詢的話,他會一行行的進行查詢。而如果存在了Elastic Search 中會變成什麼樣子呢?在全文檢索中存在這分詞器這麼個東西,分詞器會把輸入的句子自動的進行一定規律進行分割,例如過空格分割,下劃線分割,等等。如果是中文,也有外掛可以對其進行語義分割。分割後的效果如下所示(只是舉例子,真實情況未必如此)

關鍵詞 文章號
世界 1,3
人生苦短 2 .
Java 1 .
python 2
C++ 3

當我們輸入世界,立刻就知道出現在了第一個,和第三個文章中。 第二個是因為我們在做全文檢索的時候,根本用不到那麼複雜的邏輯,我們用到基礎的增刪改查就行,使用了Elastic Search 之後,我們在也不用折騰資料庫那麼多的資料了。

2.分片與索引

每一個索引包含了多個分片,每個分片是一個lucene索引(lucene是Elasticsearch的底層引擎。)只需要將分片拷貝一份,就完成了分片的備份。

3.叢集和節點

每一個叢集都有一個叢集的名字,一個叢集包含多個節點。我們只需要知道叢集的名稱,便可以拓展叢集中的節點。

4.elasticsearch.yml

我上面在啟動head外掛和設定分散式叢集的時候,有修改過這個檔案,但是這個檔案還有別的可配置屬性,我在這裡說明一下,以備不時之需。

cluster.name: elasticsearch
#設定叢集名稱,一個叢集只可以有一個名稱,ElasticSearch會自己去查詢同一個網段下的所有節點
node.name: node-1
#設定節點名稱
node.master: true
#設定該節點是否是master節點,預設為true
node.data: true
#設定該節點,是否儲存索引資料,預設為true
index.number_of_shards: 5
#設定分片的數量,預設為5個,這個配置只在5.0版本之前好用
index.number_of_replicas: 1
#設定索引副本數量,預設為一個,同樣也是隻在5.0之前好用。
path.data: /path/to/data
#設定索引資料的儲存路徑,預設在data資料夾下,可以設定多個檔案儲存路徑,用逗號分隔。
path.logs: /path/to/logs
#設定log日誌的儲存路徑,預設情況下是在logs資料夾下。
bootstrap.mlockall: true
#設定為true來鎖住記憶體
network.host: 0.0.0.0
#設定繫結的Ip地址,預設為0.0.0.0
http.port: 9200
#設定對外服務的HTTP埠號
transport.tcp.port: 9300
#設定節點間互動的TCP埠號,也是給Java API使用的埠號,預設是9300。
transport.tcp.compress: false
#是否壓縮TCP傳輸的資料,預設為false
http.cors.enabled:true
#是否使用http提供對外的服務,預設為true
http.max_content_length: 100mb
#http傳輸內容的最大容量。
discovery.zen.minimum_master_nodes: 1
#發現master節點的數量,預設為1個。
discovery.zen.ping.timeout: 3s
#發現其他節點,超時的時間。
discovery.zen.ping.multicast.enabled:true
#是否開啟多播發現節點。
discovery.zen.ping.unicast.hosts:["host1","host2:port","host3:[portX-portY]"]
#設定叢集master幾點的初始列表。
script.engine.groovy.inline.update: on
#開啟groovy指令碼的支援
script.inline: true
#開始所有指令碼語言行內執行所有的操作。

基本用法

Elastic Search 我們可以使用REST API與其進行互動,說白了就是使用url地址,通過不同的method(get,post,put,delete)傳入不同的json資料。 head外掛雖然很好,但是也並不是萬能的,我比較習慣用Post man進行api互動。下面講講具體的操作。 1.建立索引

url地址 method 用途
localhost:9200/索引名稱 put 建立索引

在建立索引之前,我要先說兩個概念分別是靜態對映和動態對映。 動態對映是在建立索引之初,不新增索引的型別和文件中屬性的格式,而是在新增文件的時候,格式會被自動轉化。兩種不同對映的設定,是由dynamic引數來決定的一共有三個可選值:

  • true 動態對映自動新增欄位
  • false 靜態對映,不會自動新增欄位
  • strict 靜態對映,如果添加了新欄位會報錯

動態轉換內容如下:

JSON格式的資料 自動推測的欄位型別
null 沒有欄位被新增
true or false boolean
浮點型別數字 float
數字 long
JSON物件 object
陣列 有陣列中第一個非空值決定
string 有可能是date型別(開啟日企檢測),double,long,text,keyword

動態對映json體:

{
	"settings":{
		"number_of_shards":3,
		"number_of_replicas":1
	}
}

number_of_shards是用來設定分片數量的 number_of_replicas是用來設定副本數量的 靜態對映Json體:

{
	 "settings":{
        "number_of_shards":3,
        "number_of_replicas":1
    },
    "mappings":{
    	"it": {
    		"dynamic":"strict",
    		"properties":{
    			"title":{
    				"type":"text"
    			},
    			"content":{
    				"type":"text"
    			},
    			"create_date":{
    				"type":"date"
    			}
    		}
    	}
    }
}

這裡的it指的就是型別,在properties中新增自己的欄位,並且指定屬性的型別。 另外發送請求的content-type一定得是application/json,這個值得注意,成功後,會返回一個屬性acknowledged 是true的,就說明建立成功,其他的如下圖(Tips:幾個更換 json體,這裡的截圖只是一個示範): image.png 檢視head外掛,如下圖 image.png 我們可以看到這裡建立了三個分片(細線為粗線的副本)。

2.插入文件

url地址 method 用途
localhost:9200/索引名稱/型別名稱/文件id put 建立文件(指定文件id)
localhost:9200/索引名稱/型別名稱 post 建立文件(隨機文件id)

3.修改文件

url地址 method 用途
localhost:9200/索引名稱/型別名稱/文件id/_update post 修改文件

json體:

{
  "doc":{
    "修改欄位名稱": "想要修改成的值"
  }
}

4.刪除文件

url地址 method 用途
localhost:9200/索引名稱/型別名稱/文件id delete 刪除文件

5.查詢文件 這裡先介紹簡單的查詢,複雜的地方,會在後面說到。

url地址 method 用途
localhost:9200/索引名稱/型別名稱/文件id get 查詢文件通過文件id
localhost:9200/索引名稱/型別名稱/_search post 查詢所有資料

簡單查詢資料結構體為

{
  "query":{
    "match_all":{},(通過該屬性查詢所有資料)
    "match":{
      "需要查詢的欄位名稱":"查詢的值"
    }
  },
  "from": "從第幾個開始"(可選),
  "size": "要查詢多少個"(可選) ,
  "sort": [
    {"欄位名稱":{"order": "desc 或者是 asc"}}(自定義排序,預設通過score元欄位進行排序)
  ]
}

聚合查詢結構體為: (可以定義多個聚合條件,放在不同的聚合名稱中)

{
  "aggs":{
    "聚合名稱1(自定義)": {
      "terms":{
        "field": "通過該欄位進行聚合"
      },
      "status":{
         "field": "通過該欄位進行聚合"(status key可以計算這個聚合的相關引數)
       }
    },
    "聚合名稱2(自定義)": {
       "terms":{
        "field": "通過該欄位進行聚合"
      }
    }
  }  
}

後記

這篇文章是學習了慕課網上瓦力老師的教程並參考《從lucene到Elasticsearch全文檢索實戰》所寫,課程地址為https://www.imooc.com/learn/889,在此感謝你們的分享,我會在後續的文章中繼續總結elasticsearch的更多查詢語法,以及Spring Boot 整合 Elastic Search 的相關知識。