📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

为什么这个错误发生 #

index_not_found_exception 表示尝试访问一个不存在的索引。

这个错误可能由以下原因引起:

  1. 索引名称拼写错误:请求中的索引名称输入错误
  2. 索引尚未创建:尝试访问还未创建的索引
  3. 索引被删除:索引已被删除但客户端仍在尝试访问
  4. 大小写不匹配:索引名称区分大小写,请求的大小写与实际不符
  5. 集群/别名问题:通过别名访问时,别名不存在或指向不存在的索引
  6. 跨集群搜索失败:跨集群搜索时,目标集群的索引不存在
  7. 时间序列索引过期:基于时间的索引(如 logs-2023-01-01)已过期被删除
  8. 多租户环境问题:在多租户环境中访问了其他租户的索引

如何修复这个错误 #

1. 验证索引名称 #

# 列出所有索引
GET /_cat/indices?v

# 搜索特定模式的索引
GET /_cat/indices/<pattern>?v

# 检查索引是否存在(返回 200 或 404)
HEAD /<index_name>

2. 创建索引 #

如果索引不存在,可以创建它:

# 创建新索引
PUT /<index_name>

# 创建索引并指定设置和映射
PUT /<index_name>
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 2
  },
  "mappings": {
    "properties": {
      "field1": {"type": "text"},
      "field2": {"type": "keyword"}
    }
  }
}

3. 使用自动创建 #

允许索引自动创建(默认开启):

# easysearch.yml
action.auto_create_index: true
# 或指定允许的模式
action.auto_create_index: +logs*,-test*

4. 处理时间序列索引 #

对于基于时间的索引,使用索引模板:

# 创建索引模板
PUT /_index_template/logs-template
{
  "index_patterns": ["logs-*"],
  "template": {
    "settings": {
      "number_of_shards": 3
    },
    "mappings": {
      "properties": {
        "timestamp": {"type": "date"},
        "message": {"type": "text"}
      }
    }
  }
}

5. 使用别名 #

通过别名访问索引,提高灵活性:

# 创建别名
POST /_aliases
{
  "actions": [
    {
      "add": {
        "index": "logs-2023-01-01",
        "alias": "logs-current"
      }
    }
  ]
}

# 通过别名访问
GET /logs-current/_search

6. 忽略不存在的索引 #

在某些操作中忽略不存在的索引:

# 删除时忽略不存在的索引
DELETE /<index_name>?ignore_unavailable=true

# 搜索时忽略不存在的索引
GET /<index1>,<index2>,<index3>/_search?ignore_unavailable=true

7. 使用通配符和不存在索引处理 #

# 使用 expand_wildcards 控制通配符行为
GET /_all/_search?expand_wildcards=open,closed

8. 检查跨集群配置 #

如果是跨集群搜索:

# 检查跨集群配置
GET /_cluster/state?filter_path=**.remote

# 验证远程集群连接
GET /_remote/info

预防措施 #

  • 使用索引模板自动管理时间序列索引
  • 使用别名而不是直接访问索引名称
  • 在代码中验证索引是否存在后再操作
  • 使用索引生命周期管理(ILM)自动管理索引
  • 对于关键操作,添加索引存在性检查
  • 使用统一的索引命名规范
  • 在多环境中使用不同的索引前缀或后缀