##################Suggester############################
#elasticsearch suggester 帮助用户在搜索的过程中,进行自动补全或者纠错,通过协助用户输入更加精准的关键词。
原理:将输入的文本分解为Token,然后再索引的字典里查找相似的term 并返回
根据不同的使⽤场景,Elasticsearch 设计了 4 种类别的 Suggesters
###● Term & Phrase Suggester
###● Complete & Context Suggester
term Suggester
DELETE articles
POST articles/_bulk
{ "index" : { } }
{ "body": "lucene is very cool"}
{ "index" : { } }
{ "body": "Elasticsearch builds on top of lucene"}
{ "index" : { } }
{ "body": "Elasticsearch rocks"}
{ "index" : { } }
{ "body": "elastic is the company behind ELK stack"}
{ "index" : { } }
{ "body": "Elk stack rocks"}
{ "index" : {} }
{ "body": "elasticsearch is rock solid"}
我们直接导入文档,默认采用standard分词器 rocks 和rock是俩个词
POST _analyze
{
"analyzer": "standard",
"text": ["Elk stack rocks rock"]
}
用户错误的输入了"lucen" 直接查询,无法查询到数据关于""lucen"的数据,只能返回rock的数据 因为默认采用standard分词器
POST articles/_search
{
"size": 1,
"query": {
"match": {
"body": "lucen rock"
}
}
}
suggester就是一种特殊类型的搜索(可以修复用户错误的输入)
我们再次进行测试,这次将用户输入的错误的"lucen" 放入我的suggest中 查询结果中返回了es建议的词"lucene" 也就是我们正确的词条 而且也建议了:"rocks"返回给我们。
"text"里面指定用户输入的词条 "field"中指定进行suggest字段名 “suggest_mode” 用来指定如何提供建议。有三种方式可选 "sort"用来指定排序方式, 默认按照分数score进行排序。也可以按照frequency频率进行排序 “prefix_length” 默认首字母不一致就不会匹配,如果设置为0.那么即使首字母不一致,也会匹配
● Missing – 如索引中已经存在,就不提供建议 比如我们的词典中有 rocks 如果用户正确输入 rocks 那么就不会进行建议返回相应的数据
● Popular – 推荐出现频率更加⾼的词 返回建议中出现频率更高的词
● Always – ⽆论是否存在,都提供建议 都进行建议
例如,下面的查询中,如果采用missing 就不会返回建议。如果采用always 就会返回建议
POST articles/_search
{
"size": 1,
"query": {
"match": {
"body": "lucen rock"
}
},
"suggest": {
"my_suggestion": {
"text": "lucen hock",
"term": {
"prefix_length": 0,
"suggest_mode": "missing",
"field": "body",
"sort": "frequency"
}
}
}
}
phrase suggester 在 termsuggester 上添加了一下额外的逻辑(可以修复用户错误的输入)
新增的参数
max errors:最多可以拼错的terms数
confidence:限制返回结果数,默认为1
highlight: 对进行建议的词高亮显示
下面的测试中 lucne elasticsear rock 这三个词都拼写错误 那么我们的建议就会返回一些options供我们选择,他们按照score 进行排序 每个词条中最多会修复俩个错误,
POST articles/_search
{
"suggest": {
"my_suggestion": {
"text": "lucne and elasticsear rock hello world ",
"phrase": {
"field": "body",
"max_errors": 2,
"confidence": 0,
"highlight": {
"pre_tag": "<em>",
"post_tag": "</em>"
}
}
}
}
}
the completion suggester
completion suggester 提供了 自动完成的功能,也就是用户没输入一个字符,就需要及时的发生一个查询请求到后端查找匹配项 对性能要求更高,所以并不是采用倒排索引,而是将analyze 的数据编码成fst 和索引一起存放,fst会被es整个加载进内存。速度很快 fst 只能用于前缀查询
使用步骤,第一步,创建index 指定mapping 指定字段的类型为 completion (其实就是一个普通的字段,只不过是进行自动建议而已)
DELETE articles
PUT articles
{
"mappings": {
"properties": {
"title_completion":{
"type": "completion"
}
}
}
}
第二步,导入数据
POST articles/_bulk
{ "index" : { } }
{ "title_completion": "lucene is very cool"}
{ "index" : { } }
{ "title_completion": "Elasticsearch builds on top of lucene"}
{ "index" : { } }
{ "title_completion": "Elasticsearch rocks"}
{ "index" : { } }
{ "title_completion": "elastic is the company behind ELK stack"}
{ "index" : { } }
{ "title_completion": "Elk stack rocks"}
{ "index" : {} }
第三步,查询
只能使用prefix 前缀查询 指定为completion查询 field指定进行建议的字段
结果会返回匹配到的文档数据
POST articles/_search
{
"size": 0,
"suggest": {
"my_suggester": {
"prefix": "E",
"completion": {
"field": "title_completion"
}
}
}
}
context suggester
context suggester 是 completion的扩展
可以在搜索中加入更多的上下文信息。例如 输入"“star”
#####● 咖啡相关:建议 “Starbucks” ● 电影相关:建议”star wars”
#####实现 Context Suggester
#####● 可以定义两种类型的 Context
#####● Category – 任意的字符串
#####● Geo – 地理位置信息
#####● 实现 Context Suggester 的具体步骤
#####● 定制⼀个 Mapping
#####● 索引数据,并且为每个⽂档加⼊ Context 信息
#####● 结合 Context 进⾏ Suggestion 查询
DELETE comments
创建一个索引
PUT comments
给索引添加映射 指定属性comment_autocomplete 的类型为completion 并且他有一个上下文。指定上下文type 为category 起一个名字叫comment_category
PUT comments/_mapping
{
"properties": {
"comment_autocomplete": {
"type": "completion",
"contexts": [
{
"type": "category",
"name": "comment_category"
}
]
}
}
}
添加数据 指定他的分类为movies 并添加文档数据comment 对象数据 comment_autocomplete
POST comments/_doc
{
"comment":"I love the star war movies",
"comment_autocomplete":{
"input":["star wars"],
"contexts":{
"comment_category":"movies"
}
}
}
添加数据 指定他的分类为coffee 并添加文档数据comment 对象数据 comment_autocomplete
POST comments/_doc
{
"comment":"Where can I find a Starbucks",
"comment_autocomplete":{
"input":["starbucks"],
"contexts":{
"comment_category":"coffee"
}
}
}
GET comments/_mapping
不同类型下回返回不同类型建议结果
POST comments/_search
{
"suggest": {
"my": {
"prefix": "sta",
"completion": {
"field": "comment_autocomplete",
"contexts":{
"comment_category":"coffee"
}
}
}
}
}
ps: 下面一些链接是我在学习的时候看到比较好的一些文章。
https://www.pianshen.com/article/7284152357/
https://www.jianshu.com/p/e245b1b4711f
https://segmentfault.com/a/1190000020272549