重生之我们在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 的分词器。

相关推荐
檀越剑指大厂7 分钟前
【Elasticsearch系列四】ELK Stack
大数据·elk·elasticsearch
2401_840192271 小时前
ELFK日志分析平台,架构和通信
elk·elasticsearch·架构
cyt涛13 小时前
搜索功能技术方案
mysql·elasticsearch·全文检索·canal·索引·数据同步·搜索
Lill_bin1 天前
ElasticSearch底层原理解析
大数据·分布式·elasticsearch·搜索引擎·zookeeper·云原生·jenkins
Flying_Fish_roe2 天前
Spring Boot- 配置中心问题
spring boot·后端·elasticsearch
SelectDB技术团队2 天前
查询性能提升 10 倍、存储空间节省 65%,Apache Doris 半结构化数据分析方案及典型场景
数据结构·数据仓库·elasticsearch·log4j·json
Chen_leilei2 天前
ES机制原理
大数据·elasticsearch·搜索引擎
西岭千秋雪_2 天前
谷粒商城のElasticsearch
java·大数据·服务器·spring boot·elasticsearch·搜索引擎
花晓木2 天前
python清除一个月以前的ES索引文档数据
开发语言·python·elasticsearch
好想有猫猫2 天前
【Git】常见命令(仅笔记)
linux·c++·笔记·git·elasticsearch