elasticsearch7.x+---搜索建议设计与实现

一、前言

  在7.0+版本中es官方贴心的为我们提供了一个新的字段类型search_as_you_type 来帮我实现开箱即用的搜索建议功能,官方文档中提到它的工作原理是创建一系列子字段,这些子字段被分析为索引词,可以通过部分匹配整个索引文本值的查询进行有效匹配。在早之前官方也为我们提供了,suggests_completion、suggests_phrase、suggest_term等实现自动补全纠错等功能。但是suggest只能提供前缀搜索建议并且存储在内存中构建成本很高(磁盘成本远远低于内存成本这也是选择search_as_you_type的一个原因),可以仔细观察市面上如淘宝,京东,微博等电商都是只支持前缀索引。B站是个例外支持了中缀索引,因为我们的业务特点中缀索引比重更大所以放弃了suggester下面就不多赘述。感兴趣的朋友可以翻阅官方文档

https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-suggesters.html#completion-suggester

二、search_as_you_type 的原理

在这里插入图片描述
  需要注意的是es7以后的版本min_gram和max_gram的粒度默认是不大于1,也就是说分词是一个字符一个字符逐个分的。如果粒度需要大于1需要设置一下index.max_ngram_diff大于等于它们的差值,否则会报错。

  要想我们的搜索建议强大且高效其内在原理我们需要吃透,下面先直观的感受下search_as_you_type帮我们创建的子字段的效果。其实官方文档的效果已经很直观了https://www.elastic.co/guide/en/elasticsearch/reference/7.17/analysis-edgengram-tokenfilter.html

  ngram我个人理解为gram(克)为最小一个单位的意思,应用到es中对应这一个字符,即排列组合按最小单位分割默认一到两个字符就会看到下面的切分结果,ngram3也很好理解了只是多出一些如qui uic ick的三字符切分


在这里插入图片描述
  很好理解edge中文翻译过来就是边缘的意思,意味着edge_ngram只能从最左侧边缘位置开始分割


在这里插入图片描述

2.2 shingle 过滤器

  一个 shingle 过滤器在 token 级别执行此操作,而不是像ngrams 在字符级别。,因此如果你有文本 “foo bar baz” 并再次使用 in_shingle_size 为2且 max_shingle_size 为3,则你将生成以下 token:

foo, foo bar, foo bar baz, bar, bar baz, baz

  为什么仍然包含单 token 输出? 这是因为默认情况下,shingle 过滤器包含原始 token,因此原始标记生成令牌 foo,bar 和 baz,然后将其传递给 shingle token 过滤器,生成标记foo bar,foo bar baz 和 bar baz。 所有这些 token 组合在一起形成最终 token 流。 你可以通过将 output_unigrams 选项设置为 false 来禁用此行为,也即不需要最原始的 token:foo, bar 及 baz

  下一个清单显示了 shingle token 过滤器的示例; 请注意,min_shingle_size 选项必须大于或等于2。

PUT my_index
PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "shingle": {
          "type": "custom",
          "tokenizer": "ik_max_word",
          "filter": [
            "shingle-filter"
          ]
        }
      },
      "filter": {
        "shingle-filter": {
          "type": "shingle",
          "min_shingle_size": 2,
          "max_shingle_size": 3,
          "output_unigrams": false
        }
      }
    }
  }
}

在这里,我们定义了一个叫做 shingle-filter 的过滤器。最小的 shangle 大小是2,最大的 shingle 大小是3。同时我们设置 output_unigrams 为 false,这样最初的那些 token 将不被包含在最终的结果之中。

下面我们来做一个例子,看看显示的结果:

POST search_suggest_complete/_search
{
  "query" : {
    "match": {
      "sayt":{
        "query": "比克"
      }
    }
  }
}

下图是开发测试时候为了对比构建的index所以有很多没有意义字段自信忽略
在这里插入图片描述

三、自定义排序(如热点加权,广告加权等)

比我我们有特殊要求,要让给了广告费的产品或者是近期新产品排在前面该如何实现(需求,让守护地球的战士排在前面)。我们通过使用function_score加权,这里为了演示新增一个字段。如果检测到type字段为1就代表当前产品给了广告费我们需要将它向前推

GET /search_suggest_complete/_search
{
  "query": {
    "function_score": {
      "query": {
        "multi_match": {
          "query": "bike",
          "type": "bool_prefix",
          "fuzziness": 2,
          "operator": "and",
          "fields": [
            "sayt",
            "sayt._2gram",
            "sayt._3gram",
            "sayt._index_prefix"
          ]
        }
    },
    "functions": [
      {
        "filter": {
          "term": {
            "type": 1
          }
        },
        "weight": 2
      }
    ],
    "boost": 1,
    "score_mode": "sum"
  }
}
}

可以看到此时守护地球比克分数直接翻了一倍到达了搜索建议的最上方,类似需求都换汤不换药都可以采用function_score实现。一个简单的搜索建议大概就是这些,如需拼音搜索建议记得指定分析器中加入pingyin其它的慢慢探索吧。
在这里插入图片描述

elasticsearch-7.12.0-py2.py3-none-any.whl 是 Elasticsearch 的 Python 客户端库的一个安装文件。Elasticsearch 是一个开源的实时分布式搜索和分析引擎,用于处理大规模数据集。它提供了一个简单可扩展的 RESTful API 接口,允许用户进行高效的数据搜索、分析以及存储。 这个安装文件的命名规则是根据 Python 的支持版本以及可运行平台来命名的。-py2.py3 表示可以同时兼容 Python 2 和 Python 3 版本的代码。-none-any 表示它是一个纯 Python 代码的库,不依赖于特定的操作系统或平台。 通过安装 elasticsearch-7.12.0-py2.py3-none-any.whl,您可以轻松地在您的 Python 环境中使用 Elasticsearch。这个库提供了许多功能,包括连接到 Elasticsearch 实例、执行索引、搜索和分析操作,以及管理和维护 Elasticsearch 的集群和节点。您可以使用这个库来构建各种应用,如全文搜索引擎、实时日志分析等。 要安装 elasticsearch-7.12.0-py2.py3-none-any.whl,您可以使用 pip 工具,在命令行中运行以下命令: ``` pip install elasticsearch-7.12.0-py2.py3-none-any.whl ``` 安装成功后,您就可以在您的 Python 代码中导入 elasticsearch 模块,并开始使用 Elasticsearch 的功能了。 总结:elasticsearch-7.12.0-py2.py3-none-any.whl 是 Elasticsearch 的 Python 客户端库的安装文件,用于连接、操作和管理 Elasticsearch 实例。通过安装这个库,您可以在您的 Python 项目中轻松使用 Elasticsearch 的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值