MySQL到ES字段映射说明-业务版.md 18 KB

MySQL 到 Elasticsearch 字段映射说明(业务版)

1. 概述

本文档说明 Elasticsearch 中的商品文档(Document)的各个字段是如何从 MySQL 数据库中的相关表获取和转换的。

1.1 数据源表

  • SPU 表 (shoplazza_product_spu): 商品基本信息
  • SKU 表 (shoplazza_product_sku): 商品变体信息(多款式)
  • Option 表 (shoplazza_product_option): 选项名称定义(如:颜色、尺寸)
  • 类目表 (product_category): 类目信息(通过 SPU 表的 category_id 关联)

2. 基础字段映射

2.1 标识字段

ES 字段 数据来源表 表中字段 转换说明
tenant_id SPU 表 tenant_id 直接使用,转为字符串
spu_id SPU 表 id 直接使用,转为字符串

2.2 文本字段(多语言)

文本字段支持中英文双语,根据租户配置自动翻译。

ES 字段 数据来源表 表中字段 转换说明
title_zh SPU 表 title 如果主语言是中文,直接使用;否则翻译为中文
title_en SPU 表 title 如果主语言是英文,直接使用;否则翻译为英文
brief_zh SPU 表 brief 同上
brief_en SPU 表 brief 同上
description_zh SPU 表 description 同上
description_en SPU 表 description 同上
vendor_zh SPU 表 vendor 同上
vendor_en SPU 表 vendor 同上

翻译规则:

  • 根据租户配置的 primary_language 确定主语言
  • 如果配置了 translate_to_en=true,且主语言不是英文,则翻译为英文
  • 如果配置了 translate_to_zh=true,且主语言不是中文,则翻译为中文

2.3 标签字段

ES 字段 数据来源表 表中字段 转换说明
tags SPU 表 tags 逗号分隔的字符串 → 数组示例:"标签1,标签2"["标签1", "标签2"]

2.4 图片字段

ES 字段 数据来源表 表中字段 转换说明
image_url SPU 表 image_src 直接使用,如果 URL 不以 http 开头则添加 // 前缀

2.5 销量字段

ES 字段 数据来源表 表中字段 转换说明
sales SPU 表 fake_sales 转为整数,如果为空则为 0

2.6 时间字段

ES 字段 数据来源表 表中字段 转换说明
create_time SPU 表 create_time 转为 ISO 格式字符串(如:2024-01-01T00:00:00
update_time SPU 表 update_time 转为 ISO 格式字符串

3. 类别(Category)字段映射

3.1 类别数据来源

类别信息主要来自 SPU 表的以下字段:

  • category_path: 类目路径,逗号分隔的类目ID列表(如:"1,2,3"
  • category: 类目名称(备用字段)
  • category_id: 当前类目ID
  • category_level: 类目层级

3.2 类别映射流程

步骤 1:解析 category_path

从 SPU 表的 category_path 字段解析出类目ID列表:

category_path = "1,2,3"
→ category_ids = ["1", "2", "3"]

步骤 2:ID 转名称

通过预加载的类目映射表(从 SPU 表查询 category_idcategory 字段构建),将ID转换为名称:

映射表:{"1": "电子产品", "2": "手机", "3": "iPhone"}
category_ids = ["1", "2", "3"]
→ category_names = ["电子产品", "手机", "iPhone"]

步骤 3:构建 ES 字段

ES 字段 数据来源 转换说明
category_path_zh 类目名称列表 / 连接:"电子产品/手机/iPhone"
category1_name 类目名称列表[0] 一级类目:"电子产品"
category2_name 类目名称列表[1] 二级类目:"手机"
category3_name 类目名称列表[2] 三级类目:"iPhone"
category_id SPU 表 category_id 转为字符串
category_level SPU 表 category_level 转为整数

备用处理:

如果 category_path 为空,使用 category 字段作为备选:

  • 如果 category 包含 /,按 / 分割为多级类目
  • 否则,直接作为 category1_name

数据质量检查:

如果 category_path 中的类目ID在映射表中不存在,则不写入任何类目字段(视为没有类目)。


4. 多款式(SKU/Options)字段映射

4.1 SKU 嵌套结构

一个 SPU 可以有多个 SKU,每个 SKU 代表一个商品变体(如:红色-L码、蓝色-M码)。

ES 中的 skus 字段结构:

{
  "skus": [
    {
      "sku_id": "123",
      "price": 99.99,
      "compare_at_price": 129.99,
      "sku_code": "SKU001",
      "stock": 100,
      "weight": 0.5,
      "weight_unit": "kg",
      "option1_value": "红色",
      "option2_value": "L",
      "option3_value": "棉",
      "image_src": "https://..."
    }
  ]
}

4.2 SKU 字段映射

ES 字段 数据来源表 表中字段 转换说明
skus[].sku_id SKU 表 id 转为字符串
skus[].price SKU 表 price 转为浮点数
skus[].compare_at_price SKU 表 compare_at_price 转为浮点数
skus[].sku_code SKU 表 sku 转为字符串
skus[].stock SKU 表 inventory_quantity 转为整数
skus[].weight SKU 表 weight 转为浮点数
skus[].weight_unit SKU 表 weight_unit 转为字符串
skus[].image_src SKU 表 image_src 转为字符串
skus[].option1_value SKU 表 option1 转为字符串
skus[].option2_value SKU 表 option2 转为字符串
skus[].option3_value SKU 表 option3 转为字符串

4.3 选项名称字段

选项名称来自 Option 表,按 position 字段排序(1、2、3 对应 option1、option2、option3)。

ES 字段 数据来源表 表中字段 转换说明
option1_name Option 表 name (where position=1) 第一个选项的名称(如:"颜色")
option2_name Option 表 name (where position=2) 第二个选项的名称(如:"尺寸")
option3_name Option 表 name (where position=3) 第三个选项的名称(如:"材质")

查询逻辑:

SELECT position, name
FROM shoplazza_product_option
WHERE spu_id = ? AND deleted = 0
ORDER BY position

4.4 选项值字段

选项值来自所有 SKU 的 option1option2option3 字段,去重后形成列表。

ES 字段 数据来源表 表中字段 转换说明
option1_values SKU 表 option1 收集所有 SKU 的 option1 值,去重示例:["红色", "蓝色", "绿色"]
option2_values SKU 表 option2 收集所有 SKU 的 option2 值,去重示例:["S", "M", "L"]
option3_values SKU 表 option3 收集所有 SKU 的 option3 值,去重示例:["棉", "涤纶"]

转换逻辑:

遍历所有 SKU:
  - 收集 option1 值 → option1_values 列表
  - 收集 option2 值 → option2_values 列表
  - 收集 option3 值 → option3_values 列表
去重后写入 ES

注意: 只有配置在 searchable_option_dimensions 中的选项才会被索引。

4.5 规格(Specifications)字段

规格字段用于支持按规格过滤和分面搜索,将 SKU 的选项值结构化存储。

ES 中的 specifications 字段结构:

{
  "specifications": [
    {"sku_id": "123", "name": "颜色", "value": "红色"},
    {"sku_id": "123", "name": "尺寸", "value": "L"},
    {"sku_id": "124", "name": "颜色", "value": "蓝色"},
    {"sku_id": "124", "name": "尺寸", "value": "M"}
  ]
}

构建逻辑:

  1. 从 Option 表获取选项名称映射:

    position=1 → name="颜色"
    position=2 → name="尺寸"
    position=3 → name="材质"
    
  2. 遍历所有 SKU,为每个 SKU 的每个选项值构建规格记录:

    SKU.id=123, option1="红色", option2="L"
    → {"sku_id": "123", "name": "颜色", "value": "红色"}
    → {"sku_id": "123", "name": "尺寸", "value": "L"}
    
ES 字段 数据来源 转换说明
specifications[].sku_id SKU 表 id 转为字符串
specifications[].name Option 表 name(根据 position 匹配)
specifications[].value SKU 表 option1/2/3 转为字符串

4.6 价格聚合字段

从所有 SKU 的价格中计算聚合值。

ES 字段 数据来源 转换说明
min_price SKU 表 所有 SKU 的 price 最小值
max_price SKU 表 所有 SKU 的 price 最大值
compare_at_price SKU 表 所有 SKU 的 compare_at_price 最大值
sku_prices SKU 表 所有 SKU 的 price 数组示例:[99.99, 99.99, 129.99]

计算逻辑:

遍历所有 SKU:
  - 收集 price → prices 列表
  - 收集 compare_at_price → compare_prices 列表

min_price = min(prices)
max_price = max(prices)
compare_at_price = max(compare_prices)
sku_prices = prices 列表

4.7 库存和重量聚合字段

ES 字段 数据来源 转换说明
total_inventory SKU 表 所有 SKU 的 inventory_quantity 求和
sku_weights SKU 表 所有 SKU 的 weight 数组示例:[500, 500, 600]
sku_weight_units SKU 表 所有 SKU 的 weight_unit 去重后的列表示例:["kg"]

计算逻辑:

遍历所有 SKU:
  - 累加 inventory_quantity → total_inventory
  - 收集 weight → sku_weights 列表
  - 收集 weight_unit → sku_weight_units 列表

total_inventory = 所有 SKU 库存之和
sku_weights = 所有 SKU 重量数组
sku_weight_units = 去重后的重量单位列表

5. 向量字段映射

5.1 标题向量(title_embedding)

ES 字段 数据来源 转换说明
title_embedding SPU 表 title 使用文本编码器(BGE)将标题转换为 1024 维向量优先使用 title_en,如果没有则使用 title_zh

生成逻辑:

如果启用向量搜索:
  文本 = title_en 或 title_zh
  向量 = 文本编码器.encode(文本)
  title_embedding = 向量(1024 维浮点数组)

6. 完整字段映射表

6.1 字段来源汇总

ES 字段 数据来源表 表中字段 说明
基础字段
tenant_id SPU tenant_id 租户ID
spu_id SPU id 商品ID
title_zh/en SPU title 标题(多语言)
brief_zh/en SPU brief 简介(多语言)
description_zh/en SPU description 描述(多语言)
vendor_zh/en SPU vendor 品牌(多语言)
tags SPU tags 标签数组
image_url SPU image_src 主图URL
sales SPU fake_sales 销量
create_time SPU create_time 创建时间
update_time SPU update_time 更新时间
类别字段
category_path_zh SPU + 类目映射 category_path → 类目名称 类目路径
category1_name SPU + 类目映射 category_path → 类目名称[0] 一级类目
category2_name SPU + 类目映射 category_path → 类目名称[1] 二级类目
category3_name SPU + 类目映射 category_path → 类目名称[2] 三级类目
category_id SPU category_id 类目ID
category_level SPU category_level 类目层级
SKU 嵌套字段
skus[] SKU 多个字段 SKU 数组(见 4.2 节)
选项字段
option1_name Option name (position=1) 选项1名称
option2_name Option name (position=2) 选项2名称
option3_name Option name (position=3) 选项3名称
option1_values SKU option1 选项1值列表
option2_values SKU option2 选项2值列表
option3_values SKU option3 选项3值列表
规格字段
specifications[] SKU + Option option1/2/3 + name 规格数组
聚合字段
min_price SKU price 最低价格
max_price SKU price 最高价格
compare_at_price SKU compare_at_price 最高原价
sku_prices SKU price 所有价格数组
total_inventory SKU inventory_quantity 总库存
sku_weights SKU weight 所有重量数组
sku_weight_units SKU weight_unit 重量单位列表
向量字段
title_embedding SPU title 标题向量(1024维)

7. 数据查询示例

7.1 查询 SPU 数据

SELECT 
    id, tenant_id, title, brief, description, vendor,
    category, category_id, category_path, category_level,
    tags, image_src, fake_sales, create_time, update_time
FROM shoplazza_product_spu
WHERE tenant_id = ? AND id = ? AND deleted = 0

7.2 查询 SKU 数据

SELECT 
    id, spu_id, price, compare_at_price, sku,
    inventory_quantity, weight, weight_unit,
    option1, option2, option3, image_src
FROM shoplazza_product_sku
WHERE tenant_id = ? AND spu_id = ? AND deleted = 0

7.3 查询 Option 数据

SELECT 
    position, name
FROM shoplazza_product_option
WHERE tenant_id = ? AND spu_id = ? AND deleted = 0
ORDER BY position

7.4 查询类目映射

SELECT DISTINCT
    category_id, category
FROM shoplazza_product_spu
WHERE deleted = 0 AND category_id IS NOT NULL

8. ES 文档示例

{
  "tenant_id": "1",
  "spu_id": "12345",
  "title_zh": "iPhone 15 Pro Max",
  "title_en": "iPhone 15 Pro Max",
  "brief_zh": "最新款 iPhone",
  "brief_en": "Latest iPhone",
  "description_zh": "详细描述...",
  "description_en": "Detailed description...",
  "vendor_zh": "Apple",
  "vendor_en": "Apple",
  "tags": ["手机", "智能手机", "Apple"],
  "category_path_zh": "电子产品/手机/iPhone",
  "category1_name": "电子产品",
  "category2_name": "手机",
  "category3_name": "iPhone",
  "category_id": "3",
  "category_level": 3,
  "option1_name": "颜色",
  "option2_name": "存储容量",
  "option1_values": ["深空黑色", "原色钛金属", "白色钛金属"],
  "option2_values": ["256GB", "512GB", "1TB"],
  "image_url": "https://example.com/image.jpg",
  "sales": 1000,
  "min_price": 8999.0,
  "max_price": 12999.0,
  "compare_at_price": 12999.0,
  "sku_prices": [8999.0, 10999.0, 12999.0],
  "sku_weights": [221, 221, 221],
  "sku_weight_units": ["g"],
  "total_inventory": 500,
  "create_time": "2024-01-01T00:00:00",
  "update_time": "2024-01-15T10:30:00",
  "title_embedding": [0.123, 0.456, ...],
  "skus": [
    {
      "sku_id": "1001",
      "price": 8999.0,
      "compare_at_price": 9999.0,
      "sku_code": "IP15PM-256-BLK",
      "stock": 100,
      "weight": 221.0,
      "weight_unit": "g",
      "option1_value": "深空黑色",
      "option2_value": "256GB",
      "image_src": "https://example.com/sku1.jpg"
    }
  ],
  "specifications": [
    {"sku_id": "1001", "name": "颜色", "value": "深空黑色"},
    {"sku_id": "1001", "name": "存储容量", "value": "256GB"}
  ]
}

9. 关键映射关系总结

9.1 类别映射

SPU.category_path ("1,2,3")
  ↓ [解析ID列表]
category_ids ["1", "2", "3"]
  ↓ [通过映射表转换]
category_names ["电子产品", "手机", "iPhone"]
  ↓ [构建字段]
category_path_zh: "电子产品/手机/iPhone"
category1_name: "电子产品"
category2_name: "手机"
category3_name: "iPhone"

9.2 SKU 和选项映射

Option 表 (position=1, name="颜色")
  ↓
option1_name: "颜色"

SKU 表 (option1="红色", option1="蓝色")
  ↓ [收集所有值,去重]
option1_values: ["红色", "蓝色"]

SKU 表 + Option 表
  ↓ [组合构建]
specifications: [
  {name: "颜色", value: "红色", sku_id: "123"},
  {name: "颜色", value: "蓝色", sku_id: "124"}
]

9.3 价格聚合

SKU 表 (price: 99.99, 109.99, 129.99)
  ↓ [聚合计算]
min_price: 99.99
max_price: 129.99
sku_prices: [99.99, 109.99, 129.99]

附录:数据表字段对照

SPU 表主要字段

表字段 ES 字段 说明
id spu_id 商品ID
tenant_id tenant_id 租户ID
title title_zh/en 标题
brief brief_zh/en 简介
description description_zh/en 描述
vendor vendor_zh/en 品牌
tags tags 标签
category_path category_path_zh 类目路径
category_id category_id 类目ID
category_level category_level 类目层级
image_src image_url 主图
fake_sales sales 销量
create_time create_time 创建时间
update_time update_time 更新时间

SKU 表主要字段

表字段 ES 字段 说明
id skus[].sku_id SKU ID
price skus[].price, min_price, max_price, sku_prices 价格
compare_at_price skus[].compare_at_price, compare_at_price 原价
sku skus[].sku_code SKU编码
inventory_quantity skus[].stock, total_inventory 库存
weight skus[].weight, sku_weights 重量
weight_unit skus[].weight_unit, sku_weight_units 重量单位
option1 skus[].option1_value, option1_values, specifications[].value 选项1值
option2 skus[].option2_value, option2_values, specifications[].value 选项2值
option3 skus[].option3_value, option3_values, specifications[].value 选项3值
image_src skus[].image_src SKU图片

Option 表主要字段

表字段 ES 字段 说明
position - 位置(1/2/3)
name option1_name, option2_name, option3_name, specifications[].name 选项名称