ElasticSearch的REST APIs 之 索引設置管理

基於 ES 7.7, 官方文檔

主要內容:

  • Update index settings: 修改索引的設置
  • Get index settings: 獲取索引的設置
  • Analyze: 分析(分析器, 分詞器)

1. 修改索引的設置

通過api可以實時修改索引的設置。 原官方英文文檔

PUT /<index>/_settings
{
}

路徑參數

  • <index>

(可選, String) 支持多個索引名稱的英文逗號分割,以及通配符的表達式。

如果要修改所有的索引的設置,可以使用_all或者直接忽略該參數。

# 修改單個索引
PUT /index1,index2/_settings

# 同時修改多個索引
PUT /index1,index2/_settings
PUT /user*/_setting

# 同修修改索引的設置
PUT /_all/_settings
PUT /_settings

查詢參數

allow_no_indices

(可選, bool) 如果設置爲true,則當全部使用通配符*_all只檢索不存在(missing)或者已關閉(closed)的索引時,會拋出錯誤。

此參數也適用於指向不存在(missing)或者已關閉(closed)的索引的別名。

默認false

expand_wildcards

(可選, String) 通配符查詢時的範圍限制。支持多個條件的逗號分割。

  • all: 匹配open和closed的索引, 包括隱藏的
  • open: 表示只查詢開放中的索引
  • closed: 只匹配closed的
  • hidden: 隱藏的(hidden)索引,必須和open/closed聯合使用
  • none: 不接受通配符

默認 open

flat_settings

(可選, bool) 是否以平面格式返回settings信息。默認false

ignore_unavailable

(可選, bool) 如果爲true, missing或closed的索引不會包括在返回數據中。默認false

preserve_existing

(可選, bool) 如果爲true, 則指定的索引已存在的設置保持不變。默認false

master_timeout

(可選,時間單位)連接到主節點的等待超時時間。如果在超時時間已過之前沒有響應, 則返回錯誤。 默認是值 30s。

timeout

(可選,時間單位) 等待超時時間。如果在超時時間已過之前沒有響應, 則返回錯誤。 默認是值 30s。

Request body

settings

(可選) 索引配置的選項。參考索引設置(Index Settings)

幾個栗子

1. 重置一個設置 (Reset an index setting)

如果要把索引的某一項設置還原爲默認值, 只要把這個選項設置爲 null 即可。

PUT /twitter/_settings
{
    "index" : {
        "refresh_interval" : null
    }
}

可以在索引模塊(Index modules) 中找到可以動態修改的設置的列表, 這些設置都可以在活動的索引(live index)上動態更新。要保持現有設置不被更新,可以在請求參數中把preserve_existing設置爲true。

2. 批量索引的使用(Bulk indexing usage)

這個應該是我們在需要批量更新文檔時, 先禁用該索引的索引更新工作, 文檔更新後再恢復索引更新。因爲ES默認會在文檔更新後, 在索引週期內(1s)即開始執行索引更新。類似在mysql中我們批量插入數據前, 把索引禁用掉,以提高數據更新和索引更新的性能。 For example, the update settings API can be used to dynamically change the index from being more performant for bulk indexing, and then move it to more real time indexing state. Before the bulk indexing is started, use:

例如, 更新設置api可以動態修改索引的設置以使批量索引更高效, 然後再改回更實時的索引狀態。在批量索引開始前, 我們使用:

PUT /twitter/_settings
{
  "index":{
    "refresh_interval": "-1"
  }
}

(另一個優化方式是在沒有任何副本的情況下啓動索引,然後再添加副本,但是要根據實際情況決定是否適用。)

Then, once bulk indexing is done, the settings can be updated (back to the defaults for example):

當批量索引執行完畢, 再執行如下代碼還原設置:

# 官方文檔中設置的是 "1s", 其實ES默認就是1s
PUT /twitter/_settings
{
  "index":{
    "refresh_interval": null
  }
}

再執行強制合併(force merge):

# 強制合併分段, 把一個分片的Lucene分段設置爲5
POST /twitter/_forcemerge?max_num_segments=5

WHY? 爲什麼要合併? 官方文檔未做說明! TODO 有理解的說一下

3. 更新索引分析(Update index analysis)

索引的分析器(analyzer)是靜態設置,不能動態修改,只能在關閉的(closed)索引上定義新的分析器。

要給索引添加一個分析器, 你必須先關閉索引,然後定義分析器,再重新打開索引。

ES 7.15版本新增了提示: 不能關閉數據流(data stream)的寫索引(write index)。更多內容參考7.15版本文檔

比如, 給索引twitter添加一個分析器content:

# 關閉索引
POST /twitter/_close
# 添加分析器: 一個自定義的名字叫`content`的分析器, 然後可以在mapping中使用
PUT /twitter/_settings
{
 "analysis":{
   "analyzer":{
     "content":{
       "type":"custom",
       "tokenizer":"whitespace"
     }
   }
 }
}
# 重新打開索引
POST /twitter/_open

關於分析器的簡單知識, 本篇第三部分會翻譯, 或者參考 這裏


2. 獲取索引的設置

返回索引的設置信息。原官方英文文檔

GET /<index>/_settings
GET /<index>/_settings/<setting>

路徑參數

  • <index>

(可選, String) 支持多個索引名稱的英文逗號分割,以及通配符表達式。

如果要修改所有的索引的設置,可以使用_all或者直接忽略該參數。

  • <setting>

(可選, String) 支持多個配置名稱的英文逗號分割,以及通配符表達式。

查詢參數

allow_no_indices

(可選, bool) 如果設置爲true,則當全部使用通配符 *_all只檢索不存在(missing)或者已關閉(closed)的索引時,會拋出錯誤。

此參數也適用於指向不存在(missing)或者已關閉(closed)的索引的別名。

默認true

expand_wildcards

(可選, String) 通配符查詢時的範圍限制。支持多個條件的逗號分割。

  • all: 匹配open和closed的索引, 包括隱藏的
  • open: 表示只查詢開放中的索引
  • closed: 只匹配closed的
  • hidden: 隱藏的(hidden)索引,必須和open/closed聯合使用
  • none: 不接受通配符

默認 all

flat_settings

(可選, bool) 是否以平面格式返回settings信息。默認false

include_defaults

(可選, bool) 如果爲true,則返回信息中包含所有的默認的設置。默認 false

ignore_unavailable

(可選, bool) 如果爲true, missing或closed的索引不會包括在返回數據中。默認false

local

(可選, bool) 如果爲true, 則只從本地節點獲取信息。默認false, 表示從主節點獲取信息。

master_timeout

(可選,時間單位)連接到主節點的等待超時時間。如果在超時時間已過之前沒有響應, 則返回錯誤。 默認是值 30s。

幾個栗子

# 獲取單個索引的設置
GET /twitter/_settings

# 獲取單個索引的設置, 包含所有索引的默認配置
GET /twitter/_settings?include_defaults=true

# 獲取多個索引的配置
GET /twitter,twitter1/_settings

# 通配符獲取多個索引的配置
GET /twitter*/_settings

# 獲取所有索引的設置
GET /_all/_settings
GET /_settings

# 獲取索引的部分設置
GET /twitter/_settings/index.number*?include_defaults=true

# 獲取索引的部分設置, 包含所有索引的默認配置
GET /twitter/_settings/index.number*?include_defaults=true

3. 分析(Analyze)

獲取字符串分析(分詞)的結果。原官方英文文檔

GET|POST /_analyze

GET|POST /<index>/_analyze

路徑參數

  • <index>

(可選, String) 指定要獲取分析器的索引。

如果設置了參數analyzerfield, 也指定了索引,則前者會覆蓋這個設置,即: analyzer指定的分析器或field字段mapping中配置的分析器會被調用, 而不會調用該索引的默認分析器。

如果沒有指定analyzerfield, 則該api會使用該索引默認的分析器。

如果沒有指定索引, 或者指定的索引沒有默認的分析器, 則該api會使用標準分析器(standard analyzer)

查詢參數

我覺得這幾個參數不應該屬於 Query parameter, 而應該屬於 Request Body

analyzer

(可選, String) 用於分析給定文本的分析器的名稱。它可以是一個內置的分析器, 或者是索引中配置的一個分析器。

如果該參數未指定,則會使用字段中的mapping中定義的分析器。

如果字段未指定,則會使用索引的默認的分析器。

如果索引未指定,或者指定的索引沒有默認的分析器,則會使用標準分析器(standard analyzer)

attributes

(可選, 字符串數組) 用於過濾explain參數輸出的token屬性數組。TODO

char_filter

(可選, 字符串數組) 在分詞器處理之前,預先過濾字符的字符過濾器數組。更多參考字符過濾器(character filters)

explain

(可選, bool) 如果爲true, 則返回數據中包含token屬性和額外的細節。默認false

field

(可選, String) 用於指定分析器的字段, 必須指定索引名稱。

如果指定了字段, 則仍然會被參數analyzer所指定的分析器覆蓋。

如果沒有指定, 則使用素銀的默認的分析器。

如果沒有指定索引,或者指定的索引沒有默認的分析器, 則會使用標準分析器。

filter

(可選, 字符串數組) 用於在分詞器執行之後的token過濾數組。參考 Token Filters

normalizer

(可選, String) 用於把文本轉換爲一個單獨的token的標準化配置。參考 Normalizers

text

(必填, String或者String數組) 要分析的文本。如果提供的是一個字符串數組, 則被當做一個多值(multi-field)的字段來分析。

tokenizer

(可選, String) 把文本轉換爲token的分詞器。參考Tokenizer

優先級順序是:參數analyzer指定的分析器 > 參數field配置的分析器 > 索引的默認分析器 > 標準分析器

幾個栗子

1. 不指定索引(No index specified)

可以使用任何一個內建的分析器分析文本,而不用指定索引。

# 只要指定analyzer即可, 而不需要指定索引
GET /_analyze
{
  "analyzer":"standard",
  "text": "elastic search"
}

返回的值的tokens是一個json數組:

{
  "tokens" : [
    {
      "token" : "elastic",
      "start_offset" : 0,
      "end_offset" : 7,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "search",
      "start_offset" : 8,
      "end_offset" : 14,
      "type" : "<ALPHANUM>",
      "position" : 1
    }
  ]
}

2. 字符串數組

如果參數text給的是一個字符串數組, 則會被當做一個multi-value的字段來分析。

GET /_analyze
{
  "analyzer":"standard",
  "text": ["elastic search", "ik smart"]
}

返回數據的格式與使用一個字符串當參數時是一致的,都是json數組。(不是一個對應字符串數組的json數組的數組)

ES的text類型的字段是可以直接存儲字符串數組的

{
  "tokens" : [
    {
      "token" : "elastic",
      "start_offset" : 0,
      "end_offset" : 7,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "search",
      "start_offset" : 8,
      "end_offset" : 14,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "ik",
      "start_offset" : 15,
      "end_offset" : 17,
      "type" : "<ALPHANUM>",
      "position" : 2
    },
    {
      "token" : "smart",
      "start_offset" : 18,
      "end_offset" : 23,
      "type" : "<ALPHANUM>",
      "position" : 3
    }
  ]
}

3.自定義分析器

可以使用tokenizers、token過濾器和字符過濾器(char filters)構建一個自定義的臨時的分析器。token過濾器使用參數filter

# 使用的分詞器是keyword(不像text那樣會分詞), 把tokens轉爲小寫
GET /_analyze
{
  "tokenizer":"keyword",
  "filter": ["lowercase"],
  "text": "I am Tom"
}

執行結果, 僅僅是把tokens轉成了小寫而已:

{
  "tokens" : [
    {
      "token" : "i am tom",
      "start_offset" : 0,
      "end_offset" : 8,
      "type" : "word",
      "position" : 0
    }
  ]
}

下面這個例子, 在調用分詞器之前使用了char_filter(html_strip)過濾了html標籤:

GET /_analyze
{
  "tokenizer":"keyword",
  "filter": ["lowercase"],
  "char_filter": ["html_strip"],
  "text": "I am <b>Tom</b>"
}

如果分詞器換成 standard:

GET /_analyze
{
  "tokenizer":"standard",
  "filter": ["lowercase"],
  "char_filter": ["html_strip"],
  "text": "I am <b>Tom</b>"
}

先把tokens轉爲小寫, 再移除html標籤, 最後分詞, 執行結果是:

{
  "tokens" : [
    {
      "token" : "i",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "am",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "tom",
      "start_offset" : 8,
      "end_offset" : 15,
      "type" : "<ALPHANUM>",
      "position" : 2
    }
  ]
}

也可以指定分詞器(tokenizers)、token filters、character filters,比如:

GET /_analyze
{
  "tokenizer": "whitespace",
  "filter": [
    "lowercase", {
    "type": "stop",
    "stopwords": ["a", "is", "this"]
  }],
  "text": "This is ONLY a test"
}

這個例子中, 我們使用空格(whitespace)分詞器, 把tokens轉小寫, 寫設置了三個停止詞, 執行結果是:

{
  "tokens" : [
    {
      "token" : "only",
      "start_offset" : 8,
      "end_offset" : 12,
      "type" : "word",
      "position" : 2
    },
    {
      "token" : "test",
      "start_offset" : 15,
      "end_offset" : 19,
      "type" : "word",
      "position" : 4
    }
  ]
}

4. 指定索引(Specific index)

我們可以使用指定索引的默認的分析器來分析文本:

# 使用指定索引的默認的分析器
GET /twitter/_analyze
{
  "text": "this is a test"
}

也可以再自行指定另一個分析器:

# 即使指定了索引, 我們堅持使用另一個分析器 whitespace(空格)
GET /twitter/_analyze
{
  "analyzer": "whitespace",
  "text": "this is a test"
}

5. 使用從字段的mapping中派生出的分析器(Derive analyzer from a filed mapping) 索引twitter中有一個字段city, 我們可直接指定這個字段, 讓api使用這個字段的分析器來分詞:

GET /twitter/_analyze
{
  "field": "city",
  "text": "This is a test"
}

如果字段city沒有指定分析器, 則會使用索引twitter指定的分析器; 如果索引twitter沒有指定分析器, 則會使用standard分析器。

6. 標準化(Normalizer)

ES7.7還沒有提供內置的normalizer, 只能在索引的setting中組合 token filters和character filters作爲自定義的normalizer. 參考官方文檔 normalizers

可以通過與指定索引相關聯的normalizer爲關鍵字字段提供一個normalizer。

GET /<index>/_analyze
{
  "normalizer" : "<my_normalizer>",
  "text" : "BaR"
}

或者, 不指定索引的情況下, 直接通過指定token filters和char filters來構建一個臨時的normalizer:

GET /_analyze
{
  "filter": ["lowercase"],
  "text": "This is a test"
}

7. 解釋分析的過程(explain analyze)

如果你想了解更多細節, 設置參數explaintrue(默認是false),api會返回每一個token的屬性(attributes)。通過設置attributes選項可以過濾token的屬性。

下面的例子, 顯示 使用分詞器“standard”、token過濾器"snowball"(不推薦使用)來分析文本, 並只顯示屬性"keyword":

GET /_analyze
{
  "tokenizer" : "standard",
  "filter" : ["snowball"],
  "text" : "detailed output",
  "explain" : true,
  "attributes" : ["keyword"]
}

下面的右邊是上面代碼執行的結果, 左邊是沒有過濾attributes的結果, 可以查一下差異:

8. 設置token限制

Generating excessive amount of tokens may cause a node to run out of memory. The following setting allows to limit the number of tokens that can be produced:

生成過多的token可能會導致節點內存耗盡。 通過設置index.analyze.max_token_count可以限制生成的token的數量。

我們先查看一下索引的analyze的所有設置:

GET /twitter/_settings/index.analyze.*?include_defaults=true

執行結果:

參數index.analyze.max_token_count默認的設置是10000。如果生成的token數量超過這個限制, 就會拋出錯誤。這個參數可以按索引設置。

那我們現在把索引twitter的這個配置改成 2 吧:

PUT /twitter/_settings
{
  "index.analyze.max_token_count": 2
}

然後看一下修改好了沒:

GET /twitter/_settings/index.analyze.max_token_count

執行結果:

{
  "twitter" : {
    "settings" : {
      "index" : {
        "analyze" : {
          "max_token_count" : "2"
        }
      }
    }
  }
}

那我們現在再次調用_analyze api接口看會不會報錯:

GET /twitter/_analyze
{
  "text": "This is aben"
}

我們要分析的這個文本會被拆分成3個token, 這就超出了設置了, 接口拋出了錯誤:

還原成默認的10000吧:

# 還原設置
PUT /twitter/_settings
{
  "index.analyze.max_token_count": null
}

這個index.analyze.max_token_count參數會影響_analyze接口, 那麼會不會影響對該索引的索引操作呢? 如果不小心設置過小, 會導致索引更新失敗嗎??

last updated at 2021/10/29 23:00

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章