Node.js使用Elasticsearch客户端报索引不存在404错误如何解决
问题原因
你的报错已经明确指向根因:你所用的Bonsai托管Elasticsearch集群默认限制了自动创建索引的白名单,action.auto_create_index配置里仅允许*logstash*,*requests*,*events*,*.kibana*,*kibana-int*,*filebeat*,.watches,.triggered_watches,.watcher-history-*这些规则匹配的索引自动创建,你要写入的question索引不在白名单范围内,因此无法自动创建,直接写入就会抛出404索引不存在错误。
解决方案
方案1:手动预先创建索引(最推荐)
在写入数据前先调用索引创建接口创建question索引,可搭配索引存在性判断逻辑避免重复创建报错,示例代码如下:
// 先判断索引是否存在 client.indices.exists({ index: 'question' }, (err, exists) => { if (err) throw err // 索引不存在则创建 if (!exists) { client.indices.create({ index: 'question', // 可自定义 mappings、settings 配置,按需填写 body: { mappings: { // 如果你用的是ES7+版本,不需要指定type,直接写properties即可 properties: { title: { type: 'text' }, tags: { type: 'keyword' } } } } }, (createErr) => { if (createErr) throw createErr // 索引创建完成后再执行写入逻辑 writeQuestionData() }) } else { // 索引已存在直接写入 writeQuestionData() } }) // 封装你原有的写入逻辑 function writeQuestionData() { client.index({ index: 'question', id: question_id, // 注意:ES7+版本已经废弃type,若你用的是7.x及以上版本,删除这行即可,默认使用_doc type: 'questions', body: { "title": title, "tags": tags } }, function(err, resp, status) { // 原有业务逻辑 }) }
方案2:修改自动创建索引白名单
如果你确实需要保留自动创建索引的逻辑,可修改集群action.auto_create_index配置,将question加入白名单:
client.cluster.putSettings({ body: { persistent: { "action.auto_create_index": "*logstash*,*requests*,*events*,*.kibana*,*kibana-int*,*filebeat*,.watches,.triggered_watches,.watcher-history-*,question" } } })
注意:部分低配额的Bonsai集群版本可能不支持修改集群级配置,若调用报错无权限请使用方案1。
方案3:调整索引命名适配现有白名单(不推荐)
你也可以将索引名修改为现有白名单匹配的格式,比如命名为requests_question,即可触发自动创建,但这种方式会打乱你的索引命名规范,仅临时测试时可使用。
额外注意事项
- 若你使用的Elasticsearch版本为7.x及以上,官方已经废弃了自定义type的配置,你原有代码里的
type: 'questions'可以删除,否则高版本集群会抛出兼容性警告或错误。 - 生产环境建议关闭自动创建索引的功能,所有索引都预先手动创建并配置对应mappings,避免字段类型自动匹配错误导致业务异常。
内容的提问来源于stack exchange,提问作者Lion789
相关产品推荐
相关产品推荐

