ES 的 suggester 被归到 _search
API 下, 算是一个特殊的检索, 用于拼写纠正/拼接建议/自动补全.
Term Suggester
mapping 并没有特殊, 就是普通的 text
.
term
之间推荐的依据是 termA 通过修改几个字符能变成 termB? 如果变动在设置范围之内, 就给予推荐.
DELETE /demo
PUT /demo
{"mappings":{"properties":{"name":{"type":"text"}}}}
索引示例数据.
需要特别注意的term: lucene
rock
rocks
.
POST /demo/_bulk
{"create": {}}
{"name": "lucene is very cool"}
{"create": {}}
{"name": "Elasticsearch builds on top of lucene"}
{"create": {}}
{"name": "Elasticsearch rocks"}
{"create": {}}
{"name": "elastic is the company behind ELK stack"}
{"create": {}}
{"name": "Elk stack rocks"}
{"create": {}}
{"name": "elasticsearch is rock solid"}
suggest_mode |
description |
---|---|
missing | default. 当 term 不存在时, 给出建议 |
always | 无论 term 是否存在, 都给出建议 |
popular | 给出词频更高的建议 |
rock
已经存在了, 返回结果为空:
GET /demo/_search
{
"suggest": {
"YOUR_SUGGESTION": {
"text": "rock",
"term": {
"suggest_mode": "missing",
"field": "name"
}
}
}
}
虽然 rock
已经存在, 但通过 rock
还可以找到 rocks
, 就推荐 rocks
:
GET /demo/_search
{
"suggest": {
"YOUR_SUGGESTION": {
"text": "rock",
"term": {
"suggest_mode": "popular",
"field": "name"
}
}
}
}
基于 第一个字符不会拼错
的假设, prefix_length
默认值是 1, 所以默认情况下, 第一个字母写错就得不到建议.
(不懂 always
有啥存在的必要, 看起来跟 popular
效果一样.)
term phrase
term suggest 只对单个 term 进行推荐, 即便 text
是多个字符, 也会先分词然后分别给出各自的建议. 如果需要 text 的上下文关系, 使用 phrase suggest.
completion phrase
自动补全对交互和性能的要求更高, 使用了单独的数据结构来存储, 需要特殊的 mapping 设置.
PUT /demo
{
"mappings": {
"properties": {
"name": {
"type": "text",
"fields": {
"completion": {
"type": "completion"
}
}
}
}
}
}
GET /demo/_search
{
"suggest": {
"YOUR_SUGGESTION": {
"text": "lu",
"completion": {
"field": "name.completion"
}
}
}
}