Files

4.0 KiB
Raw Permalink Blame History

id, title, type, domain, stack, tags, level, related, week
id title type domain stack tags level related week
backend.elasticsearch.interview Elasticsearch 面试题 interview backend
elasticsearch
Elasticsearch
倒排索引
混合检索
面试
intermediate
backend.elasticsearch.search-hybrid
14
16

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)或写入前比较更新时间,只接受更新的版本。