企业如何申请网站,做微商选择的哪个平台微平台网站,网站开发培训费,vs网站开发实例Elasticsearch里设计了4 种类别的 Suggester
Term Suggester#xff1a;词条建议器。对给输入的文本进进行分词#xff0c;为每个分词提供词项建议。Phrase Suggester#xff1a;短语建议器#xff0c;在term的基础上#xff0c;会考量多个term之间的关系Completion Sugg…Elasticsearch里设计了4 种类别的 Suggester
Term Suggester词条建议器。对给输入的文本进进行分词为每个分词提供词项建议。Phrase Suggester短语建议器在term的基础上会考量多个term之间的关系Completion Suggester它主要针对的应用场景就是Auto CompletionContext Suggester上下文建议器
Term Suggester
每个 token 挑选 options 里的词组合在一起返回给用户前端即可。
blogs 索引text 字段。
PUT /blogs/
{mappings: {tech: {properties: {body: {type: text}}}}
}Term suggester 查询使用 suggest 这种特殊的查询。
suggest_mode
missing 只有词典里找不到词才会为其提供相似的选项。popular仅提供在索引词典中出现的词语。只返回在更多的文档中出现的建议词always不管 token 是否存在于索引词典里都要给出相似项。
POST /blogs/_search
{ suggest: {// 自定义名称my-suggestion: {// query text: lucne rock,// 表示 term suggesterterm: {// 如果 query word 足够精准就不需要 sug 了也就是只会 sugword 不全匹配的。suggest_mode: missing,// sug 的字段field: body}}}
}两个term的相似性是如何判断的?
ES使用了一种叫做 Levenstein edit distance的算法其核心思想就是一个词改动多少个字符就可以和另外一个词一致。与编辑距离类似。
Phrase Suggester
Phrase suggester在Term suggester的基础上会考量多个term之间的关系比如是否同时出现在索引的原文里相邻程度以及词频等等。
POST /blogs/_search
{suggest: {my-suggestion: {text: lucne and elasticsear rock,phrase: {field: body,highlight: {pre_tag: em,post_tag: /em}}}}
}执行结果
suggest: {my-suggestion: [{text: lucne and elasticsear rock,offset: 0,length: 26,options: [{text: lucene and elasticsearch rock,highlighted: emlucene/em and emelasticsearch/em rock,score: 0.004993905},{text: lucne and elasticsearch rock,highlighted: lucne and emelasticsearch/em rock,score: 0.0033391973},{text: lucene and elasticsear rock,highlighted: emlucene/em and elasticsear rock,score: 0.0029183894}]}]}因为 lucene 和 elasticsearch 曾经在同一条原文里出现过同时替换 2 个 term 的可信度更高所以打分较高排在第一位返回
Phrase suggester 有相当多的参数用于控制匹配的模糊程度。
Completion Suggester
基于内存 FST 的数据结构只能进行前缀检索。
需要专门字段类型completion
创建索引
PUT music
{mappings: {song : {properties : {suggest : {type : completion},title : {type: keyword}}}}
}插入数据可以指定权重。
PUT music/song/1?refresh
{suggest : {input: [ Nevermind, Nirvana ],weight : 34}
}搜索在检索时 Query 也会经过 analyze 阶段也会讲 Query 中停用词剔除。
POST blogs_completion/_search?pretty
{ size: 0,suggest: {blog-suggest: {prefix: elastic i,completion: {field: body}}}
}值得注意的一点是 Completion Suggester 在索引原始数据的时候也要经过 analyze 阶段取决于选用的analyzer不同某些词可能会被 转换某些词可能 被去除这些会影响 FST 编码结果也会 影响查找匹配的效果。
比如english analyzer会剥离掉 stop word而 is 就是其中一个被剥离掉了
结果
suggest: {blog-suggest: [{text: elastic i,offset: 0,length: 9,options: [{text: Elastic is the company behind ELK stack,_index: blogs_completion,_type: tech,_id: AVrXFyn-cpYmMpGqDdcd,_score: 1,_source: {body: Elastic is the company behind ELK stack}}]}]}skip_duplicates是否应过滤掉重复的建议默认为false。
支持拼音
如果要支持拼音
下载拼音插件wget https://github.com/medcl/elasticsearch-analysis-pinyin/releases/download/v7.4.0/elasticsearch-analysis-pinyin-7.4.0.zip
当我们创建索引时可以自定义分词器通过指定映射去匹配自定义分词器
支持模糊搜索
fuzzy
POST music/_search?pretty
{suggest: {song-suggest: {prefix: nor,completion: {field: suggest,fuzzy: {fuzziness: 2}}}}
}fuziness 为1表示是针对每个词语而言的而不是总的错误的数值。
模糊性是拼写错误的简单解决方案但具有很高的 CPU 开销和非常低的精度。
支持正则
POST music/_search?pretty
{suggest: {song-suggest: {regex: n[ever|i]r,completion: {field: suggest}}}
}Context Suggester
completion suggester 是在索引中所有文档进行匹配有时我们希望在一个增加过滤条件以提高搜索的准确度。
有两种类型category 和geo
PUT place
{mappings: {shops : {properties : {suggest : {type : completion,contexts: [{ # 1name: place_type,type: category,path: cat},{ # 2name: location,type: geo,precision: 4}]}}}}
}类别上下文Category Context
插入数据这些 suggestions 将与 cafe 和 food 类别相关联。
PUT place/shops/1
{suggest: {input: [timmys, starbucks, dunkin donuts],contexts: {place_type: [cafe, food] ①}}
}查询suggestions可以按一个或多个类别进行过滤。 以下过滤了多个类别的suggestions
POST place/_suggest?pretty
{suggest : {prefix : tim,completion : {field : suggest,size: 10,contexts: {place_type: [ cafe, restaurants ]}}}
}注意当在查询时未提供类别时将考虑所有索引文档。 应避免在类别启用完成字段上没有类别的查询因为它会降低搜索性能。
Boost 类别提权
对某些类别的suggestions可以比其他类别更高。 以下内容按类别过滤suggestions并增加与某些类别相关联的suggestions
POST place/_suggest?pretty
{suggest : {prefix : tim,completion : {field : suggest,size: 10,contexts: {place_type: [ ①{ context : cafe },{ context : restaurants, boost: 2 }]}}}
}context要过滤/提升的类别的值这是强制性的。boost应该提高建议分数的因素通过将boost乘以建议权重来计算分数默认为1。prefix是否应该将类别实为前缀例如如果设置为true则可以通过指定类型的类别前缀来过滤type1type2等类别默认为false。
地理位置上下文
一个geo上下文允许我们将一个或多个地理位置或geohash与在索引时间的建议关联在查询时如果建议位于地理位置特定的距离内则可以过滤和提升建议。
在内部地位置被编码为具有指定精度的地理位置。
地理上下文可以利用suggestions被显式地设置或者经由路径参数从文档中的地理点字段索引类似于类别上下文。 将多个地理位置上下文与suggestion关联将对每个地理位置的suggestion建立索引。 以下对具有两个地理位置上下文的suggestion进行索引
插入数据
PUT place/shops/1
{suggest: {input: timmys,contexts: {location: [{lat: 43.6624803,lon: -79.3863353},{lat: 43.6624718,lon: -79.3873227}]}}
}查询
suggestions可以根据它们与一个或多个地理点的接近程度而被过滤和提升。 以下过滤suggestions落在由地理点的编码geohash表示的区域内
POST place/_suggest
{suggest : {prefix : tim,completion : {field : suggest,size: 10,contexts: {location: {lat: 43.662,lon: -79.380}}}}
}当指定在查询时具有较低精度的位置时将考虑落入该区域内的所有suggestions。 位于由geohash表示的区域内的suggestions也可以比其他suggestion更高如下所示
POST place/_suggest?pretty
{suggest : {prefix : tim,completion : {field : suggest,size: 10,contexts: {location: [ ①{lat: 43.6624803,lon: -79.3863353,precision: 2},{context: {lat: 43.6624803,lon: -79.3863353},boost: 2}]}}}
}上下文查询过滤的suggestions落在由43.662-79.380的geohash表示的地理位置精度为2下方的suggestions并提升落在43.6624803-79.3863353的geohash表示形式下的默认精度为6的suggestions乘以因子2。
总结
在用户刚开始输入的过程中使用 Completion Suggester 进行关键词前缀匹配、刚开始匹配项会比较多随着用户输入字符增多匹配项越来越少。如果用户输入比较精准可能 Completion Suggester 的结果已经够好用户已经可以看到理想的备选项了。如果 Completion Suggester 已经到了零匹配那么可以猜测是否用户有输入错误这时候可以尝试一下 Phrase Suggester。如果 Phrase Suggester没有找到任何 option开始尝试 Term Suggester。需要一个搜索词库/语料库不要和业务索引库在一起方便维护和升级语料库支持拼音插件
精准程度上( Precision )看 Completion Phrase Term 而召回率上( Recall )则反之。从性能上看Completion Suggester是最快的如果能满足业务需求只用 Completion Suggester 做前缀匹配是最理想的。 Phrase 和 Term 由于是做倒排索引的搜索相比较而言性能应该要低不少应尽量控制 Suggester 用到的索引的数据量最理想的状况是经过一定时间预热后索引可以全量 map 到内存。