重生之我们在ES顶端相遇第9 章- 搜索框最常用的功能 - 搜索建议

文章目录

      • [1 前言](#1 前言)
      • [2 Term Suggester](#2 Term Suggester)
        • [2.1 基本介绍](#2.1 基本介绍)
        • [2.2 使用 demo](#2.2 使用 demo)
        • [2.3 常用参数](#2.3 常用参数)
          • [2.3.1 suggest_mode](#2.3.1 suggest_mode)
          • [2.3.2 max_edits](#2.3.2 max_edits)
          • [2.3.3 prefix_length](#2.3.3 prefix_length)
          • [2.3.4 min_word_length](#2.3.4 min_word_length)
      • [3 Completion Suggester](#3 Completion Suggester)
        • [3.1 基本描述](#3.1 基本描述)
        • [3.2 基本使用](#3.2 基本使用)
        • [3.3 查询参数](#3.3 查询参数)
          • [3.3.1 size](#3.3.1 size)
          • [3.3.2 skip_duplicates](#3.3.2 skip_duplicates)
          • [3.3.3 fuzzy queries(模糊查询)](#3.3.3 fuzzy queries(模糊查询))
          • [3.3.4 Regex queries(正则匹配)](#3.3.4 Regex queries(正则匹配))
      • [4 结语](#4 结语)

1 前言

在上章介绍完 bool 查询后。我们接下来介绍搜索最常被使用的功能:搜索建议、搜索纠错。

在 ES 中的 Suggesters API 中有以下 4 个 API

  • Term suggester
  • Phrase Suggester
  • Completion Suggester
  • Context Suggester
    本文,因章幅原因,以及开发中使用频率,只选择讲解 Term suggester, Context Suggester。更多内容请阅读 Suggesters API

2 Term Suggester

2.1 基本介绍

返回与输入的文本相似的 terms。在日常开发中,我们可以使用 term suggest 作为拼写纠错来使用。例如以下应用场景:

2.2 使用 demo

写入数据

复制代码
POST test6/_doc
{
  "intro": "apple fruits applz"
}
POST test6/_doc
{
  "intro": "grapes fruit grapz"
}
POST test6/_doc
{
  "intro": "banana fruit bannnn"
}

查询语法

复制代码
GET test6/_search
{
  "suggest": {         
    "my_suggest": {   ①
      "text": "banane",   ②
      "term": {
        "field": "intro"  ③
      }
    }
  }
}
  • ①:自定义的名词
  • ②:用户输入的文本
  • ③:被检索的字段
2.3 常用参数
2.3.1 suggest_mode

该参数有 3 个枚举值

  • missing:如果用户输入的文本存在于文档中,则不推荐。适用于拼写检查
  • popular:只推荐比用户输入的文本出现频率更高的 term。适用于推荐更流行的词
  • always:无论用户输入的文本是否存在于文档中,都推荐。

love apples 会被分词为 love, apples,这 2 个词都不存在于文档中。ES 文档中有 apple 这个词,就推荐了。

复制代码
GET test6/_search
{
  "suggest": {         
    "my_suggest": { 
      "text": "love apples",   
      "term": {
        "field": "intro",
        "suggest_mode": "missing"
      }
    }
  }
}

文档中存在 fruit, fruits。但是 fruit 出现的频率大于 fruits 因此 fruit 被推荐。

复制代码
GET test6/_search
{
  "suggest": {         
    "my_suggest": { 
      "text": "fruits",   
      "term": {
        "field": "intro",
         "suggest_mode": "popular"
      }
    }
  }
}

不管文档中存不存在,ES 都会推荐。

复制代码
GET test6/_search
{
  "suggest": {         
    "my_suggest": { 
      "text": "applz",  
      "term": {
        "field": "intro",
         "suggest_mode": "always"
      }
    }
  }
}
2.3.2 max_edits

最大编辑距离,可选值: 1~2,默认值 2。

什么是编辑距离,举个例子。

字符串 banane 变为 banana 的编辑距离为 1;
banzza 变为 banana 的编辑距离为 2;

即:需要修正多少个字符才能变为目标字符。

也就是说,使用 term suggest 至多允许错 2 个字母。

复制代码
GET test6/_search
{
  "suggest": {         
    "my_suggest": { 
      "text": "banane",   
      "term": {
        "field": "intro",
        "max_edits": 1
      }
    }
  }
}
2.3.3 prefix_length

在返回的相似文本中,最小的公共前缀长度。默认值 1。

例如,输入文本 janana,即使 ES 中存在 banana 的 term,banana 也不会被返回。因为 janana 的开头是 j, banana 的开头是 b,2 者没有公共前缀。

复制代码
GET test6/_search
{
  "suggest": {         
    "my_suggest": { 
      "text": "janana",   
      "term": {
        "field": "intro",
        "prefix_length": 0
      }
    }
  }
}
2.3.4 min_word_length

用户输入的文本,被分词为 term 后,term 的长度必须大于 n,term 才会被推荐。n 默认值为 4。

例如:用户输入 grap apz 会被分词为 grap, apz 2 个 term。apz 因为长度小于 4,因此不会被推荐。 grap 长度大于等于4,因此会被推荐。

复制代码
GET test6/_search
{
  "suggest": {         
    "my_suggest": { 
      "text": "grap apz",  
      "term": {
        "field": "intro"
        "string_distance": "ngram"
      }
    }
  }
}

接下来,我们修改下 min_word_length 的值。则被建议 apple, applz

复制代码
GET test6/_search
{
  "suggest": {         
    "my_suggest": { 
      "text": "app",
      "term": {
        "field": "intro",
        "min_word_length": 3,
        "suggest_mode": "missing",
        "string_distance": "ngram"
      }
    }
  }
}

需要注意:该 case 修改了 string_distance 参数。如果使用默认值 internal 则不会被建议。

PS:作者对算法不熟悉,因此不过多介绍 string_distance 可选的 5 个算法。更多内容见 term suggester 官网

3 Completion Suggester

3.1 基本描述

自动补全,或者搜索建议 API,一般常用在搜索框中。例如以下搜索场景。

该功能有非常快的响应速度,但是是以内存做为代价。下文是 ES 官网对其描述

The completion suggester provides auto-complete/search-as-you-type functionality. This is a navigational feature to guide users to relevant results as they are typing, improving search precision. It is not meant for spell correction or did-you-mean functionality like the term or phrase suggesters.

Ideally, auto-complete functionality should be as fast as a user types to provide instant feedback relevant to what a user has already typed in. Hence, completion suggester is optimized for speed. The suggester uses data structures that enable fast lookups, but are costly to build and are stored in-memory.

3.2 基本使用

设置 mapping

复制代码
PUT test7
{
  "mappings": {
    "properties": {
      "mysuggest": {
        "type": "completion"
      }
    }
  }
}

写入测试数据

复制代码
POST test7/_doc
{
  "mysuggest": "helloworld"
}
POST test7/_doc
{
  "mysuggest": "hello java"
}
POST test7/_doc
{
  "mysuggest": "hello"
}
POST test7/_doc
{
  "mysuggest": "hello"
}

查询

复制代码
GET test7/_search
{
  "suggest": {
    "mytest": {
      "prefix": "he",
      "completion": {
        "field": "mysuggest"
      }
    }
  } 
}
3.3 查询参数
3.3.1 size

返回结果数量

复制代码
GET test7/_search
{
  "suggest": {
    "mytest": {
      "prefix": "he",
      "completion": {
        "field": "mysuggest"
        "size": "1"
      }
    }
  } 
}
3.3.2 skip_duplicates

结果去重

复制代码
GET test7/_search
{
  "suggest": {
    "mytest": {
      "prefix": "he",
      "completion": {
        "field": "mysuggest",
        "size": 5,
        "skip_duplicates": true
      }
    }
  } 
}
3.3.3 fuzzy queries(模糊查询)

如果拼写有错误,也可以正常匹配结果

以下查询,是没有任何结果的,但是当我们使用 fuzzy queries 时,就允许有部分拼写错误

复制代码
# 没有任何结果
POST test7/_search
{
  "suggest": {
    "mytest": {
      "prefix": "hez",
      "completion": {
        "field": "mysuggest",
        "skip_duplicates": true,
        "size": 5
      }
    }
  }
}

# 使用 `fuzzy queries` 
POST test7/_search
{
  "suggest": {
    "mytest": {
      "prefix": "hez",
      "completion": {
        "field": "mysuggest",
        "fuzzy": {
          "fuzziness": "auto"
        },
        "skip_duplicates": true,
        "size": 5
      }
    }
  }
}

fuzziness 参数可选值有:auto, 0,1,2。该参数的作用类似编辑距离。意思为允许拼写中错多少个字母。

当我们首字母拼写错误时,也想要有建议,则可以配置 prefix_length 参数,该参数默认为 1,意思为:必须满足的最小的公共前缀长度

复制代码
POST test7/_search
{
  "suggest": {
    "mytest": {
      "prefix": "zhe",
      "completion": {
        "field": "mysuggest",
        "fuzzy": {
          "fuzziness": 2,
          "prefix_length": 0
        },
        "skip_duplicates": true,
        "size": 5
      }
    }
  }
}

当用户输入的文本长度为 1 时,我们也想要有建议,则可以修改 min_length 参数,该参数默认为 3,意思为:输入的文本长度最少为 3 时,才会建议

复制代码
POST test7/_search
{
  "suggest": {
    "mytest": {
      "prefix": "h",
      "completion": {
        "field": "mysuggest",
        "fuzzy": {
          "fuzziness": 2,
          "min_length":1
        },
        "skip_duplicates": true,
        "size": 5
      }
    }
  }
}
3.3.4 Regex queries(正则匹配)

实际开发比较少用,不过多介绍

复制代码
GET test7/_search
{
  "suggest": {
    "mytest": {
      "regex": "h.*o",
      "completion": {
        "field": "mysuggest",
        "skip_duplicates": true,
        "size": 5
      }
    }
  }
}

4 结语

我们已经将 ES 大部分主流的查询介绍完了,下一个篇章我们将介绍 ES 的分词器。

相关推荐
starandsea3 小时前
gitlab解决传过大文件后删除导致pack过大问题
大数据·elasticsearch·gitlab
大海绵啤酒肚5 小时前
EL(F)K日志分析系统
运维·elasticsearch·云计算
Elasticsearch15 小时前
如何在 AWS EC2 上安装和配置 Elasticsearch
elasticsearch
Elasticsearch18 小时前
Elastic AI agent builder 介绍(二)
elasticsearch
维尔切19 小时前
ELK日志系统部署与使用(Elasticsearch、Logstash、Kibana)
elk·elasticsearch·jenkins·kibana·logstash
帅帅梓1 天前
ELK es+logstash
大数据·elk·elasticsearch
Elasticsearch2 天前
Elastic Observability 中的 Streams 如何简化保留管理
elasticsearch
shan~~2 天前
ubuntu系统安装elasticsearch
ubuntu·elasticsearch·jenkins