基于Elasticsearch实现搜索建议

标签: Elasticsearch Elasticsearch 搜索建议 | 发表时间:2017-01-23 09:14 | 作者:
分享到:
出处:http://ginobefunny.com/

搜索建议是搜索的一个重要组成部分,一个搜索建议的实现通常需要考虑建议词的来源、匹配、排序、聚合、关联的文档数和拼写纠错等,本文介绍一个基于Elasticsearch实现的搜索建议。

问题描述

电商网站的搜索是最基础最重要的功能之一,搜索框上面的良好体验能为电商带来更高的收益,我们先来看看淘宝、京东、亚马逊网站的搜索建议。

在淘宝的搜索框输入【卫衣】时,下方的搜索建议包括建议词以及相关的标签:
淘宝的搜索建议

在京东的搜索框输入【卫衣】时,下方搜索建议右方显示建议词关联的商品数量:
京东的搜索建议

在亚马逊的搜索框输入【卫衣】时,搜索建议上部分能支持在特定的分类下进行搜索:
亚马逊的搜索建议

通过上述对比可以看出,不同的电商对于搜索建议的侧重点略有不同,但核心的问题包括:

  • 匹配:能够通过用户的输入进行前缀匹配;
  • 排序:根据建议词的优先级进行排序;
  • 聚合:能够根据建议词关联的商品进行聚合,比如聚合分类、聚合标签等;
  • 纠错:能够对用户的输入进行拼写纠错;

搜索建议实现

在我们的搜索建议实现里,主要考虑了建议词的来源、匹配、排序、关联的商品数量和拼写纠错。

SuggestionDiscovery

  • SuggestionDiscovery的职责是发现建议词;
  • 建议词的来源可以是商品的分类名称、品牌名称、商品标签、商品名称的高频词、热搜词,也可以是一些组合词,比如“分类 + 性别”和“分类 + 标签”,还可以是一些自定义添加的词;
  • 建议词维护的时候需要考虑去重,比如“卫衣男”和“卫衣 男”应该是相同的,“Nike”和“nike”也应该是相同的;
  • 由于建议词的来源通常比较稳定,所以执行的周期可以比较长一点,比如每周一次;

SuggestionCounter

  • SuggestionCounter的职责是获取建议词关联的商品数量,如果需要可以进行一些聚合操作,比如聚合分类和标签;
  • SuggestionCounter的实现的时候由于要真正地调用搜索接口,应该尽量避免对用户搜索的影响,比如在凌晨执行并且使用单线程调用;
  • 为了提升效率,应该使用Elasticsearch的Multi Search接口批量进行count,同时批量更新数据库里建议词的count值;
  • 由于SuggestionCounter是比较耗资源的,可以考虑延长执行的周期,但是这可能会带来count值与实际搜索时误差较大的问题,这个需要根据实际情况考虑;

SuggestionIndexRebuiler

  • SuggestionIndexRebuiler的职责是负责重建索引;
  • 考虑到用户的搜索习惯,可以使用 Multi-fields来给建议词增加多个分析器。比如对于【卫衣 套头】的建议词使用Multi-fields增加不分词字段、拼音分词字段、拼音首字母分词字段、IK分词字段,这样输入【weiyi】和【套头】都可以匹配到该建议词;
  • 重建索引时通过是通过bulk批量添加到临时索引中,然后通过别名来更新;
  • 重建索引的数据依赖于SuggestionCounter,因此其执行的周期应该与SuggestionCounter保持一致;

SuggestionService

  • SuggestionService是真正处于用户搜索建议的服务类;
  • 通常的实现是先到缓存中查询是否能匹配到缓存记录,如果能匹配到则直接返回;否则的话调用Elasticsearch的 Prefix Query进行搜索,由于我们在重建索引的时候定义了Multi-fields,在搜索的时候应该用boolQuery来处理;如果此时Elasticsearch返回不为空的结果数据,那么加入缓存并返回即可;
  POST /suggestion/_search
{
  "from" : 0,
  "size" : 10,
  "query" : {
    "bool" : {
      "must" : {
        "bool" : {
          "should" : [ {
            "prefix" : {
              "keyword" : "卫衣"
            }
          }, {
            "prefix" : {
              "keyword.keyword_ik" : "卫衣"
            }
          }, {
            "prefix" : {
              "keyword.keyword_pinyin" : "卫衣"
            }
          }, {
            "prefix" : {
              "keyword.keyword_first_py" : "卫衣"
            }
          } ]
        }
      },
      "filter" : {
        "range" : {
          "count" : {
            "from" : 5,
            "to" : null,
            "include_lower" : true,
            "include_upper" : true
          }
        }
      }
    }
  },
  "sort" : [ {
    "weight" : {
      "order" : "desc"
    }
  }, {
    "count" : {
      "order" : "desc"
    }
  } ]
}
  • 如果Elasticsearch返回的是空结果,此时应该需要增加拼写纠错的处理(拼写纠错也可以在调用Elasticsearch搜索的时候带上,但是通常情况下用户并没有拼写错误,所以建议还是在后面单独调用suggester);如果返回的suggest不为空,则根据新的词调用建议词服务;比如用户输入了【adidss】,调用Elasticsearch的suggester获取到的结果是【adidas】,则再根据adidas进行搜索建议词处理。
  POST /suggestion/_search
{
  "size" : 0,
  "suggest" : {
    "keyword_suggestion" : {
      "text" : "adidss",
      "term" : {
        "field" : "keyword",
        "size" : 1
      }
    }
  }
}
  • 关于排序:在我们的实现里面是通过weight和count进行排序的,weight目前只考虑了建议词的类型(比如分类 > 品牌 > 标签);

实现效果和后续改进

  • 通过上面的实现,我们已经能实现一个比较强大的搜索建议词了,实际的效果如下所示:

最终效果

  • 后续可以考虑的改进:参考亚马逊增加分类的聚合展示、增加用户个性化的处理支持更好的建议词排序、基于用户的搜索历史支持更好的建议词推荐;

参考资料

相关 [elasticsearch 搜索] 推荐:

[Elasticsearch] 分布式搜索

- - 编程语言 - ITeye博客
本文翻译自Elasticsearch官方指南的 Distributed Search Execution一章. 在继续之前,我们将绕一段路来谈谈在分布式环境中,搜索是如何执行的. 和在分布式文档存储(Distributed Document Store)中讨论的基本CRUD操作相比,这个过程会更加复杂一些.

ElasticSearch入门-搜索如此简单

- - ITeye博客
搜索引擎我也不是很熟悉,但是数据库还是比较了解. 可以把搜索理解为数据库的like功能的替代品. 第一、like的效率不行,在使用like时,一般都用不到索引,除非使用前缀匹配,才能用得上索引. 第二、like的不能做到完全的模糊匹配. 比如like '%化痰冲剂%'就不能把”化痰止咳冲剂“搜索出来.

Elasticsearch搜索类型(query type)详解

- - ITeye博客
欢迎发送邮件至 donlianli@126.com. 请支持原创 http://donlianli.iteye.com/blog/2094305. es在查询时,可以指定搜索类型为QUERY_THEN_FETCH,QUERY_AND_FEATCH,DFS_QUERY_THEN_FEATCH和DFS_QUERY_AND_FEATCH.

基于Elasticsearch实现搜索推荐

- - GinoBeFunny
在 基于Elasticsearch实现搜索建议一文中我们曾经介绍过如何基于Elasticsearch来实现搜索建议,而本文是在此基础上进一步优化搜索体验,在当搜索无结果或结果过少时提供推荐搜索词给用户. 在根据用户输入和筛选条件进行搜索后,有时返回的是无结果或者结果很少的情况,为了提升用户搜索体验,需要能够给用户推荐一些相关的搜索词,比如用户搜索【迪奥】时没有找到相关的商品,可以推荐搜索【香水】、【眼镜】等关键词.

基于Elasticsearch实现搜索建议

- - GinoBeFunny
搜索建议是搜索的一个重要组成部分,一个搜索建议的实现通常需要考虑建议词的来源、匹配、排序、聚合、关联的文档数和拼写纠错等,本文介绍一个基于Elasticsearch实现的搜索建议. 电商网站的搜索是最基础最重要的功能之一,搜索框上面的良好体验能为电商带来更高的收益,我们先来看看淘宝、京东、亚马逊网站的搜索建议.

【翻译】用 elasticsearch 和 elasticsearch 为数十亿次客户搜索提供服务

- - IT技术博客大学习
标签:   elasticsearch   elasticsearch   搜索.    原文地址: http://www.elasticsearch.org/blog/using-elasticsearch-and-logstash-to-serve-billions-of-searchable-events-for-customers/.

开源搜索引擎评估:lucene sphinx elasticsearch

- - 鲁塔弗的博客
lucene系,java开发,包括 solr和 elasticsearch. sphinx,c++开发,简单高性能. 搜索引擎程序这个名称不妥当,严格说来应该叫做 索引程序(indexing program),早期主要用来做中文全文搜索,但是随着互联网的深入普及,各家网站规模越来越大,索引程序在 优化网站架构上发挥了更大的作用: 替代mysql数据库 内置的索引.

使用elasticsearch+simple_flow搭建实时日志搜索系统

- - ITeye博客
    在实际的系统中,我们经常会进行分布式的系统部署,但是这样会导致一个问题,系统日志也被分散开了,导致根据日志进行错误定位不太方便,所以,利用simple_flow实时流的特点,再配合elasticsearch建立索引,搭配构建一个实时日志搜索系统.具体流程图如下:. 1.启动elasticsearch, 这个参考官方文档  http://www.elasticsearch.org/.

基于Nutch+Hadoop+Hbase+ElasticSearch的网络爬虫及搜索引擎

- - zzm
网络爬虫架构在Nutch+Hadoop之上,是一个典型的分布式离线批量处理架构,有非常优异的吞吐量和抓取性能并提供了大量的配置定制选项. 由于网络爬虫只负责网络资源的抓取,所以,需要一个分布式搜索引擎,用来对网络爬虫抓取到的网络资源进行实时的索引和搜索. 搜 索引擎架构在ElasticSearch之上,是一个典型的分布式在线实时交互查询架构,无单点故障,高伸缩、高可用.

elasticsearch RESTful搜索引擎-(java jest 使用[入门])

- - zzm
elasticsearch简称ES. 好吧下面我介绍下jest(第三方工具),个人认为还是非常不错的...想对ES用来更好,多多研究源代码吧...迟点,会写一些关于ES的源代码研究文章,现在暂时还是入门的阶段.哈..(不敢,不敢). 它是ES的java客户端,基于http restful.... jest是开源的....其他就不清楚了,看源代码吧..哈..