ElasticSearch 簡介
Elasticsearch 是一個基於 Lucene 的搜尋伺服器。它提供了一個分散式多使用者能力的 全文搜尋引擎,基於 RESTful web 介面。Elasticsearch 是用Java語言開發的,並作為 Apache 許可條款下的開放原始碼釋出,是一種流行的企業級搜尋引擎。
Elasticsearch 是與名為 Logstash 的資料收集和日誌解析引擎以及名為 Kibana 的分析和視覺化平臺一起開發的。這三個產品被設計成一個整合解決方案,稱為 “Elastic Stack”(以前稱為“ELK stack”)。
ElasticSearch 概念介紹
Elasticsearch 是面向文件型資料庫,一條資料在這裡就是一個文件。為了理解,可以將Elasticsearch 裡儲存文件資料和關係型資料庫 MySQL 儲存資料的概念進行一個類比
- es 的 Index 就相當於 MySql 的資料庫
- es 的 type 相當於 MySql 的表
- es 的 Document 相當於 MySql 的一行記錄
- es 的 Field 相當於 MySql 的欄位
Elasticsearch 7.X 中, Type 的概念已經被刪除了
本文不在講述
- 分片:一個物理機器的效能是有瓶頸的,直接往物理機上存資料,儲存數量有上限。es 採用了分片的概念,將海量資料切分成片,每一個分片,儲存一部分資料。相當於 MySql 的分庫, es 在一整個大的叢集裡,包含很多節點,每個節點又包含很多分片,這樣,海量資料由叢集來承載。
- 副本(replica)又叫從分片,分片的備份,防止資料丟失。並且當主分片出現物理故障時,從分片頂上去,負責資料的檢索等只讀請求。從分片的數量可變,不用重新建庫。
Docker-Compose 安裝 ElasticSearch
透過 Docker-compose 進行 ElasticSearch 和 Kibana 整合。本文所用案例在 倉庫 已經整合,可根據 專案的 readmi.md
進行 clone 和使用
整合 ElasticSearch
docker-compose.yml 檔案
elasticsearch:
build:
context: ./services/elasticsearch #所用映象
args:
ELASTICSEARCH_VERSION: ${ELASTICSEARCH_VERSION} #所使用的的版本
ELASTICSEARCH_PLUGINS: ${ELASTICSEARCH_PLUGINS} #需要安裝的外掛
container_name: elasticsearch #容器名
environment: #設定邊來你跟
- TZ=$TZ # 市區設定
- discovery.type=single-node #單節點模式
- "ES_JAVA_OPTS=-Xms512m -Xmx512m" #JVM 記憶體堆大小
volumes: #檔案對映
- ${DATA_DIR}/esdata:/usr/share/elasticsearch/data
- ${ELASTICSEARCH_CONF_FILE}:/usr/share/elasticsearch/config/elasticsearch.yml
- ${ELASTICSEARCH_IK_CONFIG_FILE}:/usr/share/elasticsearch/config/analysis-ik/IKAnalyzer.cfg.xml #IK 分詞器的詞庫配置檔案
- ${ELASTICSEARCH_IK_DIC}:/usr/share/elasticsearch/config/analysis-ik/my.dic #自定義詞庫檔案
hostname: elasticsearch # 主機名
restart: always
ports:
- "${ELASTICSEARCH_HOST_PORT_C}:9200" # 客戶端埠
- "${ELASTICSEARCH_HOST_PORT_S}:9300" # 服務端埠
networks: #docker-compose 配置的網路組
static-network:
ElasticSearch 預設安裝的 IK 分詞器,所以先把詞庫配置檔案對映出來,方便自定義詞庫
.env 檔案
ELASTICSEARCH_VERSION=7.8.1 # 版本號
ELASTICSEARCH_CONF_FILE=./services/elasticsearch/elasticsearch.yml # es配置檔案
ELASTICSEARCH_HOST_PORT_C=9200 #埠
ELASTICSEARCH_HOST_PORT_S=9300 #服務端埠
ELASTICSEARCH_PLUGINS=analysis-ik # es 需要安裝的外掛
ELASTICSEARCH_IK_CONFIG_FILE=./services/elasticsearch/ik/IKAnalyzer.cfg.xml
ELASTICSEARCH_IK_DIC=./services/elasticsearch/ik/my.dic
整合 Kibana
Kibana 是一個開源的分析與視覺化平臺,設計出來用於和 Elasticsearch 一起使用的。你可以用kibana 搜尋、檢視存放在 Elasticsearch 中的資料。Elasticsearch、Logstash 和 Kibana 這三個技術就是我們常說的ELK技術棧,可以說這三個技術的組合是大資料領域中一個很巧妙的設計。一種很典型的MVC思想,模型持久層,檢視層和控制層。Logstash擔任控制層的角色,負責蒐集和過濾資料。Elasticsearch擔任資料持久層的角色,負責儲存資料。而 Kibana 擔任檢視層角色,擁有各種維度的查詢和分析,並使用圖形化的介面展示存放在 Elasticsearch 中的資料。
docker-compose.yml 檔案
kibana:
image: kibana:${KIBANA_VERSION} # 映象
container_name: kibana # 容器名
environment: #引數
TZ: "$TZ"
elasticsearch.hosts: http://elasticsearch:9200 # 和 es 進行關聯
I18N_LOCALE: "${KIBANA_I18N_LOCALE}" #語言設定
hostname: kibana #主機名
depends_on: # Kibana 啟動要取決於 es 是否啟動
- elasticsearch
restart: always
ports:
- "${KIBANA_HOST}:5601"
networks:
static-network:
.env 檔案
#
# KIBANA
#
KIBANA_VERSION=7.8.1
KIBANA_HOST=5601
KIBANA_I18N_LOCALE=zh-CN
執行 ElasticSearch
當整合完畢後,透過 docker-compose up -d
來進行啟動和後臺執行,透過 Docker 客戶端可以看到
此時訪問本地或伺服器的 9200
埠可檢視 es
執行檢視 Kibana,請求本地或伺服器的 5601
埠,可檢視
ElasticSearch 使用
es 是基於 RESTful web 介面,所以根據不同的請求,可進行不同的操作,本文使用 Kibana 工具進行對 es 的訪問和使用
索引簡單基礎使用
要是用 es 儲存資料,需要先建立一個 索引
(相當於 MySql 的資料庫)
透過
PUT
請求建立一個簡單的索引
透過
GET
獲取剛建立的索引
{ "user" : { //索引名 "aliases" : { }, //別名 "mappings" : { }, //對映 "settings" : { //設定 "index" : { "creation_date" : "1630057022470", //建立時間 "number_of_shards" : "1", //分片數量 "number_of_replicas" : "1", //備份數量 "uuid" : "cfbmaM-2SM2vr-EvciKUug", //唯一標識 "version" : { "created" : "7080199" }, "provided_name" : "user" } } } }
透過
DELETE
方法刪除索引
文件簡單基礎使用
索引建立好之後,就可以透過介面來建立文件,並新增資料。這裡的文件可以類比為關係型數
據庫中的表資料,新增的資料格式為 JSON
格式
透過
POST
方法來建立文件,需加上預設的 type 型別_doc
{ "_index" : "students", //索引名 "_type" : "_doc", //預設 type 型別 "_id" : "-vBqm3sBvfOuEZni9DUz", //生成的唯一id,類比 mysql 的 id "_version" : 1, //版本 "result" : "created", //操作結果 "_shards" : { //分片 "total" : 2, //分片總數 "successful" : 1, "failed" : 0 }, "_seq_no" : 0, "_primary_term" : 1 }
上面建立資料後,由於沒有指定資料唯一性標識(ID),預設情況下,ES 伺服器會隨機生成,
建立指定
id
的資料,如果有 id,使用PUT
方法也可以
透過
GET
方法,檢視文件,需要帶入 id 進行查詢
透過
POST
方法,修改某一個欄位的值
透過
DELETE
方法刪除文件資料
刪除一個文件不會立即從磁碟上移除,它只是被標記成已刪除(邏輯刪除)。當然沒有 id,也可以根據查詢條件進行刪除,後續會說明
索引對映
對映是定義文件及其包含的欄位如何儲存和索引的過程,相當於 MySql 的表欄位型別設定。每個文件都是一個欄位的集合,每個欄位都有自己的 資料型別
。
對映和索引是一對一的關係。對映分為 靜態對映
和 動態對映
。
動態對映
靜態對映:新增文件時,如果檢測到新欄位,Elasticsearch會新建該文件欄位的特性生成一個動態對映,也就是 Es 自動推斷並設定新欄位的資料型別等。
欄位對映型別和JSON文件欄位型別的關係如下:
JSON資料型別 | ES 推斷的資料型別 |
---|---|
null | 未新增欄位 |
true 或者 false | boolean |
double | float |
integer | long |
object | object |
array | 取決於陣列中的第一個非null值 |
string | 根據字串內容特徵而定,有可能為text/keyword/double/long/date型別等 |
使用 Kibana 向 ES 建立如下文件
PUT /person/_doc/1
{
"id": 1,
"name": "張三",
"height": 180.52,
"man": true,
"country": "中國",
"born": "1950-6-14",
"child": ["李四", "王五", "趙六"]
}
ES 會自動建立 person 索引,並動態對映欄位型別
GET /person/_mapping
查詢索引的對映資訊
{
"person" : {
"mappings" : {
"properties" : {
"born" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"child" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"country" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"height" : {
"type" : "float"
},
"id" : {
"type" : "long"
},
"man" : {
"type" : "boolean"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
可以看到 ES 依據建立的 JSON 資料推斷並建立了資料的型別
靜態對映
既然 ES 能自動推斷欄位型別,那麼也就可以在建立索引的時候,手動進行欄位的型別定義,類似於MySQL 的建表操作。
- 透過
PUT /students/_mapping
向 students 索引建立靜態對映PUT /students/_mapping { "properties":{ "title":{ "type": "keyword", "index": true }, "image":{ "type":"keyword", "index": false }, "content":{ "type":"text", "index":true, "analyzer":"ik_max_word" }, "sell":{ "type":"long" } } }
- 透過
GET /students/_mapping
檢視建立的對映資訊{ "students" : { "mappings" : { "properties" : { "age" : { "type" : "long" }, "content" : { "type" : "text", "analyzer" : "ik_max_word" }, "desc" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "image" : { "type" : "keyword", "index" : false }, "name" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "sell" : { "type" : "long" }, "sex" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "title" : { "type" : "keyword" } } } } }
關於索引的靜態對映,基礎的資料有
- 欄位名:任意填寫,欄位名字
- type:型別,就是欄位型別,Es 支援的欄位型別有很多,常用的有
- string
- text 可分詞,欄位的內容會被分詞器進行分詞,然後形成倒排索引
- keyword 不可分詞,資料會作為完整欄位進行匹配
- Numerical
- 基本資料型別:long、integer、short、byte、double、float、half_float
- 浮點數的高精度型別:scaled_float
- Date 日期型別
- array 陣列型別
- object 物件型別
- string
- index:是否索引,預設為 true,也就是說你不進行任何配置,所有欄位都會被索引
true:欄位會被索引,則可以用來進行搜尋
false:欄位不會被索引,不能用來搜尋 - analyzer:分詞器,對這個欄位使用那種分詞器,這裡的 ik_max_word 即使用 ik 分詞器
string 的 text 和 keyword
text
1:支援分詞,全文檢索,支援模糊、精確查詢,不支援聚合,排序操作; 2:test型別的最大支援的字元長度無限制,適合大欄位儲存; 使用場景: 儲存全文搜尋資料, 例如: 郵箱內容、地址、程式碼塊、部落格文章內容等。 預設結合standard analyzer(標準解析器)對文字進行分詞、倒排索引。 預設結合標準分析器進行詞命中、詞頻相關度打分。
keyword
1:不進行分詞,直接索引,支援模糊、支援精確匹配,支援聚合、排序操作。 2:keyword型別的最大支援的長度為——32766個UTF-8型別的字元,可以透過設定ignore_above指定自持字元長度,超過給定長度後的資料將不被索引,無法透過term精確匹配檢索返回結果。 使用場景: 儲存郵箱號碼、url、name、title,手機號碼、主機名、狀態碼、郵政編碼、標籤、年齡、性別等資料。 用於篩選資料(例如: select * from x where status='open')、排序、聚合(統計)。 直接將完整的文字儲存到倒排索引中。
text 型別的資料會把內容 先進行分詞
,然後再 再存入
到es中。
keyword:不分詞,沒有資料內容進行分詞處理,而是存入了整個資料!
案列說明
- 建立 test 索引
PUT /test
- 建立靜態對映,對映兩個欄位
title:keyword
,content:text
PUT /test/_mapping { "properties":{ "title":{ "type": "keyword", "index": true }, "content":{ "type":"text", "index":true, "analyzer":"ik_max_word" } } }
- 建立文件,存入資料
PUT /test/_doc/1 { "title":"分散式,高擴充套件,高實時", "content":"Elasticsearch 是一個分散式,高擴充套件,高實時的搜尋與資料分析引擎" }
- 透過全部內容進行匹配查詢,查詢 content
可以看到查詢資料為空GET /test/_doc/_search { "query":{ "term":{ "content":"Elasticsearch 是一個分散式,高擴充套件,高實時的搜尋與資料分析引擎" } } } # 查詢結果 { "took" : 0, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 0, "relation" : "eq" }, "max_score" : null, "hits" : [ ] } }
使用 title 查詢
可看到對GET /test/_doc/_search { "query":{ "term":{ "title":"分散式,高擴充套件,高實時" } } } # 查詢結果 { "took" : 0, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 0.2876821, "hits" : [ { "_index" : "test", "_type" : "_doc", "_id" : "1", "_score" : 0.2876821, "_source" : { "title" : "分散式,高擴充套件,高實時", "content" : "Elasticsearch 是一個分散式,高擴充套件,高實時的搜尋與資料分析引擎" } } ] } }
content
的text
型別進行全部內容匹配查不到資料,而對title
的keyword
型別進行全部內容匹配成功查到資料。
可透過GET /test/_analyze
檢視這條資料在存入 es 的時候分詞情況GET /test/_analyze { "field": "title", "text":"分散式,高擴充套件,高實時" } #分詞結果 { "tokens" : [ { "token" : "分散式,高擴充套件,高實時", "start_offset" : 0, "end_offset" : 11, "type" : "word", "position" : 0 } ] } ```
儲存資料的時候不會對 title 的內容進行分詞,而是全部內容存入 es
檢視 content 存入情況
GET /test/_analyze
{
"field": "content",
"text":"Elasticsearch 是一個分散式,高擴充套件,高實時的搜尋與資料分析引擎"
}
#分詞結果
{
"tokens" : [
{
"token" : "elasticsearch",
"start_offset" : 0,
"end_offset" : 13,
"type" : "ENGLISH",
"position" : 0
},
{
"token" : "是",
"start_offset" : 14,
"end_offset" : 15,
"type" : "CN_CHAR",
"position" : 1
},
{
"token" : "一個",
"start_offset" : 15,
"end_offset" : 17,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "一",
"start_offset" : 15,
"end_offset" : 16,
"type" : "TYPE_CNUM",
"position" : 3
},
{
"token" : "個",
"start_offset" : 16,
"end_offset" : 17,
"type" : "COUNT",
"position" : 4
},
{
"token" : "分散式",
"start_offset" : 17,
"end_offset" : 20,
"type" : "CN_WORD",
"position" : 5
},
{
"token" : "分佈",
"start_offset" : 17,
"end_offset" : 19,
"type" : "CN_WORD",
"position" : 6
},
{
"token" : "式",
"start_offset" : 19,
"end_offset" : 20,
"type" : "CN_CHAR",
"position" : 7
},
{
"token" : "高",
"start_offset" : 21,
"end_offset" : 22,
"type" : "CN_CHAR",
"position" : 8
},
{
"token" : "擴充套件",
"start_offset" : 22,
"end_offset" : 24,
"type" : "CN_WORD",
"position" : 9
},
{
"token" : "高",
"start_offset" : 25,
"end_offset" : 26,
"type" : "CN_CHAR",
"position" : 10
},
{
"token" : "實時",
"start_offset" : 26,
"end_offset" : 28,
"type" : "CN_WORD",
"position" : 11
},
{
"token" : "的",
"start_offset" : 28,
"end_offset" : 29,
"type" : "CN_CHAR",
"position" : 12
},
{
"token" : "搜尋",
"start_offset" : 29,
"end_offset" : 31,
"type" : "CN_WORD",
"position" : 13
},
{
"token" : "與",
"start_offset" : 31,
"end_offset" : 32,
"type" : "CN_CHAR",
"position" : 14
},
{
"token" : "資料",
"start_offset" : 32,
"end_offset" : 34,
"type" : "CN_WORD",
"position" : 15
},
{
"token" : "據分析",
"start_offset" : 33,
"end_offset" : 36,
"type" : "CN_WORD",
"position" : 16
},
{
"token" : "分析",
"start_offset" : 34,
"end_offset" : 36,
"type" : "CN_WORD",
"position" : 17
},
{
"token" : "引擎",
"start_offset" : 36,
"end_offset" : 38,
"type" : "CN_WORD",
"position" : 18
}
]
}
對 content 的內容會先進行分詞,在儲存,所以使用全內容進行匹配時,在 es 中是找不到的。
本文對 ElasticSearch 的使用是最最最基本的。
感謝: www.cnblogs.com/sanduzxcvbnm/p/121...
blog.csdn.net/abc123lzf/article/de...
本作品採用《CC 協議》,轉載必須註明作者和本文連結