29 · suggester 自动补全(搜索框联想 / 拼写纠错)
阶段:第二三阶段补充 / 查询结果处理
ES:
completion/term/phrasesuggester | PostgreSQL:pg_trgm相似度 / 前缀索引
1. 概念
三种建议器,解决不同问题:
| suggester | 作用 | 场景 |
|---|---|---|
completion |
前缀实时补全(基于 FST,极快) | 搜索框输入即联想 |
term |
逐词纠错(编辑距离) | "拼错了帮我改对" |
phrase |
整句纠错(term 的升级,考虑上下文) | "did you mean ..." |
completion 需要字段类型是 completion,写入时把候选词喂进去。
2. PostgreSQL 对照
sql
-- 前缀补全:前缀索引 + LIKE
SELECT name FROM products WHERE name LIKE 'think%' ORDER BY name LIMIT 10;
-- 拼写纠错:pg_trgm 相似度
SELECT name FROM products ORDER BY name <-> 'thnkpad' LIMIT 5;
ES 的 completion 比 LIKE 'x%' 快得多(内存 FST);term/phrase 类似 pg_trgm 纠错。
3. ES DSL
3.1 completion:mapping + 写入 + 补全
PUT products_idx
{ "mappings": { "properties": {
"name": { "type": "text" },
"name_suggest":{ "type": "completion" }
} } }
POST products_idx/_doc
{ "name": "ThinkPad X1", "name_suggest": ["ThinkPad X1", "X1 Carbon"] }
POST products_idx/_search
{
"suggest": {
"s": {
"prefix": "think",
"completion": { "field": "name_suggest", "size": 5 }
}
}
}
3.2 term / phrase:纠错
POST products_idx/_search
{
"suggest": {
"correct": {
"text": "thnkpad",
"term": { "field": "name" }
}
}
}
4. Spring Boot 实现
java
@Component
public class Doc29Suggester {
@Autowired
private ElasticsearchClient elasticsearchClient;
/** 前缀补全,返回候选词列表 */
public List<String> complete(String indexName, String prefix) throws IOException {
SearchResponse<Void> resp = elasticsearchClient.search(s -> s
.index(indexName)
.suggest(sg -> sg.suggesters("s", su -> su
.prefix(prefix)
.completion(c -> c.field("name_suggest").size(5)))),
Void.class);
return resp.suggest().get("s").stream()
.flatMap(entry -> entry.completion().options().stream())
.map(opt -> opt.text())
.collect(Collectors.toList());
}
}
completion suggester 的结果在
resp.suggest()(Map<String, List<Suggestion>>),取
entry.completion().options()里的text()。搜索建议不占hits,size(0)亦可。
5. 坑与最佳实践
- completion 是独立字段 :要单独 mapping + 写入候选词,不是给已有
text直接加的。 - completion 占内存:FST 常驻堆内存,候选量极大时评估内存。
- 要拼音/中文补全:需装分析插件(如 pinyin / IK),默认分词对中文补全不友好。
- 纠错用
phrase更稳 :term逐词纠,phrase结合上下文更准,适合"你是不是要找"。 - 补全 vs 搜索是两件事 :补全给候选词,用户选定后再发一次正常
search。
下一篇
进入第三阶段聚合能力:20-metric-指标聚合.md。