【云岚到家】-day05-4-项目迁移-商品搜索
- 2 项目迁移-商品搜索
- 2.1 迁移目标
- 2.2 能力基础
- 2.2.1 索引同步方案设计能力
- 2.2.2 Elasticsearch全文检索应用能力
- 2.3 需求分析
- 2.3.1 界面原型
- 2.3.2 功能列表梳理
- 2.4 系统设计
- 2.4.1 索引结构
- 2.4.2 索引同步方案
- 2.4.3 搜索自动补全
- 2.4.4 同义词处理
- 2.4.5 自定义词库
- 2.4.6 深度分页方案
2 项目迁移-商品搜索
2.1 迁移目标
通过服务搜索的学习,将所学技术迁移到商品搜索,通过迁移有能力理解商品搜索的需求和设计内容。
通过全文检索技术进行搜索的场景非常多,通过迁移有能力根据需求分析不同场景下的搜索技术方案。
商品搜索:电商网站通常需要让用户能够快速地搜索和浏览大量商品。通过全文检索,可以实现对商品名称、描述、品牌等信息的快速搜索。
文档搜索:在企业或团队内,文档管理系统中包含了大量的文档、报告、合同等文件。全文检索可以提供便捷的搜索功能,使用户能够快速找到需要的文件。
新闻搜索:在新闻门户网站中,用户经常需要搜索和浏览大量的新闻文章。全文检索可以提供高效的搜索体验,帮助用户找到感兴趣的新闻。
论坛搜索:论坛和社交媒体平台上的用户生成内容庞大而复杂。通过全文检索,可以帮助用户找到相关的帖子、评论或用户。
2.2 能力基础
2.2.1 索引同步方案设计能力
使用ES进行商品搜索首先需要将数据库中的商品信息同步到Elasticsearch中,需要具备索引同步方案设计的能力,具体如下:
根据搜索需求定义索引结构。
参考本项目服务搜索的方案使用Canal+MQ将商品信息同步到ES中。
2.2.2 Elasticsearch全文检索应用能力
商品搜索不仅需要通过关键字进行检索,还需要进行过滤、排序等。
基于ES提供的API完成商品信息的搜索、过滤、排序等功能。
2.3 需求分析
2.3.1 界面原型
2.3.2 功能列表梳理
模块 | 功能点 | 详细介绍 |
---|---|---|
关键字搜索 | 输入关键词来搜索商品,搜索结果高亮显示 | 用户可以输入关键词来搜索商品,系统应该能够根据关键词匹配商品的相关信息。 |
多条件过滤 | 根据商品分类、价格范围、品牌、颜色、尺寸等进行过滤 | 允许用户使用多种条件进行搜索,如商品分类、价格范围、品牌、颜色、尺寸等,以细化搜索结果。 |
搜索自动补全 | 输入关键字显示自动补全的关键字 | 主要涉及到对商品属性及属性值进行管理当用户输入关键词时,系统可以提供自动补全功能,帮助用户更快地找到相关商品。 |
搜索结果排序 | 根据价格、销量、评论数、综合指标进行排序 | 提供多种排序选项,让用户根据不同的标准对搜索结果进行排序,如价格、销量、评价等 |
同义词处理 | 同义词定义 | 处理同义词,确保用户能够使用不同的词汇描述相同的概念。 |
自定义词库 | 根据自定义词库进行分词 | 通常在以下情况下进行自定义词库,包括:领域专用术语、品牌、产品名词、地名、公司名等信息搜索时。 |
热门搜索推荐 | 显示热门搜索关键字 | 展示当前热门的搜索关键词,帮助用户发现流行的商品或主题。 |
2.4 系统设计
2.4.1 索引结构
商品检索goods结构如下:
{
"settings": {
"analysis": {
"filter": {
"synonym_filter": {
"type": "synonym",
"synonyms_path": "/usr/share/elasticsearch/data/goods_synonyms.txt"
}
},
"analyzer": {
"goods_analyzer": {
"tokenizer": "standard",
"filter": ["lowercase", "synonym_filter"]
}
}
}
},
"mappings": {
"properties": {
"id":{
"type": "long"
},
"name":{
"type": "text",
"analyzer": "goods_analyzer"
},
"name_c":{
"type": "completion",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"brand_id":{
"type": "long"
},
"category_id1":{
"type": "long"
},
"category_id2":{
"type": "long"
},
"category_id3":{
"type": "long"
},
"list_url":{
"type": "text"
},
"market_price":{
"type": "integer"
},
"stock":{
"type": "integer"
},
"evaluation_num":{
"type": "integer"
},
"composite_score":{
"type": "double"
},
"sale_num":{
"type": "integer"
},
"create_time":{
"type": "integer"
},
"express_ways":{
"type": "integer"
},
"attr_value_ids":{
"type": "long"
}
}
}
}
字段说明:
id:商品spu id
name:商品spu名称,支持同义词词库
name_c:商品spu名称,支持自动补全
brand_id:品牌id
category_id1:一级分类id
category_id2:二级分类id
category_id3:三级分类id
list_url:商品列表展示图片url
market_price:市场价格,单位分
stock:整个商品spu的库存数量
evaluation_num:评价数量
composite_score:综合评分
sale_num:销量
create_time:创建时间,使用时间戳,用来判断是否是新品
express_ways:物流方式,可以指定多种物流渠道
attr_value_ids:属性值id列表
同义词文件:
/usr/share/elasticsearch/data/goods_synonyms.txt
2.4.2 索引同步方案
采用本项目讲解的Canal+MQ方案。
2.4.3 搜索自动补全
效果:
elasticsearch提供了Completion Suggester查询来实现自动补全功能。这个查询会匹配以用户输入内容开头的词条并返回。为了提高补全查询的效率,对于文档中字段的类型有一些约束:参与补全查询的字段必须是completion类型。
2.4.1中创建了商品索引结构,其中对名称进行了补全和分词设计,可以通过elasticsearch的建议对分词进行自动补全查询,方式如下:
POST /goods/_search
{
"suggest":{
"name_suggest":{
"text":"搜索内容",
"completion":{
"field":"name_c",
"size": 10,
"skip_duplicates": true
}
}
}
}
检索出商品名称中和输入内容相关的单词,并且去掉重复内容
2.4.4 同义词处理
在2.4.1索引结构中设计了同义词词库过滤器,其中配置了商品同义词词库文件/usr/share/elasticsearch/data/goods_synonyms.txt,向该文件中写入同义词即可,每一行为一个同义词词组,词语之间使用逗号隔开,例如:
电话,手机
香皂,肥皂
配置文件中配置了两对同义词词组,分别是电话,手机;香皂,肥皂。
2.4.5 自定义词库
在ik分词器的目录中可以通过配置文件配置扩展词库:
/data/soft/es7.17.7/xzb/plugins/ik/config/IKAnalyzer.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict"></entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords"></entry>
<!--用户可以在这里配置远程扩展字典 -->
<!-- <entry key="remote_ext_dict">words_location</entry> -->
<!--用户可以在这里配置远程扩展停止词字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
在文件中添加自定义库存:
市面上也有一些其它的方式:
-
配置远程词库地址
在web服务器(nginx)创建自定义词库文件,配置远程访问词库的地址,找到配置文件elasticsearch/plugins/ik/config/,配置远程拓展字典访问地址,重启elasticsearch
-
基于数据库配置词库
首先从 GitHub获取IK分词器插件的源码,地址:https://github.com/medcl/elasticsearch-analysis-ik,添加数据库配置,修改代码将原本从配置文件中读取词库改为从数据库中读取词库,添加定时任务,定时同步数据库中的词库,编译词库源码,并进行安装。
2.4.6 深度分页方案
搜索请求通常跨越多个分片。每个分片必须加载其请求的命中数和内存中任何先前页面的命中数。对于深层页面或大量结果,这些操作可以显着增加内存和 CPU 使用率,导致性能下降或节点故障
当查询分页深度较大时,汇总数据过多,对内存和CPU会产生非常大的压力,因此elasticsearch会禁止from+ size 超过10000的请求。
针对深度分页,ES提供了两种解决方案,(https://www.elastic.co/guide/en/elasticsearch/reference/7.17/paginate-search-results.html#search-after)
- search after:分页时需要排序,原理是从上一次的排序值开始,查询下一页数据。官方推荐使用的方式。
- scroll滚动搜索:原理将排序后的文档id形成快照,保存在内存。官方已经不推荐使用。
search after实现:
查询第二页: