一、概念:
查询建议主要包括两部分:
1、拼写检查纠错建议:
2、搜索词自动补全:
二、分类:
Elasticsearch提供了4种查询建议:
1、Term(词元建议):
如果输入的文本是句子,该句子被拆成多个单词。如果在倒排索引中存在对应单词在Levenshtein距离的词元,就返回该词元作为查询建议。由于输入的是句子,所以每个查询建议返回的结果是句子中每个词的建议,是个数组。同时也可以定义多个查询建议。
查询:
GET http://$user:$passwd@$host:$port/$index/$type/_search
{
"suggest": {
"my-suggestion1": { //自定义查询建议名1
"text": "an rede appel",
"term": {
"field": "title"
}
},
"my-suggestion2": { //自定义查询建议名2
"text": "an yello apples",
"term": {
"field": "content"
}
}
}
}
参数 | 说明 |
---|---|
text | 搜索词,可以设置全局的,也可以设置单个建议器的搜索词 |
field | 指定建议词从哪个字段中来 |
analyzer | 分析搜索词所用的分析器,默认是field指定的字段所使用的查询分析器 |
size | 每个搜索词可返回的最多建议词个数 |
sort | score:先按相关性排序,再按频率排序,默认 frequency:先按频率排序,再按相关性排序 |
suggest_mode | missing:当搜索词不在索引中才会建议 popular:当索引中存在比搜索词词频更高的词时该词会被建议出来 always:无论如何都会提供建议 |
max_edits | 待选建议词距搜索词的Levenshtein距离,只能是1或2,默认为2 |
prefix_length | 必须匹配的最小前缀字符数才能成为候选建议,默认值为1 |
string_distance | 计算距离使用的算法:internal |
详情请参考:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/search-suggesters-term.html
2、Phrase(短语建议):
在Term(词元建议)的基础上,会考虑多个Term之间的关系,可以对短语提供建议,同时具有高亮功能。
查询:
GET http://$user:$passwd@$host:$port/$index/$type/_search
{
"suggest": {
"my-suggestion1": { //自定义查询建议名1
"text": "an rede appel",
"phrase": {
"field": "title"
}
},
"my-suggestion2": { //自定义查询建议名2
"text": "an yello apples",
"phrase": {
"field": "content"
}
}
}
}
3、Completion(补全建议):
用于当用户每输入一个字符时,都需要即时发送一次查询请求查找匹配项。在用户输入速度较快的情况下对后端响应速度要求比较苛刻,因此实现上它和前面两个Suggester采用了不同的数据结构,索引并非通过倒排来完成,而是将analyze过的数据编码成FST和索引一起存放。FST被装载在内存中,并且只支持前缀匹配查找。如果要使用补全建议,对应的字段类型必须定义为completion。
定义索引结构:
PUT http://$user:$passwd@$host:$port/$index
{
"mappings": {
"$type": {
"properties": {
"字段名": {
"type": "completion"
}
}
}
}
}
查询:
GET http://$user:$passwd@$host:$port/$index/$type/_search
{
"suggest": {
"my-suggestion1": {
"prefix": "n",
"completion": {
"field": "title",
"fuzzy": {
"fuzziness": 2
}
}
},
"my-suggestion2": {
"regex": "n[ever|i]r",
"completion": {
"field": "title"
}
}
}
}
4、Context(上下文建议):
用于当用户每输入一个字符时,都需要即时发送一次查询请求来查找匹配项,而在查询时只在上下文指定的范围进行查询,而补全建议是查所有的文档。上下文建议又分为:
1>类别上下文:将一个或多个类别与所在字段的内容进行关联,上下文的type必须是category,这样在查询时就可以通过对应字段关联的类别进行过滤和提升。有两种使用方式:
①上下文中不指定path,上下文数据只能从上下文字段中指定。
定义索引结构:
PUT http://$user:$passwd@$host:$port/$index
{
"mappings": {
"$type": {
"properties": {
"book_name": {
"type": "completion",
"contexts": [ //可以定义多个上下文
{
"name": "birthland",
"type": "category"
}
]
}
}
}
}
}
索引数据:
POST http://$user:$passwd@$host:$port/$index/$type/1/_create
{
"book_name":{
"input":["哈姆雷特英文版","鲁滨逊漂流记英文版","呼啸山庄英文版"],
"contexts":{
"birthland":["英国","欧洲"]
}
}
}
查询:
GET http://$user:$passwd@$host:$port/$index/$type/_search
{
"suggest": {
"my-suggestion1": {
"prefix": "鲁",
"completion": {
"field": "book_name",
"size": 5,
"contexts": {
"birthland": [
"英国",
"欧洲"
]
}
}
},
"my-suggestion2": {
"prefix": "呼",
"completion": {
"field": "book_name",
"size": 5,
"contexts": {
"birthland": [
{"context":"中国","boost":2},
{"context":"亚洲"}
]
}
}
}
}
}
②上下文中指定path,上下文数据从path指定的字段上获取。官方文档是这么说的,但我验证不能成功。
2>地理上下文:将一个或多个geo位置或geohash与所在字段的内容进行关联,上下文的type必须是geo,这样在查询时就可以通过对应字段关联的geo进行过滤和提升。有两种使用方式:
①上下文中不指定path,上下文数据只能从上下文字段中指定。
定义索引结构:
PUT http://$user:$passwd@$host:$port/$index
{
"mappings": {
"$type": {
"properties": {
"book_name": {
"type": "completion",
"contexts": [ //可以定义多个上下文
{
"name": "location",
"type":"geo",
"precision": 4
}
]
}
}
}
}
}
索引数据:
POST http://$user:$passwd@$host:$port/$index/$type/1/_create
{
"book_name": {
"input": [
"哈姆雷特英文版",
"鲁滨逊漂流记英文版",
"呼啸山庄英文版"
],
"contexts": {
"location": [
{
"lat": 43.6624803,
"lon": -79.3863353
},
{
"lat": 43.6624718,
"lon": -79.3873327
}
]
}
}
}
查询:
GET http://$user:$passwd@$host:$port/$index/$type/_search
{
"suggest": {
"my-suggestion1": {
"prefix": "鲁",
"completion": {
"field": "book_name",
"size": 5,
"contexts": {
"location": {
"lat": 43.6625,
"lon": -79.38
}
}
}
},
"my-suggestion2": {
"prefix": "哈",
"completion": {
"field": "book_name",
"size": 5,
"contexts": {
"location": [
{
"lat": 43.6624803,
"lon": -79.3863353,
"precision": 2
},
{
"context": {
"lat": 43.6624803,
"lon": -79.3863353
},
"boost": 2
}
]
}
}
}
}
}
②上下文中指定path,上下文数据从path指定的字段上获取。官方文档是这么说的,但我验证不能成功。
详情请参考:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/search-suggesters.html