Elasticsearch重建索引切换alias时避免搜索结果重复方案咨询
问题根因
重复查询结果的核心诱因是执行第3步后,你的搜索别名同时关联了index_1和index_2两个存储了相同全量数据的索引,查询别名时会默认检索所有关联索引的全部数据,相同文档会分别从两个索引返回,最终表现为结果重复。
规避方案
你可以通过调整重建索引的操作流程彻底解决该问题,以下两种方案可根据业务容忍度选择:
方案1:秒级切换(适合可接受秒级只读的业务)
调整后的操作流程全程不会出现别名关联双索引的状态,完全不会产生重复结果:
- 基于新映射创建新索引
index_2 - 执行全量重建任务,将
index_1的所有数据同步到index_2 - 将
index_1设置为只读状态,阻止新的写入产生,操作参考:PUT /index_1/_settings { "settings": { "index.blocks.write": true } } - 同步全量同步结束到设置只读这段时间产生的少量增量数据到
index_2 - 调用ES别名原子操作接口,一次性完成旧索引解绑、新索引绑定、写权限设置三个操作,不存在中间状态:
POST /_aliases { "actions": [ {"remove": {"index": "index_1", "alias": "你的搜索别名"}}, {"add": {"index": "index_2", "alias": "你的搜索别名", "is_write_index": true}} ] } - 确认流量完全切到
index_2后,删除原索引index_1即可
方案2:完全零停机(适合不能接受写入中断的业务)
如果不允许设置只读,可以通过别名隐藏属性规避双索引查询的重复问题:
- 基于新映射创建新索引
index_2 - 执行全量重建任务,将
index_1的所有数据同步到index_2 - 调用别名接口绑定
index_2到别名,设置为写索引,同时给旧索引index_1的关联加上隐藏属性,此时查询别名只会返回index_2的内容:POST /_aliases { "actions": [ {"remove": {"index": "index_1", "alias": "你的搜索别名"}}, {"add": {"index": "index_1", "alias": "你的搜索别名", "is_hidden": true}}, {"add": {"index": "index_2", "alias": "你的搜索别名", "is_write_index": true}} ] } - 同步
index_1的剩余增量数据到index_2 - 确认增量同步完成后,原子性解绑
index_1和别名的关联 - 删除原索引
index_1即可
内容的提问来源于stack exchange,提问作者mnaa
相关产品推荐
相关产品推荐

