ElasticSearch核心基礎之索引管理
一 索引管理
1.1 建立索引
# 建立索引的時候,我們可以設定主分片和備份分片的數量通過setting欄位number_of_shards和number_of_replicas欄位設定
# 對於ES的文件而言,一個文件會包含一個或者多個欄位,任何欄位都要有自己的資料型別,例如string、integer、date等。ElasticSearch中是通過對映來進行欄位和資料型別對應的。在預設的情況下ElasticSearch會自動識別字段的資料型別。同時ElasticSearch提供了mappings引數可以顯示的進行對映
PUT /web //索引名字
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"site": { // 型別
"properties": {
"title": {"type" : "text"},
"content":{"type":"string","index":"not_analyzed"}
}
}
}
}
1.2 刪除索引
DELETE /index
DELETE /index1,index2
DELETE /index*
DELETE /_all
1.3 修改索引
PUT /web/_settings
{
"number_of_replicas": 1
}
1.4 獲取索引
GET 127.0.0.1:9200/web
1.5 開啟、關閉索引
開啟、關閉索引介面允許關閉一個開啟的索引或者開啟一個關閉的索引。關閉的索引只能顯示索引元資料資訊,不能進行讀寫操作
POST 127.0.0.1:9200/web/_open
二 索引對映管理
有時候我們在欄位對映的時候,需要進行一些更加高階的設定,比如索引分詞,是否儲存等
2.1 增加對映
向索引web新增型別logs,欄位message型別為string
PUT /web
{
"mappings": {
"logs":{
"properties": {
"messages":{"type": "string"}
}
}
}
}
或者
PUT /web/_mapping/logs
{
"properties": {
"messages":{"type": "string"}
}
}
2.2 更新欄位對映
一般情況下,一旦欄位對映建立,我們不會更新,但有時候可能會,比如新的屬性被新增到物件資料型別欄位,增加了ignore_above引數
2.3 不同型別之間的衝突
在同一個索引中, 不同型別可能存在相同的名字的欄位,所以相同名字的欄位中必須有相同的對映。如果檢視在這種情況下更新引數,系統將會丟擲異常。除非在更新的時候指定update_all_types引數。
比如資料:
PUT 127.0.0.1:9200/web
{
"mappings": {
"type1":{
"properties": {
"messages":{"type":"string","analyzer": "standard"}
}
},
"type2":{
"properties": {
"messages":{"type":"string","analyzer": "standard"}
}
}
}
}
現在修改為:
PUT 127.0.0.1:9200/web/_mapping/type1
{
"properties": {
"messages":{
"type": "string",
"analyzer": "standard",
"search_analyzer": "whitespace"
}
}
}
此時就會報錯。然後增加update_all_types,此時就會同時更新type1和type2兩個型別。
PUT127.0.0.1:9200/web/_mapping/type1?update_all_types
{
"properties": {
"messages":{
"type": "string",
"analyzer": "standard",
"search_analyzer":"whitespace"
}
}
}
2.4 獲取對映
獲取文件對映介面允許通過索引或者索引和型別來搜尋:
GET 127.0.0.1:9200/web/_mapping/type1
系統支出同時獲取多個索引或者型別,多個索引或者型別以逗號分割
如下:
GET 127.0.0.1:9200/{web,logs}/_mapping/type1
GET 127.0.0.1:9200/web/_mapping/{type1,type2}
也可以使用_all來表示全部索引或者直接省略_all也可以
GET 127.0.0.1:9200/_all/_mapping/type1,type2
GET 127.0.0.1:9200/_mapping/type1,type2
2.5 判斷文件索引或者型別是否存在
三 索引別名
我們可以為索引建立別名,類似於資料庫中的檢視
3.1 建立或者刪除別名
POST http://127.0.0.1:9200/_aliases
{
"actions": [
{"add": {"index": "web","alias":"site"}},
{"add": {"index":"article","alias": "book"}}
]
}
POST http://127.0.0.1:9200/_aliases
{
"actions": [
{
"remove": {
"index": "web",
"alias": "site"
}
}
]
}
3.2 過濾索引別名
POST http://127.0.0.1:9200/_aliases
{
"actions": [
{
"add": {
"index": "web",
"alias": "site",
"filter": {
"term": {
"user": "nicky"
}
}
}
}
]
}
3.3 別名與路由
通過別名也可以和路由關聯,可以避免不必要的碎片操作:
POST http://127.0.0.1:9200/_aliases
{
"actions": [
{
"add": {
"index": "web","alias":"site","routing": "1"
}
}
]
}
同時我可以指定索引路由和搜尋路由,但是索引路由只能指定一個,搜尋路由可以指定多個:
POST http://127.0.0.1:9200/_aliases
{
"actions": [
{
"add": {
"index": "web","alias":"site","search_routing":"2,3","index_routing":"1"
}
}
]
}
我們還可以直接通過請求引數新增別名:
語法:PUT/{index}/_alias/{name}
PUT http://127.0.0.1:9200/web/_alias/site
{
"routing": "1",
"filter": {
"term": {
"name": "tmall"
}
}
}
3.4 建索引的時候同時指定別名
PUT http://127.0.0.1:9200/web
{
"mappings": {
"type":{
"properties": {"year":{"type":"integer"}}
}
},
"aliases": {
"current_day": {},
"2014":{
"filter": {"term":{"year":2014}}
}
}
}
3.5 刪除別名
3.6 查詢現有的別名
四 索引配置
在ElasticSearch中索引有很多的配置引數,有些配置是可以在建好索引重新設定的,比如索引的副本數量、索引分詞等
4.1 更新索引配置
# 先關閉索引
# 新增分詞器:
PUT http://127.0.0.1:9200/web/_settings
{
"analysis": {
"analyzer": {
"content":{"type":"custom","tokenizer":"whitespace"}
}
}
# 在開啟索引
4.2 獲取配置
索引中包含很多配置引數,可以通過下面命令獲取索引的引數配置
name=index.number.*: 表示設定將只返回number_of_replicas,number_of_shards兩個引數
4.3 索引分析
索引分析(analysis)是這樣一個過程:首先,把一個文字塊分析稱一個個單獨的詞term,為了後面的倒排索引做準備。然後標準化這些詞為標準形式,提高他們的可搜尋性,這些工作是由分析器analyzers來完成的,分析器analyzers是一個組合,用於將三個功能放到一起:
# 字符集過濾:字串經過字元過濾器(character filter)處理,他們的工作是在標記化之前處理的字串
# 分詞器:分詞器tokenizer被標記化為獨立的詞。一個簡單的分詞器可以根據空格或者逗號將單詞分開
# 標記過濾器:每一個詞通過所有標記過濾器token filters處理,他可以修改詞(比如Quick轉化為小寫,去掉詞比如a,an,the等或者增加同義詞之類的)
ElasticSearch提供了很多內建的字元過濾器,分詞器和標記過濾器。這些可以在組合起來建立自定義的分析器以應對不同的需求
自定義分析器:
請求POSTlocalhost:9200/_anylyze
POST /_analyze
{
"tokenizer": "keyword",
"char_filter": ["html_strip"],
"explain": true,
"text": "this is a <p>test</P>"
}
表示適用keyword分詞器,字元過濾器是html_strip,explain表示獲取分析器更多的細節
五 索引監控
索引監控主要就是涉及到索引的統計資訊,碎片資訊,恢復的狀態和分片的資訊,利用這些介面隨時監控索引的狀態
5.1 索引統計
索引統計介面提供索引中不同內容的統計資料,比如:
GET localhost:9200/_stats
GET localhost:9200/{index1,index2}/_stats
預設返回所有的統計資料,也可以在URL中指定需要返回的特定統計資料
# 獲取所有索引的混合和重新整理統計資料
# 獲取名為web索引中型別為type1和type2的文件統計資料
另外返回的統計資料在索引級別發生聚合,生成名為primaries和total的聚合。其中primaries僅包含主分片的值,total是主分片和從分片的累計值。
為了獲取分片級別的統計資料,需要設定level引數為shards
5.2 索引分片
提供Lucene索引所在的分片資訊。可以用來提供分片和索引的更多統計資訊,可能是優化資訊,刪除垃圾資料等
5.3 索引恢復
索引恢復介面提供正在進行恢復的索引分片資訊。可以報告指定索引或者叢集範圍的恢復狀態
去掉索引名可以檢視叢集範圍的恢復狀態:
六 狀態管理
ElasticSearch中還有一些和索引相關的重要介面需要介紹,這些介面包括清除索引快取、索引重新整理、沖洗索引、合併索引介面
6.1 清除快取
預設清理所有快取,你也可以指定query,fielddata,request來清理特定快取
6.2 索引重新整理refresh
重新整理介面可以明確的重新整理一個或多個索引,使之前最後一次重新整理之後的所有操作被執行
POST http://127.0.0.1:9200/web,book/_refresh
6.3 flush
可以沖洗一個或者多個索引,將資料儲存到索引儲存並且清除內部事務日誌,以此來釋放索引的記憶體空間
6.4 合併索引
合併介面可以強制合併一個或者多個索引。合併分片數量和每一個分片儲存的Lucene索引,強制合併可以通過合併減少分片數量。
呼叫會被阻塞一直到合併完成。如果http連線丟失,請求 後臺繼續執行,任何新的請求都會被阻塞直到一個強制合併完成
POST http://127.0.0.1:9200/web,book/_forcemerge
七 文件管理
7.1 增加文件
就是把一條文件增加到索引中,使他可以被搜尋,文件的格式是JSON格式。注意,在ElasticSearch中如果有相同ID的文件存在,則更新此文件
語法:PUT /{index}/{type}/{docId}
返回的資訊:
total: 文件被建立的時候,在多少個分片中進行了操作,包括主分片和副本分片
successful: 成功建立索引分片的數量,當建立成功後,成功建立索引分片的數量最少是1
failed: 失敗建索引分片的數量
# 自動建立索引
當建立文件的時候,如果索引不存在,則會自動建立索引。自動建立的索引會自動對映每一個欄位的型別。自動建立欄位型別是非常靈活的,新的欄位型別將會自動匹配欄位物件的型別。
我們也可以通過配置檔案action.auto_create_index為fasle在所有節點禁止配置檔案中禁止自動建立索引;通過設定index.mapper.dynamic為false禁止自動對映型別
# 版本號
每一個文件都有一個版本號,版本號的具體值放在建立索引返回值_version中的,通過版本號引數可以達到併發控制的效果,比如更新文件:
PUT /ecommerce/product/4?_version=1&pretty
{
"desc":"YamahaF335",
"price":129.19
}
# 操作型別
系統同時支援op_type=create引數強制命令執行建立操作,只有系統中不存在此文件的時候才會建立成功,如果不指定此操作型別,如果存在此文件,則會更新此文件
POST /ecommerce/product/4?op_type=create&pretty
{
"name":"Yamaha",
"desc":"YamahaF335 Acoustic Guitar",
"price":159.99,
"type":"Acoustic",
"reviews":250,
"tags":["Guitar","Acoustic","OnSale"]
}
# 自動建立ID
當建立文件的時候,如果不指定ID,系統會自動建立ID.自動生成的ID是一個不會重複的隨機數。但是在5.x系列必須指定id,否則報錯例如:
POST /ecommerce/product?op_type=create&pretty
{
"name":"RoundGlasses",
"desc":"RoundGlasses #120100",
"price":59.09,
"type":"Round",
"reviews":100,
"tags":["Round","Glasses"]
}
# 分片選擇
我們在建立文件的時候,可以指定該文件散落在哪一個分片上,這個值只可以通過router來控制
POST/ecommerce/product?routing=ecommerce&pretty
{
"name":"RoundGlasses",
"desc":"RoundGlasses #120100",
"price":59.09,
"type":"Round",
"reviews":100,
"tags":["Round","Glasses"]
}
比如上面就是通過routing=ecommerce的雜湊值來決定落在哪一個分片上
7.2 更新刪除文件
# 第一種更新方式
判斷文件id是否存在,如果存在則更新,不存在則新增
POST /ecommerce/product/1/
{
"price":45.78
}
# 第二種更新方式,開啟動態指令碼功能,新版本 預設禁用
如果要使用,需要在elasticsearch.yml中新增如下配置:
script.inline:on
script.indexed:on
script.file:on
POST /ecommerce/product/4/_update?pretty
{
"script": {
"inline": "ctx._source.price += p",
"params": {"p":12}
}
}
7.3 查詢文件
查詢操縱都是實時查詢,如果不希望實時查詢,則可以全域性設定action.get.realtime為false
# 我們還可以禁止返回原始資料即_source
# 如果你只想獲取source一部分內容,可以使用_source_include或者_source_exclude引數
GET /ecommerce/product/4?_source_exclude=desc,type
GET/ecommerce/product/4?_source_include=name,price,reviews
# 還可以通過fields欄位過濾(以前版本)
GET /ecommerce/product/4?fields=name,price,reviews
# 只獲取文件內容,不獲取額外的資訊
GET /ecommerce/product/4/_source
# 查詢的時候指定分片
GET /ecommerce/product/4?routing=ecommerce&pretty
# 查詢引數
_primary: 在主節點查詢
_local: 儘可能在本地節點查詢
refresh: 在搜尋之前重新整理相關的分片可以保證及時查詢到,但是這個引數會消耗系統資源,除非有必要,否則不需要設定
GET /ecommerce/product/4? _primary=true&refresh=true
7.4 索引詞頻率
Term Vector(檢索詞向量):是Lucene的概念,就是相當於文件的每一列,如title,body這種文字型別的建立詞頻的多維向量空間,每一個詞就是一個維度,這個維度的值就是這個詞在這個列中的頻率。
在ElasticSearch中,_termvectors返回索引中特定文件欄位的統計資訊,termvectors在ElasticSearch中是實時分析的,如果不想要實時分析,可以設定realtime引數。預設情況索引詞頻統計是關閉的,需要在建索引的時候手工開啟。
# 設定索引
PUT http://hadoop-all-01:9200/secisland
{
"mappings": {
"secilog":{
"properties": {
"type":{
"type": "string", // 在5.x版本是text
"term_vector": "with_positions_offsets",
"store": true,
"analyzer":"fulltext_analyzer"
},
"message":{
"type": "string", // 在5.x版本是text
"term_vector":"with_positions_offsets",
"analyzer":"fulltext_analyzer"
}
}
}
},
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0,
"analysis": {
"analyzer": {
"fulltext_analyzer":{
"type":"custom",
"tokenizer":"whitespace",
"filter":["lowercase"]
}
}
}
}
}
# 新增文件
PUT http://hadoop-all-01:9200/secisland/secilog/1
{
"type":"syslog",
"message":"secilog test test test"
}
PUT http://hadoop-all-01:9200/secisland/secilog/2
{
"type":"file",
"message":"Another secilog test"
}
{
"_index": "secisland",
"_type": "secilog",
"_id": "1",
"_version": 1,
"found": true,
"took": 32,
"term_vectors": {
"message": {
"field_statistics": {
"sum_doc_freq": 5,
"doc_count": 2,
"sum_ttf": 7
},
"terms": {
"secilog": {
"term_freq": 1,
"tokens": [
{
"position": 0,
"start_offset": 0,
"end_offset": 7
}
]
},
"test": {
"term_freq": 3,
"tokens": [
{
"position": 1,
"start_offset": 8,
"end_offset": 12
},
{
"position": 2,
"start_offset": 13,
"end_offset": 17
},
{
"position": 3,
"start_offset": 18,
"end_offset": 22
}
]
}
}
},
"type": {
"field_statistics": {
"sum_doc_freq": 2,
"doc_count": 2,
"sum_ttf": 2
},
"terms": {
"syslog": {
"term_freq": 1,
"tokens": [
{
"position": 0,
"start_offset": 0,
"end_offset": 6
}
]
}
}
}
}
}
我們只關注term_vectors欄位資訊:
# message 和 type使我們要統計的欄位
# field_statistics:整個索引下型別的所有文件統計
sum_doc_freq:該欄位中詞的數量(去掉重複的數目)
sum_ttf文件中詞的數量(包含重複的數目)
doc_count涉及的文件數等等
# terms:詞統計
term_freq:該次出現頻率
tokens:
position: 位置,處於文字第幾個單詞
start_offset:詞的開始偏移量
end_offset:詞的結束偏移量