菜单

搜索模块 (mall-search)

相关源文件

搜索模块使用 Elasticsearch 为电商系统提供商品搜索和推荐功能。该模块负责商品数据的索引、关键词搜索、结果过滤、商品推荐获取以及相关品牌、分类和属性信息的检索。

有关管理商品的 Admin API,请参阅 Admin 模块 (mall-admin)。有关与客户交互的 Portal API,请参阅 Portal 模块 (mall-portal)

1. 模块概述

mall-search 模块实现了一个全面的商品搜索系统,提供快速、准确、灵活的搜索能力。它充当前端应用程序和 Elasticsearch 搜索引擎之间的桥梁,提供关键词匹配、过滤、排序和推荐等高级搜索功能。

1.1 模块架构

来源

2. 领域模型

2.1 EsProduct

EsProduct 类是表示 Elasticsearch 索引中商品的 핵심 领域模型。

EsProduct 类使用了 Elasticsearch 特定的注解

  • @Document(indexName = "pms"):指定 Elasticsearch 中的索引名称
  • @Setting(shards = 1, replicas = 0):配置索引设置
  • 字段注解,例如用于文本分析的 @Field(analyzer = "ik_max_word", type = FieldType.Text)

关键可搜索文本字段使用 IK 分词器支持中文

  • name:商品名称
  • subTitle:商品副标题
  • keywords:用于搜索优化的关键词

来源

EsProductRelatedInfo 类存储与搜索结果相关的聚合信息,包括:

  • 品牌名称
  • 商品分类名称
  • 商品属性及其值

此模型用于提供分面搜索功能,允许用户按品牌、分类或特定商品属性过滤搜索结果。

来源

3. 数据访问层

3.1 Elasticsearch Repository

EsProductRepository 接口扩展了 Spring Data 的 ElasticsearchRepository,为 EsProduct 实体提供了标准的 CRUD 操作。它还定义了一个自定义方法用于搜索商品

Page<EsProduct> findByNameOrSubTitleOrKeywords(String name, String subTitle, String keywords, Pageable page)

此方法允许在商品名称、副标题和关键词字段上进行简单的关键词搜索。

来源

3.2 自定义 DAO

该模块使用自定义 DAO(EsProductDao)和 MyBatis 从 MySQL 数据库获取商品数据。相应的 XML Mapper 定义了一个 SQL 查询,该查询连接多个表以检索完整的商品信息,包括:

  • 来自 pms_product 的基本商品详情
  • 来自 pms_product_attribute_value 的商品属性值
  • 来自 pms_product_attribute 的属性元数据

来源

4. 服务层

服务层负责商品搜索和索引相关的业务逻辑。EsProductService 接口定义了几项操作:

方法描述
importAll()将所有商品从数据库导入 Elasticsearch
delete(Long id)从 Elasticsearch 索引中删除一个商品
create(Long id)在索引中创建或更新指定的商品
delete(List<Long> ids)批量从索引中删除商品
search(String keyword, Integer pageNum, Integer pageSize)简单的关键词搜索
search(String keyword, Long brandId, Long productCategoryId, Integer pageNum, Integer pageSize, Integer sort)带筛选和排序的高级搜索
recommend(Long id, Integer pageNum, Integer pageSize)根据商品 ID 推荐相关商品
searchRelatedInfo(String keyword)检索与搜索词相关的品牌、分类和属性

来源

5. 搜索实现细节

5.1 商品索引

搜索模块提供了几种管理商品索引的方法:

  1. 导入所有商品:

  2. 索引单个商品:

这些方法使用 EsProductDao 从 MySQL 数据库获取商品数据,然后使用 Spring Data 的 repository 将其存储在 Elasticsearch 中。

来源

5.2 商品搜索流程

来源

5.3 高级搜索功能

搜索实现包含几项高级功能:

5.3.1 带 Function Score Query 的加权搜索

对于关键词搜索,使用 Function Score Query 来提高不同字段匹配的 relevancy。

  • 商品名称:权重 10
  • 商品副标题:权重 5
  • 商品关键词:权重 2

这确保了在名称字段匹配关键词的商品比仅在副标题或关键词字段匹配的商品排名更高。

来源

5.3.2 灵活的排序选项

搜索支持多种排序选项:

  • 按相关性排序(默认)
  • 按新品排序(ID 降序)
  • 按销量排序(降序)
  • 按价格排序(升序或降序)

来源

5.4 商品推荐

商品推荐功能通过查找与参考商品属性相似的商品来工作。

  1. 从数据库检索参考商品
  2. 提取关键属性:名称、品牌 ID 和分类 ID
  3. 构建一个 Function Score Query,用于提升具有相似属性的商品的 relevancy
  4. 排除原始商品
  5. 返回推荐商品的分页列表

来源

搜索模块还可以使用 Elasticsearch 聚合功能,基于关键词搜索聚合相关信息(品牌、分类和属性)。

此功能支持分面搜索,允许用户按品牌、分类或属性值过滤结果。

来源

6. REST API 端点

EsProductController 暴露了以下 REST API 端点:

端点方法描述
/esProduct/importAllPOST将所有商品导入 Elasticsearch
/esProduct/delete/{id}GET从索引中删除一个商品
/esProduct/delete/batchPOST从索引中批量删除商品
/esProduct/create/{id}POST在索引中创建或更新一个商品
/esProduct/search/simpleGET执行简单的关键词搜索
/esProduct/searchGET执行带过滤和排序的高级搜索
/esProduct/recommend/{id}GET根据商品 ID 获取商品推荐
/esProduct/search/relateGET获取相关的品牌、分类和属性信息

6.1 搜索 API 参数

高级搜索 API(/esProduct/search)参数:

参数类型必填描述
keyword字符串搜索关键词
brandId长期按品牌 ID 过滤
productCategoryId长期按商品分类 ID 过滤
pageNum整型页码(默认:0)
pageSize整型每页大小(默认:5)
sort整型排序选项(0:相关性,1:最新,2:销量,3:价格低到高,4:价格高到低)

来源

7. 与 Elasticsearch 集成

该模块使用 Spring Data Elasticsearch 进行集成,利用了多项功能:

  1. 基于注解的映射:领域模型使用 @Document@Field@Setting 等注解定义 Elasticsearch 映射。
  2. Repository 模式EsProductRepository 接口扩展了 ElasticsearchRepository 以实现基本的 CRUD 操作。
  3. ElasticsearchRestTemplate:用于聚合和 Function Score Query 等高级操作。
  4. 原生查询构建器:使用 NativeSearchQueryBuilder 来构建复杂的 Elasticsearch 查询。

该模块的测试类(MallSearchApplicationTests)包含测试 Elasticsearch 连接和映射的方法。

来源

8. 总结

mall-search 模块为 mall 电商系统提供了使用 Elasticsearch 的全面搜索解决方案。主要功能包括:

  1. 商品索引:将商品数据从 MySQL 同步到 Elasticsearch。
  2. 搜索:多种搜索选项,支持过滤、排序和分页。
  3. 推荐:基于相似属性的商品推荐。
  4. 分面搜索:聚合和检索相关的搜索信息。

该模块遵循清晰的架构,具有独立的层次:

  • 表示 Elasticsearch 文档的领域模型。
  • 用于与 Elasticsearch 和 MySQL 交互的数据访问层。
  • 实现搜索业务逻辑的服务层。
  • 暴露 REST API 的控制器层。

该模块使用户能够快速找到相关商品,并通过提供推荐和分面搜索功能来增强整体购物体验。