后端存储实战课
李玥
美团高级技术专家
44005 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 30 讲
结束语 (1讲)
后端存储实战课
15
15
1.0x
00:00/00:00
登录|注册

06 | 如何用Elasticsearch构建商品搜索系统?

实现搜索提示功能的思考
使用ES进行商品搜索
向ES中插入商品数据
创建商品索引的MAPPING
安装ES及中文分词插件
ES的数据结构
倒排索引的快速搜索原理
倒排索引的构建过程
倒排索引的作用
数据库不适合做搜索的原因
搜索速度与结果质量的关系
实现搜索的简单与复杂性
搜索功能的普遍性
思考题
在ES中构建商品的索引
倒排索引机制
搜索系统
如何用Elasticsearch构建商品搜索系统?

该思维导图由 AI 生成,仅供参考

你好,我是李玥。
搜索这个特性可以说是无处不在,现在很少有网站或者系统不提供搜索功能了,所以,即使你不是一个专业做搜索的程序员,也难免会遇到一些搜索相关的需求。搜索这个东西,表面上看功能很简单,就是一个搜索框,输入关键字,然后搜出来想要的内容就好了。
搜索背后的实现,可以非常简单,简单到什么程度呢?我们就用一个 SQL,LIKE 一下就能实现;也可以很复杂,复杂到什么程度呢?不说百度谷歌这种专业做搜索的公司,其他非专业做搜索的互联网大厂,搜索团队大多是千人规模,这里面不仅有程序员,还有算法工程师、业务专家等等。二者的区别也仅仅是,搜索速度的快慢以及搜出来的内容好坏而已。
今天这节课,我们就以电商中的商品搜索作为例子,来讲一下,如何用 ES(Elasticsearch) 来快速、低成本地构建一个体验还不错的搜索系统。

理解倒排索引机制

刚刚我们说了,既然我们的数据大多都是存在数据库里,用 SQL 的 LIKE 也能实现匹配,也能搜出结果,为什么还要专门做一套搜索系统呢?我先来和你分析一下,为什么数据库不适合做搜索。
搜索的核心需求是全文匹配,对于全文匹配,数据库的索引是根本派不上用场的,那只能全表扫描。全表扫描已经非常慢了,这还不算,还需要在每条记录上做全文匹配,也就是一个字一个字的比对,这个速度就更慢了。所以,使用数据来做搜索,性能上完全没法满足要求。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Elasticsearch是一款强大的搜索引擎,适用于构建商品搜索系统。本文深入解释了倒排索引机制,阐述了数据库不适合用于搜索的原因,并介绍了Elasticsearch是如何解决搜索问题的。倒排索引是Elasticsearch中用于支持快速全文搜索的特殊索引,通过对文本进行分词并构建倒排索引,实现了高效的搜索功能。相比于数据库全表扫描和模糊匹配的方式,Elasticsearch的倒排索引实现了更高效的搜索,提供了良好的搜索体验。文章通过实际例子和分析,深入浅出地介绍了Elasticsearch的搜索原理和性能优势。对于想要构建商品搜索系统的读者来说,是一篇值得阅读的技术文章。文章还介绍了如何在Elasticsearch中构建商品索引,以及如何使用Elasticsearch快速实现搜索提示功能。总之,Elasticsearch是一个支持全文搜索的分布式内存数据库,特别适合用于构建搜索系统,而倒排索引是其能够实现高效全文搜索的关键。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《后端存储实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(37)

  • 最新
  • 精选
  • 李玥
    置顶
    Hi,我是李玥。 还是在这里回顾一下上节课的思考题: 2PC也有一些改进版本,比如3PC、TCC这些,它们大体的思想和2PC是差不多的,解决了2PC的一些问题,但是也会带来新的问题,实现起来也更复杂,限于篇幅我们没法每个都详细地去讲解。在理解了2PC的基础上,课后请你自行去学习一下3PC和TCC,然后对比一下,2PC、3PC和TCC分别适用于什么样的业务场景? 谈一下我的理解: 3PC相比于2PC做了两个改进,一是事务执行器也增加了超时机制,避免我们课程中提到的因为协调者宕机,导致执行器长时间卡死的问题,另外,3PC在2PC之前增加一个询问阶段,这个阶段事务执行器可以去尝试锁定资源(但不等待),这样避免像2PC那样直接去锁定资源,而资源不可用的情况下,一直等待资源而卡住事务的情况。 TCC可以理解为业务层面的2PC(也有观点主张TCC和2PC是完全不同的,我个人建议没必要在这些概念上较真,理解并正确使用才是关键),TCC同样分为Try和Confirm/Cancel 两个阶段,在Try阶段锁定资源,但不执行任何更新操作,Confirm阶段来执行所有更新操作并提交,如果失败进入Cancel阶段。Cancel阶段就是收拾烂摊子,把Confirm阶段做的数据更新都改回去,把Try阶段锁定的资源都释放。相比于2PC,TCC可以不依赖于本地事务,但是Cancel阶段的业务逻辑比较难实现。
    2020-03-10
    2
    56
  • Geek_c76e2d
    因为用户每输入一个字都可能会发请求查询搜索框中的搜索推荐。所以搜索推荐的请求量远高于搜索框中的搜索。es针对这种情况提供了suggestion api,并提供的专门的数据结构应对搜索推荐,性能高于match,但它应用起来也有局限性,就是只能做前缀匹配。再结合pinyin分词器可以做到输入拼音字母就提示中文。如果想做非前缀匹配,可以考虑Ngram。不过Ngram有些复杂,需要开发者自定义分析器。比如有个网址www.geekbang.com,用户可能记不清具体网址了,只记得网址中有2个e,此时用户输入ee两个字母也是可以在搜索框提示出这个网址的。以上是我在工作中针对前缀搜索推荐和非前缀搜索推荐的实现方案。

    作者回复: 👍👍👍

    2020-03-10
    6
    188
  • 每天晒白牙
    老师,我刚刚问的那个问题,我这边找到了一个方案,但不知道是否是业界用的方案,还请老师指点一下 全文检索要把 title 的 type 设置为 text 前缀推荐要把 title 的 type 设置为 completion 想同时支持全文检索和前缀匹配推荐如何做? 用 fields mapping 文件如下 PUT sku { "mappings": { "properties": { "sku_id":{ "type": "long" }, "title":{ "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word", "fields": { "title_suggest":{ "type":"completion" } } } } } } 支持全文检索 GET sku/_search?pretty { "query": { "match": { "title": "苹果手机" } } } 支持前缀匹配 POST sku/_search?pretty { "size":0, "suggest": { "suggester": { "prefix": "烟台", "completion": { "field": "title.title_suggest" } } } }

    作者回复: 没毛病👍

    2020-03-15
    4
    30
  • 黄平
    老师,es除了做搜索,还有哪些业务场景可以使用呢?能简单列举下吗?

    作者回复: 另外一个常见的用法是,作为在线分析型数据库来使用,做一些海量数据的实时查询。

    2020-03-19
    4
    10
  • 大秦皇朝
    李sir我还想再问下,根据我们不同的业务,选分词插件有啥讲究没?虽有点跑题,但是能不能简单说下,感谢~

    作者回复: 我没有专业做过搜索,我的朋友孙健(https://github.com/ansjsun)老师,他是开源分词项目ansj(https://github.com/NLPchina/ansj_seg)的作者,建议你和他讨论一下这个问题。

    2020-03-11
    8
  • 呦呦鹿鸣
    李老师好,请问下ES在做深度分页查询时的场景下有什么好的方案么

    作者回复: 额……ES最不擅长的就是深分页了……所以,据我所知,没什么好的解决方案。

    2020-04-14
    3
    4
  • Jax
    老师您好,是否可以做一些电商这种海量数据下,后台管理系统存储方面的最佳实践。还有对于不同系统之间的数据同步,也希望得到一些比较好的实践方案或者工具。 以下是比较具体的点: 我在上家公司也是做电商系统的,不过我负责的是后台商品数据的维护系统。前台可以用各种缓存来提速,但是对于后台系统,该如何让系统变得比较快?尤其是后台管理系统往往会涉及大批量商品的价格,库存之类的更新,并且更新后业务团队希望能实时看到他们更新成功了,而且有不少更新的操作对丢数据的容忍度比较低,这种情况下缓存也很难做,所以想得到一些对于这种大批量数据后台管理系统的实践经验。 对于数据同步,主要是有的原始数据存储在传统数据库,而为了速度,会存储到一些no sql产品做缓存,但是我们在实践中,经常会有一些丢数据,或者未能及时同步的情况发生,希望能得到这方面的一些经验分享。

    作者回复: 你提的这些问题,我们在后面的课程中都会讲到。 比如,《11 | MySQL如何应对高并发(一):使用缓存保护MySQL》《17 | 大厂都是怎么做MySQL to Redis同步的?》这两节会讲怎么来更快更准确的更新缓存。 《19 | 跨系统实时同步数据,分布式事务是唯一的解决方案吗?》这节课会讲如何在异构数据库之间来实时同步数据。

    2020-03-10
    2
    4
  • 旅途
    老师 您说的二次查找是指在第一次的查找结果中继续查找吗

    作者回复: 是的

    2020-03-10
    2
    4
  • 王超
    老师,针对订单中心的表数据,业务库用mysql,同步到es做查询时,比如一个订单主表,关联5个子表,在es存的时候是以嵌套的形式存一个index,还是mysql一张表,对应es的一个index,然后维护父子关系?或者有更好的方案

    作者回复: 这个取决于ES里面的这份订单数据服务什么业务。 比如,ES里面最常用的查询操作是查订单关联的商品,那就把订单表和订单商品表做成一张宽表。

    2020-03-31
    2
    3
  • 郭刚
    用ES有两个问题,1.它不适合多索引关联,就像关系数据库的多表关联,那关系数据库多表关联查询的情况是不是建一张中间表,把中间表的数据导入到es 2.要做到准实时的要求,有没有好的方式

    作者回复: 其实我见到一些业务,用ES来作为在线分析的数据库,实时的进行多表联查,性能也还可以。虽然从数据结构上来说,像你说的不太适合干这个活儿。但所谓“一力降十会”,因为ES它是内存数据库,加上原生分布式,自带Map-Reduce光环,很多情况实际表现还是不错的。你可以尝试一下。

    2020-03-24
    2
收起评论
显示
设置
留言
37
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部