Bootstrap

谷粒商城实战笔记-128-商城业务-商品上架-sku在es中存储模型分析-关键

一,Elasticsearch在谷粒商城中的应用

这一节的内容非常重要,讲述了ES在商城中如何使用,从大的方面来说,主要有两大场景:

  • 商城的商品检索
  • 系统日志检索

1,商城的商品检索

第一种检索:根据三级分类检索。

鼠标移到左侧的三级分类,右侧列出更详细的分类信息,点击其中一个分类,比如办公桌,前端页面会向后台发出请求,商品服务接受到请求后会从ES中根据分类检索到这个分类下的SPU,并返回给前端展示。
在这里插入图片描述

第二种检索:根据SKU标题检索。

如下图,输入关键词公主笔记本进行搜索,前端页面发出请求,后端接收到请求后,根据关键词在ES中进行全文搜索,并整理搜索到的结果的属性值,进行分类汇总,把整理过的属性值(对应下图第一部分)和搜索到的SPU返回给前端进行展示(对应下图第二部分)。

注意,第一部分是根据搜索结果的属性值动态分类汇总而来。

在这里插入图片描述

2,日志检索

有过较大项目微服务开发经验的同学,对日志检索应该非常熟悉。对于排查测试和开发环境中的问题来说,日志检索必不可少。

二,谷粒商城ES的商品索引mapping如何设计

1,商品索引product的mapping

执行如下请求,创建商品索引product。

PUT product
{
"mappings": {
"properties": {
"skuId": {
"type": "long"
},
"spuId": {
"type": "keyword"
},
"skuTitle": {
"type": "text",
"analyzer": "ik_smart"
},
"skuPrice": {
"type": "keyword"
},
"skuImg": {
"type": "keyword",
"index": false,
"doc_values": false
},
"saleCount": {
"type": "long"
},
"hasStock": {
"type": "boolean"
},
"hotScore": {
"type": "long"
},
"brandId": {
"type": "long"
},
"catalogId": {
"type": "long"
},
"brandName": {
"type": "keyword",
"index": false,
"doc_values": false
},
"brandImg": {
"type": "keyword",
"index": false,
"doc_values": false
},
"catalogName": {
"type": "keyword",
"index": false,
"doc_values": false
},
"attrs": {
"type": "nested",
"properties": {
"attrId": {
"type": "long"
},
"attrName": {
"type": "keyword",
"index": false,
"doc_values": false
},
"attrValue": {
"type": "keyword"
}
}
}
}
}
}

设计商品mapping结构时,有两种方案:

  • 第一种方案是每一个sku文档都冗余spu信息
  • 另一种方案是把spu信息单独保存,检索时通过spuId关联sku信息。

我们最终采用的是第一种方案,理论依据就是用空间换时间,追求检索的高效率。具体分析如下。

冗余 SPU 信息的原因

  1. 查询性能:

    • 直接在 SKU 文档中包含 SPU 的关键信息(如 spuId)可以避免在查询时进行额外的关联操作。
    • 这样做可以减少对其他索引或文档的访问,从而加快查询速度。
  2. 可扩展性:

    • 当 SKU 和 SPU 的数量都非常大时,减少索引之间的依赖关系可以提高系统的整体性能。
    • 如果 SPU 信息被频繁地用于 SKU 查询,那么将它们内联在 SKU 记录中可以简化查询逻辑。

第一种方案的优缺点:

优点:
  • 查询效率:直接从 SKU 文档获取所有所需信息,无需进行额外的关联查询。
  • 易于维护:简化了数据模型和查询逻辑。
缺点:
  • 存储开销:每个 SKU 都会携带完整的 SPU 信息,可能会增加存储空间的需求。
  • 数据更新:如果 SPU 信息发生变化,需要更新所有相关 SKU 的记录以保持一致性。

第二种方案(SPU 单独存储)的优缺点

优点:
  • 存储效率:避免了冗余数据,节省存储空间。
  • 数据管理:更容易管理和更新 SPU 数据,只需在一个地方更新即可。
缺点:
  • 查询复杂度:需要额外的关联查询来获取完整的 SPU 信息,这可能导致查询性能下降。

选择第一种方案的理由

  • 性能优先:如果你的应用程序需要非常快速的响应时间,并且查询 SKU 时经常需要 SPU 的相关信息,那么将 SPU 信息内联到 SKU 记录中可以显著提高性能。
  • 简单性:对于复杂的查询,内联 SPU 信息可以减少开发和维护的成本。

2,mapping设计核心点

这个映射定义中的几个核心点如下:

2.1 index: false

当一个字段设置为 index: false 时,意味着该字段不会被索引,因此无法进行基于该字段的搜索。例如,在这个映射中,skuImg, brandName, brandImg, catalogName, 和 attrs.attrName 字段都被设置为 index: false。这意味着这些字段将不参与全文检索,也无法通过这些字段进行过滤或排序。

2.2 doc_values: false

doc_values 是一个字段级别的设置,它控制是否存储该字段的值以便于排序、聚合或脚本使用。当 doc_values: false 时,表示该字段不会存储任何文档级别的值,也就意味着不能基于这些字段进行排序或聚合。

3. 唯一的全文检索属性

在这个映射中,唯一被标记为全文检索的属性是 skuTitle,其类型为 text 并且使用了 ik_smart 分词器。这意味着 skuTitle 字段支持全文检索功能,并且在搜索时会使用 ik_smart 分词器进行分词处理,以实现更智能的中文搜索结果。

4,总结

  1. index: false 的目的:

    • 减少存储开销:不索引这些字段可以节省存储空间。
    • 提高性能:不需要维护索引,可以提高写入性能。
    • 简化查询:不需要考虑这些字段在查询中的使用。
  2. doc_values: false 的目的:

    • 减少存储开销:不存储文档级别的值可以进一步减少存储空间的需求。
    • 提高性能:不需要维护文档级别的值,可以提高写入性能。
    • 限制使用场景:不能基于这些字段进行排序或聚合。
  3. 全文检索属性:

    • skuTitle 被设计成全文检索属性,允许用户基于产品标题进行搜索。
    • 使用 ik_smart 分词器,可以提供更精细的中文分词能力,从而提高搜索质量。

结合这些特点,可以推得出以下几点:

  • 设计意图:

    • 映射的设计倾向于优化性能,以空间换时间。
    • 重点放在了 skuTitle 上,因为这是用户最有可能用来搜索产品的字段。
    • 其他字段主要用于参考或显示用途,而不是作为查询条件。
  • 应用场景:

    • 适用于那些需要高效搜索的产品目录系统,其中产品标题是最主要的搜索依据。
    • 对于其他字段的查询需求较低。
;