es向量搜索
**多数场景下,用“ES + 向量”会更稳**,尤其是同义改写、语序变化这类纯语义相似;但标题很短(≤8字)时,**仅向量容易误杀**,要搭配 BM25 一起用。最简单、效果好的做法是:**在你现有 ES 上加一个向量字段做 Hybrid(BM25+向量)**。
# 什么时候向量更好
* 同义/改写多:如“Kafka 广播机制原理?” vs “Kafka 主题广播怎么实现?”
* 关键词差别大:同义换词、概念近义
* 你只看标题,不用标签/正文
# 什么时候别只用向量
* 标题很短(≤8字):语义不稳定,向量容易把不同题拉近
* 需要解释性强的匹配权重:BM25 分词+短语更可控
# 最小改造(基于 ES 的 Hybrid)
保留你现在的 `title` 字段,**只新增一个向量字段**,离线/入库时把标题做同一套预处理后生成 embedding 存进去。
## 索引(ES 8.x 原生 HNSW,最小可用)
```json
PUT question_idx
{
"mappings": {
"properties": {
"title": { "type": "text", "analyzer": "ik_smart" },
"title_vec": {
"type": "dense_vector",
"dims": 768, // 用你的向量维度
"index": true,
"similarity": "cosine",
"index_options": { "type": "hnsw", "m": 16, "ef_construction": 256 }
}
}
}
}
```
> 注:ES 7.10/7.15 没原生 ANN,只能 `script_score` 点积(慢)。若你有 ES 8 集群,直接上面这个。
## 查询(Hybrid:BM25 召回 + 向量重排,保持简单)
1. 先做一次普通 BM25,拿 Top200 候选:
```json
POST question_idx/_search
{
"size": 200,
"_source": ["title"],
"query": {
"multi_match": {
"query": "<raw_title>",
"fields": ["title"]
}
}
}
```
2. 同时做一次向量 KNN(Top200):
```json
POST question_idx/_search
{
"size": 200,
"knn": {
"field": "title_vec",
"query_vector": [ /* 你的标题向量 */ ],
"k": 200,
"num_candidates": 1000
},
"_source": ["title"]
}
```
3. 在应用侧**合并去重**两路候选后打分融合(超简版):
```
final_score = 0.6 * cosine_sim + 0.4 * bm25_norm
```
* `cosine_sim`:ES knn 的 `_score` 本身就是相似度(取值看实现,通常可直接用/做Min-Max归一化)
* `bm25_norm`:把 BM25 分数做 Min-Max 到 [0,1]
## 判重阈值(只标题)
* 若标题长度 > 8 字:
* `cosine_sim ≥ 0.88` → 直接判重
* `0.82 ≤ cosine_sim < 0.88` 且 BM25 Top1 → 判重
* 若标题长度 ≤ 8 字(短标题更严):
* `cosine_sim ≥ 0.92` 且同时 BM25 Top3 → 判重
* 否则不判重(可把 Top5 返回人工二审)
> 以上是保守默认值,跑你们历史样本100~200条后再微调一次就稳定了。
# 生成向量的注意点
* **线上查询与入库向量必须同一模型、同一预处理**(统一大小写、全半角、去括号尾注等)
* 中文短文本用**中文专用 embedding**效果更好(维度 512/768/1024 均可,保持一致即可)
* 入库时就写入 `title_vec`,避免查询时现算
# 如果你只想要“最简单可用”的版本
* 把上面的第 2 步(KNN)+ 第 3 步(融合)拿掉,先只用 BM25;不够再加 KNN
* 或者只做 **KNN 一条查询**,判重阈值用 `cosine_sim ≥ 0.88/0.92(短标题)`,这是最少改造
# 小结
* **是的,向量会更好**(对语义改写鲁棒),但要与 BM25 互补,尤其短标题。
* 不需要上新向量库;**ES 8 自带 HNSW 就够**。
* 从“BM25 → Hybrid(再加一个向量字段)”的增量改造成本很低,先上再调阈值即可。
需要的话我可以:
* 给你一段 Java/Python 的“标题→向量”小工具(同一清洗规则)
* 帮你把现有索引脚本改成“BM25-only”与“Hybrid”两套可切换的版本(包含阈值配置)
公众号进入网站体验更佳

