4.0 KiB
id, title, type, domain, stack, tags, level, related, week
| id | title | type | domain | stack | tags | level | related | week | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| backend.elasticsearch.interview | Elasticsearch 面试题 | interview | backend |
|
|
intermediate |
|
|
Elasticsearch 面试题
基础
【基础】什么是倒排索引?
参考答案:从“词”到“包含该词的文档列表(及位置、词频)”的映射。写入时对文本分词建立倒排表,查询时分词后查表求交并、算分,所以全文检索快。
追问:为什么 ES 写入后不能立即搜到?→ 近实时:写入先进内存缓冲,refresh(默认约 1 秒)后生成新的段才可搜索;可以 refresh=wait_for 但会影响写入性能。
【基础】text 和 keyword 的区别?
参考答案:text 会分词,用于全文检索;keyword 不分词,用于精确匹配、过滤、排序和聚合。同一字段可以用多字段(fields)同时建两种。
追问:对 text 字段做 term 查询会怎样?→ 往往查不到,因为存储的是分词后的词项,而 term 查询不分词。
【基础】must 和 filter 的区别?
参考答案:都要求匹配;must 参与相关性算分,filter 不算分并且可以被缓存,适合租户、权限、状态、时间范围等条件。
追问:权限条件应该放哪里?→ filter,并且在向量检索中也要通过 knn.filter 传入。
进阶
【进阶】混合检索怎么做?为什么常用 RRF?
参考答案:关键词(BM25)和向量(kNN)分别召回,再融合。BM25 分数无上限、与查询相关,向量相似度在固定区间,直接加权需要归一化且不稳定;RRF 只用名次 1/(k+rank) 求和,简单稳健。融合后再用重排模型精排。
追问:服务端 RRF 和应用层 RRF 怎么选?→ 服务端少一次往返、写法简洁,但受版本和许可证限制;应用层灵活、可以融合来自不同系统(例如 ES + pgvector)的结果。
【进阶】映射需要修改怎么办?
参考答案:已有字段的类型和分词器不能修改。新建索引(新映射)→ _reindex 或从数据源重新导入 → 追平增量 → 校验 → 原子切换别名 → 保留旧索引以便回滚。
追问:重建期间的增量写入怎么处理?→ 双写到新旧索引,或者重建完成后按时间戳 / 版本号补齐差异再切换。
【进阶】中文分词怎么做?
参考答案:常用 IK 插件:写入用细粒度(ik_max_word),查询用粗粒度(ik_smart);维护业务词典和同义词;插件版本要与 ES 一致。内置 cjk 分析器按二元切分,可以作为没有插件时的方案。
追问:词典更新后要做什么?→ 新写入的数据按新词典分词,已有数据需要重建索引才会生效。
场景题
【场景题】RAG 知识库对型号、错误码检索不准,怎么改?
参考答案:引入关键词检索与向量检索混合(ES BM25 + kNN,RRF 融合 + 重排);业务词典保证型号不被切碎;权限作为 filter;同步链路保证数据新鲜;用标注集评估召回率。详见知识库混合检索场景。
追问:怎么证明改进有效?→ 固定标注集,对比改动前后的召回率@K、MRR 以及最终回答的正确率。
【场景题】数据库中的数据怎么可靠地同步到 ES?
参考答案:常用方案:业务事务内写 outbox 表 → 投递到消息队列 → 幂等消费者写 ES(数据库主键作为 _id、带版本号防止旧数据覆盖新数据);或者用 CDC(读取数据库日志,如 Debezium / MongoDB 变更流)。失败重试 + 死信 + 定期对账。
追问:消息乱序导致旧版本覆盖新版本怎么办?→ 使用外部版本号(version_type=external)或写入前比较更新时间,只接受更新的版本。