添加分词器

Elasticsearch 动态添加分词器:解决非动态配置更新问题

在 Elasticsearch 中,索引的部分配置(如分词器、分片数)属于非动态配置,创建索引后无法直接修改,否则会报 Can't update non dynamic settings 错误。若需为运行中的索引添加新分词器,需通过 “关闭索引→修改配置→重新打开索引” 的流程实现。

操作步骤详解

关闭索引

关闭索引后,索引暂时不可读写,但数据不会丢失,此时可修改非动态配置:

POST my_index/_close  # 关闭名为my_index的索引

响应示例

{
  "acknowledged": true
}

添加 / 修改分词器配置

通过 _settings API 为关闭的索引添加新分词器(如按逗号拆分的 comma_analyzer):

PUT my_index/_settings
{
  "settings": {
    "analysis": {
      "analyzer": {
        "comma_analyzer": {  # 自定义分词器名称
          "type": "pattern",  # 基于正则模式的分词器
          "pattern": ","      # 按逗号拆分
        }
      }
    }
  }
}

配置说明

  • type: "pattern":使用正则表达式定义分词规则。
  • pattern: ",":指定逗号为分词分隔符(即按逗号拆分文本)。

重新打开索引

修改配置后,重新打开索引使其生效:

POST my_index/_open  # 重新打开索引

响应示例

{
  "acknowledged": true,
  "shards_acknowledged": true
}

验证分词器

通过 _analyze API 验证新分词器是否生效:

POST my_index/_analyze
{
  "analyzer": "comma_analyzer",  # 使用新添加的分词器
  "text": "apple,banana,orange"  # 测试文本
}

预期结果(按逗号拆分):

{
  "tokens": [
    {"token": "apple", "start_offset": 0, "end_offset": 5, "position": 0},
    {"token": "banana", "start_offset": 6, "end_offset": 12, "position": 1},
    {"token": "orange", "start_offset": 13, "end_offset": 19, "position": 2}
  ]
}

关键注意事项

  1. 索引可用性
    关闭索引期间,该索引无法执行读写操作,建议在业务低峰期操作,并提前通知相关方。

  2. 配置兼容性

    • 仅可修改非动态配置(如分词器、分析器),分片数(number_of_shards)仍无法修改
    • 若新增的分词器依赖自定义过滤器或字符过滤器,需一并在 settings 中定义。
  3. 映射更新
    若需在现有字段中使用新分词器,需通过 _mapping API 更新字段映射:

    PUT my_index/_mapping
    {
      "properties": {
        "tags": {
          "type": "text",
          "analyzer": "comma_analyzer"  # 为tags字段应用新分词器
        }
      }
    }
  4. 版本差异

    • 7.x+ 版本中,索引关闭 / 打开操作支持集群级别的并发处理,影响范围较小。
    • 旧版本(如 5.x)可能存在性能瓶颈,建议提前测试。

替代方案:重建索引(推荐)

若索引数据量较大,关闭索引可能影响可用性,推荐通过重建索引方式添加分词器:

  1. 创建新索引:定义包含新分词器的映射和配置。
  2. 数据迁移:使用 _reindex API 将旧索引数据迁移至新索引。
  3. 切换别名:通过索引别名无缝切换读写流量至新索引。

示例

# 1. 创建带新分词器的新索引
PUT my_index_new
{
  "settings": {
    "analysis": {
      "analyzer": {
        "comma_analyzer": {
          "type": "pattern",
          "pattern": ","
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "tags": {
        "type": "text",
        "analyzer": "comma_analyzer"
      }
    }
  }
}

# 2. 迁移数据
POST _reindex
{
  "source": {"index": "my_index"},
  "dest": {"index": "my_index_new"}
}

# 3. 切换别名(假设原索引使用别名my_index_alias)
POST _aliases
{
  "actions": [
    {"remove": {"index": "my_index", "alias": "my_index_alias"}},
    {"add": {"index": "my_index_new", "alias": "my_index_alias"}}
  ]
}