MySQL到ES字段映射说明-业务版.md 20.9 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

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 文档示例

GET /search_products/_search
{
    "size": 1,
    "_source": "*",
    "query": {
      "bool": {
        "filter": [
          { "term": {"_id" : 74174} },
          { "term": { "tenant_id": "162" } }
        ]
      }
    }
  }

结果

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0,
    "hits": [
      {
        "_index": "search_products",
        "_id": "74174",
        "_score": 0,
        "_source": {
          "tenant_id": "162",
          "spu_id": "74174",
          "title.zh": "实色二阶碳纤维魔方 方形 2阶 塑料【英文包装】",
          "title.en": "Solid Color 2nd Order Carbon Fiber Rubik's Cube Square 2 Steps Plastic [English Packaging",
          "brief.zh": "实色二阶碳纤维魔方 方形 2阶 塑料【英文包装】",
          "brief.en": "Solid Color 2nd Order Carbon Fiber Rubik's Cube Square 2 Steps Plastic [English Packaging",
          "description.zh": "<p>实色二阶碳纤维魔方 方形 2阶 塑料【英文包装】</p>",
          "description.en": "<p>Solid Color 2nd Order Carbon Fiber Rubik's Cube Square 2 Steps Plastic [English Packaging]</p",
          "vendor.zh": "顺达",
          "vendor.en": "Shunda",
          "title_embedding": [
            -0.005125104915350676,
...
            0.018752742558717728
          ],
          "tags": [
            "魔方",
            "ShunDa"
          ],
          "category_path.zh": "玩具/汽车",
          "category_path.en": null,
          "category1_name": "玩具",
          "category2_name": "汽车",
          "category_name_text.zh": "汽车",
          "category_name_text.en": null,
          "category_name": "汽车",
          "category_id": "593389466647880832",
          "category_level": 2,
          "option1_name": "color",
          "option2_name": "size",
          "option3_name": "material",
          "image_url": "////img.staticdj.com/6eb4a98e2cb23af523da5456e424fc24.jpeg",
          "sales": 0,
          "skus": [
            {
              "sku_id": "3577878",
              "price": 346.13,
              "compare_at_price": 464.3,
              "sku_code": "2210777-Orange-30-塑料英文包装",
              "stock": 87,
              "weight": 1.99,
              "weight_unit": "kg",
              "option1_value": "Orange",
              "option2_value": "30",
              "option3_value": "塑料英文包装"
            },
            {
              "sku_id": "3577879",
              "price": 316.62,
              "compare_at_price": 466.27,
              "sku_code": "2210777-Orange-8-塑料英文包装",
              "stock": 41,
              "weight": 1.95,
              "weight_unit": "kg",
              "option1_value": "Orange",
              "option2_value": "8",
              "option3_value": "塑料英文包装"
            },
...
            {
              "sku_id": "3577941",
              "price": 380.03,
              "compare_at_price": 553.67,
              "sku_code": "2210777-Olive-2-塑料英文包装",
              "stock": 56,
              "weight": 2.78,
              "weight_unit": "kg",
              "option1_value": "Olive",
              "option2_value": "2",
              "option3_value": "塑料英文包装"
            }
          ],
          "specifications": [
            {
              "sku_id": "3577878",
              "name": "color",
              "value": "Orange"
            },
...
            {
              "sku_id": "3577941",
              "name": "material",
              "value": "塑料英文包装"
            }
          ],
          "option1_values": [
            "White",
            "Gold",
            "Violet",
            "Olive",
            "Turquoise",
            "Khaki",
            "Teal",
            "Orange"
          ],
          "option2_values": [
            "2",
            "30",
            "8",
            "1",
            "18",
            "27",
            "25",
            "29"
          ],
          "option3_values": [
            "塑料英文包装"
          ],
          "min_price": 262.92,
          "max_price": 389.18,
          "compare_at_price": 567.6,
          "sku_prices": [
            346.13,
...
            309.64,
            380.03
          ],
          "sku_weights": [
            1,
            1,
...
            2,
            2
          ],
          "sku_weight_units": [
            "kg"
          ],
          "total_inventory": 3269,
          "create_time": "2025-11-29T00:02:00",
          "update_time": "2025-12-20T00:01:41"
        }
      }
    ]
  }
}

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 选项名称