ES (Elasticsearch)入門指南
簡介
ES=elaticsearch簡寫, Elasticsearch是一個開源的高擴充套件的分散式全文檢索引擎,它可以近乎實時的儲存、檢索資料;本身擴充套件性很好,可以擴充套件到上百臺伺服器,處理PB級別的資料。 本質上是一個分散式nosql資料庫,允許多臺伺服器協同工作,每臺伺服器可以執行多個 Elastic 例項。單個 Elastic 例項稱為一個節點(node)。一組節點構成一個叢集(cluster)。
概念介紹
關係資料庫(mysql) ⇒ 資料庫 ⇒ 表 ⇒ 行 ⇒ 列(Columns)
Elasticsearch ⇒ 索引 ⇒ 型別 ⇒ 文件 ⇒ 欄位(Fields)
index: es裡的index相當於一個數據庫,每個 Index (即資料庫)的名字必須是小寫。
type: 相當於資料庫裡的一個表。
id: 唯一,相當於主鍵,PUT資料的時候需要指定id。
node:節點是es例項,一臺機器可以執行多個例項,但是同一臺機器上的例項在配置檔案中要確保http和tcp埠不同。
cluster:代表一個叢集,叢集中有多個節點,其中有一個會被選為主節點,這個主節點是可以通過選舉產生的,主從節點是對於叢集內部來說的。
shards:代表索引分片,es可以把一個完整的索引分成多個分片,這樣的好處是可以把一個大的索引拆分成多個,分佈到不同的節點上,構成分散式搜尋。分片的數量只能在索引建立前指定,並且索引建立後不能更改。
replicas:代表索引副本,es可以設定多個索引的副本,副本的作用一是提高系統的容錯性,當個某個節點某個分片損壞或丟失時可以從副本中恢復。二是提高es的查詢效率,es會自動對搜尋請求進行負載均衡。
mapping : 在 Elasticsearch 中的作用就是約束,類似於mysql中的表的約束。
埠
ElasticSearch 客戶端程式除了Java 使用TCP的方式連線ES叢集以外,其他的語言基本上都是使用的Http的方式。眾所周知,ES 客戶端預設的TCP埠為9300,而HTTP預設埠為9200。elasticsearch-hadoop 使用的就是HTTP的方式連線的ES叢集。
域資料型別:
mapping
Mapping)相當於資料表的表結構。ElasticSearch中的對映(Mapping)用來定義一個文件,可以定義所包含的欄位以及欄位的型別、分詞器及屬性等等,對映可以分為動態對映和靜態對映。
(1)動態對映
我們知道,在關係資料庫中,需要事先建立資料庫,然後在該資料庫例項下建立資料表,然後才能在該資料表中插入資料。而ElasticSearch中不需要事先定義對映(Mapping),文件寫入ElasticSearch時,會根據文件欄位自動識別型別,這種機制稱之為動態對映。
(2)靜態對映
當然,在ElasticSearch中也可以事先定義好對映,包含文件的各個欄位及其型別等,這種方式稱之為靜態對映。
ES 6.3 mapping 引數說明
"type" : "text", #是資料型別一般文字使用text(可分詞進行模糊查詢);keyword無法被分詞(不需要執行分詞器),用於精確查詢
"format" : "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" ,#格式化 此引數代表可接受的時間格式 3種都接受
"analyzer" : "ik_max_word", #指定分詞器,一般使用最大分詞:ik_max_word
"index" : true, #該欄位是否會被索引和可查詢 預設true 不分詞是:not_analyzed ,設定成 no,欄位將不會被索引
"store" : true, #預設情況false,其實並不是真沒有儲存,_source欄位裡會儲存一份原始文件。
# 在某些情況下,store引數有意義,比如一個文件裡面有title、date和超大的content欄位,如果只想獲取title和date
"boost" : 1.5, #欄位權重;用於查詢時評分,關鍵欄位的權重就會高一些,預設都是1;另外查詢時可臨時指定權重
"normalizer" : "normalizer_name", #欄位標準化規則;如把所有字元轉為小寫;具體如下舉例
"coerce" : true, #清理髒資料:1,字串會被強制轉換為整數 2,浮點數被強制轉換為整數;預設為true
更新mapping
es中建立後的mapping不可修改,但是可以新增新欄位
新增新欄位:
PUT /my_index/_mapping/my_type
{
"properties": {
"new_field_name": {
"type": "string"
}
}
}
賦值:
POST my_index/_update_by_query
{
"script": {
"lang": "painless",
"inline": "ctx._source.new_field_name= '02'"
}
}
pretty
在任意的查詢字串中增加pretty引數,會讓Elasticsearch美化輸出(pretty-print)JSON響應以便更加容易閱讀。
_source欄位不會被美化,它的樣子與我們輸入的一致。
ES資料結構
index定義欄位的分析型別以及檢索方式
- 如果是no,則無法通過檢索查詢到該欄位;
- 如果設定為not_analyzed則會將整個欄位儲存為關鍵詞,常用於漢字短語、郵箱等複雜的字串;
- 如果設定為analyzed則將會通過預設的standard分析器進行分析
store定義了欄位是否儲存
在ES中原始的文字會儲存在_source裡面(除非你關閉了它)。預設情況下其他提取出來的欄位都不是獨立儲存的,是從_source裡面提取出來的。當然你也可以獨立的儲存某個欄位,只要設定store:true即可。獨立儲存某個欄位,在頻繁使用某個特殊欄位時很常用。而且獲取獨立儲存的欄位要比從_source中解析快得多,而且額外你還需要從_source中解析出來這個欄位,尤其是_source特別大的時候。不過需要注意的是,獨立儲存的欄位越多,那麼索引就越大;索引越大,索引和檢索的過程就會越慢....
string
字串型別,es中最常用的類型別: 注意:5.X以上版本沒有string型別了,換成了text
把string欄位設定為了過時欄位,引入text,keyword欄位,這兩個欄位都可以儲存字串使用,但建立索引和搜尋的時候是不太一樣的
keyword:儲存資料時候,不會分詞建立索引
text:儲存資料時候自動分詞並生成索引(這是智慧的,但在有些欄位裡面是沒用的,所以對於有些欄位使用text則浪費了空間)
store儲存
true 獨立儲存 false(預設)不儲存,從_source中解析
Numeric
數值型別,注意numeric並不是一個型別,它包括多種型別,比如:long,integer,short,byte,double,float,每種的儲存空間都是不一樣的,一般預設推薦integer和float。官方文件參考
重要的引數:
index分析 not_analyzed(預設) ,設定為該值可以保證該欄位能通過檢索查詢到
store儲存 true 獨立儲存 false(預設)不儲存,從_source中解析
date
日期型別,該型別可以接受一些常見的日期表達方式,官方文件參考。
重要的引數:
index分析 not_analyzed(預設) ,設定為該值可以保證該欄位能通過檢索查詢到
store儲存 true 獨立儲存 false(預設)不儲存,從_source中解析
format格式化
strict_date_optional_time||epoch_millis(預設)
你也可以自定義格式化內容,比如
"date": {
"type": "date",
"format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
boolean
布林型別,所有的型別都可以標識布林型別,參考官方文件
False: 表示該值的有:false, "false", "off", "no", "0", "" (empty string), 0, 0.0
True: 所有非False的都是true
重要的引數:
index分析 not_analyzed(預設) ,設定為該值可以保證該欄位能通過檢索查詢到
store儲存 true 獨立儲存 false(預設)不儲存,從_source中解析
指令總結
我講從索引(資料庫)→型別(表)→文件(行)→屬性(欄位)一一介紹相關的指令
請求型別
Http請求內容:
PUT /customer?pretty
GET /_cat/indices?v
Curl命令
curl -XPUT ‘localhost:9200/customer?pretty&pretty’
curl -XGET ‘localhost:9200/_cat/indices?v&pretty’
POST和PUT的區別
POST不用加具體的id,它是作用在一個集合資源之上的(/uri),而PUT操作是作用在一個具體資源之上的(/uri/xxx)。
在ES中,如果不確定document的ID(documents具體含義見下),那麼直接使用POST對應uri( “POST /website/blog” ),ES可以自己生成不會發生碰撞的UUID當做ID;如果確定document的ID,即自己設定的ID,使用PUT即可,比如 “PUT /website/blog/123”,那麼執行建立或修改(修改時_version版本號提高1)
1.每個 Index 所包含的 Type
curl -H "Content-Type: application/json" 'localhost:9200/_mapping?pretty=true'
2.建立一個索引
curl -XPUT 'localhost:9200/sqlcommand?pretty'
或 5.5 以後儘量使用下面的方式
curl -XPUT -H 'Content-Type: application/json' 'localhost:9200/megacorp?pretty'(5.5以後版本)
返回資訊 代表建立成功
{
"acknowledged" : true,
"shards_acknowledged" : true
}
3.顯示所有索引
curl -XGET -H 'Content-Type: application/json' 'localhost:9200/_cat/indices?v'
4.刪除索引
curl -XDELETE 'localhost:9200/sqlcommand?pretty'
5.在對應的索引中建立文件和type已經定義mapping
curl -H "Content-Type: application/json" -PUT "http://127.0.0.1:9200/sqltest/infotest/_mapping?pretty" -d '
{
"infotest": {
"properties": {
"application_id": {
"type": "keyword"
},
"session_id": {
"type": "keyword"
},
"user_ip_address": {
"type": "keyword"
},
"logger_type": {
"type": "keyword"
},
"mryxblg_command_monitoring": {
"type": "keyword"
}
}
}
}'
匯入資料
curl -H "Content-Type: application/json" -XPOST 'http://127.0.0.1:9200/productx/product/1' -d '
{
"title": "物品",
"description": "電腦",
"price": 89.0
"onSale": true
"type": 2
"createDate": 2018
}'
注意:PUT一定要大寫 -d之前,必需要空格
檢視索引的type
curl -X GET 'localhost:9200/sql_command/_mapping'
6.檢索文件
普通檢索
curl -XGET -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/1'
輕量檢索
curl -XGET -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/_search'
檢索部分內容
curl -XGET -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/1?_source=first_name,last_name'
只得到源的內容
curl -XGET -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/1?_source'
按條件搜尋
curl -XGET -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/_search?q=last_name:Smith'
Q =表示匹配全部文件 * 排序=年齡表示按照年齡資訊排序 ASC表示升序
可以不加引數,查詢全部文件
curl -XGET 'localhost:9200/megacorp/_search?pretty'
{
"took" : 5,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : null,
"hits" : [
{
"_index" : "customer",
"_type" : "external",
"_id" : "1",
"_score" : null,
"_source" : {
"name" : "Zhao1"
},
"sort" : [
9223372036854775807
]
}
]
}
}
使用檢索表示式
curl -XGET -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/_search?pretty' -d '
{
"query" : {
"match" : {
"last_name" : "Smith"
}
}
}'
複雜檢索
curl -XGET -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/_search?pretty' -d '
{
"query" : {
"bool": {
"must": {
"match" : {
"last_name" : "smith"
}
},
"filter": {
"range" : {
"age" : { "gt" : 30 }
}
}
}
}
}'
批量檢索(multi-get或者mget API)
mget API要求有一個docs陣列作為引數,每個元素包含需要檢索文件的元資料,包括_index,_type和_id。如果你想檢索一個或者多個特定的欄位,那麼你可以通過_source引數來指定這些欄位的名字:
curl -XGET -H 'Content-Type: application/json' 'http://localhost:9200/_mget?pretty' -d '
{
"docs" : [
{
"_index" : "megacorp",
"_type" : "employee",
"_id" : 2
},
{
"_index" : "megacorp",
"_type" : "employee",
"_id" : 1
}
]
}'
如果想檢索的資料都在相同的_index中(甚至相同的_type中),則可以在URL中指定預設的/ _index或者預設的
文件是否存在
curl -i -XHEAD -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/4'
刪除文件
curl -XDELETE -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/4'
成功返回200,找不到是404,版本會加1(即使是虛假),_版本值仍然會增加。這是Elasticsearch內部記錄本的一部分,用來確保這些改變在跨多節點時以正確的順序執行)
刪除全部文件
curl -XPOST -H 'Content-Type: application/json' 'http://localhost:9200/megacorp/employee/_delete_by_query?conflicts=proceed' -d '
{
"query": {
"match_all": {}
}
}'