前言:
之前已經說過最近正在做數據建設,爬取數據之後經過處理,最終導入到ElasticSearch中,並編寫公共接口以提供給後臺進行檢索操作;本來想等把ElasticSearch官方API都看過一遍,形成思維導圖之後再整理出來,因爲熟悉一個工具,它能做到的,比你知道它能做到的要全面也重要的多,但是整理了兩章之後發現,內容真的太多了,這還僅僅只2類。。所以想還是先把基礎用法記錄下來,先一步步來了。
ElasticSearch 簡介
Elasticsearch 是一個分佈式可擴展的近實時搜索和分析引擎,一個建立在全文搜索引擎 Apache Lucene(TM) 基礎上的搜索引擎.當然 Elasticsearch 並不僅僅是 Lucene 那麼簡單,它不僅包括了全文搜索功能,還可以進行以下工作:
- 分佈式實時文件存儲,並將每一個字段都編入索引,使其可以被搜索。
- 實時分析的分佈式搜索引擎。
- 可以擴展到上百臺服務器,處理PB級別的結構化或非結構化數據。
ElasticSearch 安裝
安裝比較簡單,建議練手階段安裝Kibana,安裝步驟參見之前寫的博客:ElasticSearch安裝
基本概念:
- ES是一個近實時的搜索引擎,面向文檔型數據庫,一條數據就對應一個文檔,以JSON格式存儲;
- 所有的操作都是通過rest接口實現,即每一個操作都是向ES發送要給rest請求
- 支持分佈式部署,node節點跟slave集羣;
- shards分片:個人感覺類似於關係型數據庫的分區分表操作
- replicas副本:類似於傳統數據庫的從表了,ES裏是針對每個shards而言的副本 例如:創建index默認爲shards爲5,replicas爲1,則意味着總共有10個shards,5個主5個從;
- 與傳統關係型數據庫術語對照表如下:
關係數據庫 ⇒ 數據庫 ⇒ 表 ⇒ 行 ⇒ 列(Columns) Elasticsearch ⇒ 索引(Index) ⇒ 文檔(Docments) ⇒ 字段(Fields)
- 6.x之後ES建議刪除type,因爲按照目前理解的type=table,但實際上卻並不太一樣,ES裏同一個index下的多個type字段類型必須一致;但是傳統數據庫中,一個db裏的多個table是可以不一樣的; 具體可看官網:刪除type及替代方案 目前6.x語法上也還是支持type,7.x語法就不支持了,所以要習慣理解修改後的模式:
Elasticsearch ⇒ 索引(Index) ⇒ 文檔(Docments) ⇒ 字段(Fields)
創建Index(索引)
既然刪除了type,感覺將Index理解爲table是不是更加合理些。。
創建Index語法如下:
PUT /userinfo?pretty
{
"mappings": {
"_doc": {
"properties": {
"name": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word", "fields": {"raw":{"type":"keyword"}}},
"content": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word" },
"org_type": { "type": "keyword"},
"create_time":{"type":"date", "format": "epoch_second"}
}
}
}
}
如果理解了上面的基本概念的話,這命令看起來應該不難理解,有幾點需要提一下:
- analyzer、search_analyzer:爲該字段配置的分詞器,
- 中文一般使用ik分詞器 包括ik_max_word和ik_smart,ik_max_word:會將文本做最細粒度的拆分;儘可能多的拆分出詞語 ,ik_smart:會做最粗粒度的拆分;已被分出的詞語將不會再次被其它詞語佔有
- type爲text的不支持排序,統計等操作,如有排序或統計需求,則需在後面加上**"fields": {"raw":{"type":"keyword"}}**以支持該功能,text 類型的字段,如不指定分詞器,ES會默認設置分詞器
- type爲date可以指定轉換格式,epoch_second轉換爲當前時間的秒數 這只是簡單常用的創建Index的命令,完整的請點擊Mapping API
- ES會根據值自動創建映射,例如,給usetinfo新增一個age字段,可以直接添加即可:
通過GET /userinfo/_mapping命令查看userinfo最新的字段,可以看到ES默認新增了一個類型爲long的age字 段。但是一般建議關鍵字段在創建Index的時候進行指定字段;PUT /userinfo/_doc/1? { "name":"lctest", "age":29 }
{ "userinfo": { "mappings": { "_doc": { "properties": { "age": { "type": "long" }, "content": { "type": "text", "analyzer": "ik_max_word" }, "create_time": { "type": "date", "format": "epoch_second" }, "name": { "type": "text", "fields": { "raw": { "type": "keyword" } }, "analyzer": "ik_max_word" }, "org_type": { "type": "keyword" } } } } } }
修改Index
- ES不支持對索引中已有的字段進行修改,只能添加字段,添加字段有兩種方法,
- 上面提到的,直接賦值,由ES去創建字段;
- 手動設置字段,代碼如下:
PUT /userinfo/_mapping/_doc { "properties": { "params": { "type": "nested", "properties": { "update_time":{"type":"date", "format": "epoch_second"} } } } }
刪除Index
//刪除指定索引
DELETE /userinfo
//刪除多個索引
DELETE /index1,index2 或者 DELETE /index*
//刪除所有索引
DELETE /_all 或者 DELETE /*
最基本的索引操作就到此結束,基本上能滿足簡單的基本需求,下面有一些擴展知識點,可以選擇性的使用
aliases別名
索引別名就像一個快捷方式或軟連接,或者是一個指向,都是最終指的同一個東西,別名 帶給我們極大的靈活性,允許我們做下面這些:
- 在運行的集羣中可以無縫的從一個索引切換到另一個索引
- 給多個索引分組 (例如, last_three_months)
- 給索引的一個子集創建 視圖
有兩種方式管理別名: _alias用於單個操作, _aliases用於執行多個原子級操作。
- 創建別名
POST /_aliases { "actions" : [ { "add" : { "index" : "test1", "alias" : "alias1" } } ] }
- 刪除別名
POST /_aliases { "actions" : [ { "remove" : { "index" : "test1", "alias" : "alias1" } } ] }
- 切換索引
POST /_aliases { "actions" : [ { "remove" : { "index" : "test1", "alias" : "alias1" } }, { "add" : { "index" : "test2", "alias" : "alias1" } } ] }
- 操作單個索引
PUT /{index}/_alias/{name} PUT /logs_201305/_alias/2013
以上便是Index別名的基本常用語法,完整API詳見Aliases API
常用命令
-
查看所有索引信息 GET /_cat/indices?v&pretty
-
查看某個索引信息 GET /{index}
-
刪除索引單個索引 DELETE /{index}
-
刪除所有索引 DELETE /_all 或者 DELETE /*
-
刪除多個索引: DELETE /index1,index2 或者 DELETE /index*
-
查看索引的映射 GET /{index}/_mapping
-
查看某個索引的某個類型的映射 GET /{index}/_mapping/{type}
-
映射添加新字段 PUT /{index}/_mapping/{type}
禁用通配符
爲了防止誤操作 ,造成刪庫跑路的情況,建議在elasticsearch.yml 做如下配置:action.destructive_requires_name: true 這個設置使刪除只限於特定名稱指向的數據, 而不允許通過指定 _all 或通配符來刪除指定索引庫。你同樣可以通過 Cluster State API 動態的更新這個設置。
新手推薦使用Kibana工具,帶命令提示,很適合不熟悉命令的初學者,我也一直在用,只是博客的話,命令的表現形式感覺更好一些