[ElasticSearch]Suggest查询建议(自动补全&纠错)

1) 概念

查询建议,能够为用户提供良好的使用体验。主要包括:
    拼写检查(纠错)
    自动建议查询词(自动补全)

2) Suggest种类及参数

2.1 Term Suggester

Term Suggester: 对给入的文本进行分词,为每个词进行模糊查询提供词项建议。(建议对搜索词进行长度控制,超过长度则不会进行TermSuggest,原因也是一般Term Suggester适用于单个词使用 把得分最高的推荐词进行返回代表纠错)

参数描述
text建议文本,即要进行推荐建议的文本(推荐控制长度 使用单个词进行搜索推荐)。
field从哪个字段中获取建议结果,智搜词库中指定的keyword字段
analyzer分析器
size建议返回的更正词的最大数量。
sort排序方式 1.score(默认):首先是按分数进行排序,分数相同按词频(freq)进行排序 2.frequency: 首先按词频进行排序,然后按分数进行排序
suggest_mode建议模式控制 1.missing(默认): 搜索的词如果本身就存在词库中,则不进行推荐搜索 2.popular:推荐词的词频大于搜索的词的时候才会推荐出来 3.always:根据建议文本中的术语提出任何匹配的建议。
max_edits允许推荐的词的最大编辑距离 默认为2
prefix_length必须满足搜索词的前端的多少个字符
max_term_freq搜索词可以出现在文档中的最大阈值(一般设置为百分比如0.4) 用于过滤高频词
min_doc_freq最少出现在多少个文档中
string_distance指定算法进行推荐计算 1.internal: 默认基于 damerau_levenshtein,但高度优化用于比较索引内术语的字符串距离 2.damerau_levenshtein 3.levenshtein 4.jaro_winkler 5. ngram

2.2 Phrase Suggester

Phrase Suggester:在term的基础上,会考量多个term之间的关系,比如是否同时出现在索引的原文里,相邻程度,以及词频等。

如果说term suggester建议处理单个词的纠错 那么Phrase Suggester就建议作为一整句话的纠错(返回值的suggest列表中返回的也是一整句话)

参数描述
max_errors该句子中拼写错误的术语的最大百分比 如果给定[0,1)的浮点数则为百分比!! 如果>1 则为可拼写错误词的个数!!
separator短语中各个术语的分隔符 默认为空格 可以手动指定
highlight可以指定高亮

2.3 Completion Suggester

Completion Suggester:自动补全的建议器,此场景下用户每输入一个字符的时候,就需要即时发送一次查询请求到后端查找匹配项,在用户输入速度较高的情况下对后端响应速度要求比较苛刻。因此实现上它和前面两个Suggester采用了不同的数据结构。为了使用Completion Suggester,字段的类型需要专门定义如下(当然可以通过fields来指定):

 这里比较有意思的一点是:completion并非使用倒排索引,而是将analyze过的数据编码成FST和索引一起存放。也就是直接编码放入内存,这样会导致他是连续的(非倒排的连续索引),这样就可以保证自动补全(利用前缀)的查询速度极快,但是由于他不是倒排索引仅仅只能用于前缀搜索了

接下来我们put数据进行测试

利用completion suggester进行查找

得到结果应该为 Elastic is the company behind...那一条

但是此处如果我们更换analyzer为English

此时我们在此插入并搜索 elastic i 将搜索不到,这是因为 我们前面提过了 它是通过分词器进行分词 并且把连续的词放入内存中以便快速搜索,但是english analyzer会剥离高频词 比如is 所以我们输入 elastic i的时候 输入被分解成"elastic"和"i",FST没有编码这个“i” , 匹配失败。

但是如果查询 elastic is 则会查询到 因为:经过english analyzer的时候is也被剥离了,只需在FST里查询"elastic"这个前缀,自然就可以匹配到了。

2.4 参数

 刨析参数之前,值得一提的是:它不仅仅包含前缀查询 还包含以下几种

* prefix前缀:一般就是用于搜索推荐自动补全的 最常用
* fuzzy模糊: 对输入的词进行模糊查询并自动补全
* Regex正则:满足正则表达式的搜索....

prefix参数描述
field推荐结果选取字段
size最大返回推荐数量
skip_duplicates是否去重(默认false)
fuzzy参数描述
fuzziness模糊音字 参考上方的Fuzzy Query中的详解
transpositions是否允许术语之间的位置交换,默认为ture
min_length输入的最小长度 默认为3
prefix_length前多少个字符必须完全满足

3) 查询语句及返回结果解析

# 通用格式
{
  "suggest" : {
    "my-suggestion" : {  #一个查询建议名称
      "text" : "tring out Elasticsearch",  #查询文本
      "term" : {  #种类 可以替换为phrase(phrase suggester)/prefix(complite suggester)/fuzzy.....
        "field" : "message"  #指定在哪个字段上获取建议词
      }
    }
  }
}
# term
{ 
  "suggest": {
    "my-suggestion": {
      "text": "lucne rock",
      "term": {
        "suggest_mode": "missing",
        "field": "body"
      }
    }
  }
}
# Phrase 
{
  "suggest": {
    "my-suggestion": {
      "text": "lucne and elasticsear rock",
      "phrase": {
        "field": "body",
        "highlight": {
          "pre_tag": "<em>",
          "post_tag": "</em>"
        }
      }
    }
  }
}
# completion 
POST blogs_completion/_search?pretty
{ "size": 0,
  "suggest": {
    "blog-suggest": {
      "prefix": "elastic i",
      "completion": {
        "field": "body"
      }
    }
  }
}


# 返回结果格式及解析
# 需要注意term suggester返回的结果为术语,而phrase返回的为一段话


# term返回结果解析
# 可以看到在options中返回结果集,text即为推荐的结果 score即为得分 frep为推荐词出现的词频
{
    "suggest":{
        "my_suggest1":[
            {
                "text":"curr",
                "offset":0,
                "length":4,
                "options":[
                    {
                        "text":"curry",
                        "score":0.75,
                        "freq":6
                    },
                    {
                        "text":"court",
                        "score":0.5,
                        "freq":1
                    }
                ]
            }
        ]
    }
}

# phrase返回结果解析
# 可以看到根据我们的文本进行短语的模糊搜索并给出一整句话!!这是需要注意的和term的区别
{
    "suggest":{
        "my_suggest1":[
            {
                "text":"curr is good",
                "offset":0,
                "length":12,
                "options":[
                    {
                        "text":"curry is good",
                        "score":0.007225802
                    },
                    {
                        "text":"court is good",
                        "score":0.0033184804
                    }
                ]
            }
        ]
    }
}

4) Java SDK

SearchRequest request = new SearchRequest("test_index");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // 内层的term以及参数  还有text给定
        TermSuggestionBuilder termSug = SuggestBuilders.termSuggestion("content").text("查询文本").suggestMode(TermSuggestionBuilder.SuggestMode.ALWAYS).size(10);
        // 外层suggest
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        suggestBuilder.addSuggestion("my_suggest", termSug);


        // 给入suggest到整个查询中
        searchSourceBuilder.suggest(suggestBuilder);
        request.source(searchSourceBuilder);

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值