Blame view

docs/MySQL到ES字段映射说明-业务版.md 20.9 KB
768ad710   tangwang   MySQL到ES字段映射说明-业务...
1
2
3
4
5
6
7
8
9
10
11
12
13
  # 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 关联)
  
768ad710   tangwang   MySQL到ES字段映射说明-业务...
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  ---
  
  ## 2. 基础字段映射
  
  ### 2.1 标识字段
  
  | ES 字段 | 数据来源表 | 表中字段 | 转换说明 |
  |---------|-----------|----------|----------|
  | `tenant_id` | SPU 表 | `tenant_id` | 直接使用,转为字符串 |
  | `spu_id` | SPU 表 | `id` | 直接使用,转为字符串 |
  
  ### 2.2 文本字段(多语言)
  
  文本字段支持中英文双语,根据租户配置自动翻译。
  
  | ES 字段 | 数据来源表 | 表中字段 | 转换说明 |
  |---------|-----------|----------|----------|
d7d48f52   tangwang   改动(mapping + 灌入结构)
31
32
33
34
35
36
37
38
  | `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` | 同上 |
768ad710   tangwang   MySQL到ES字段映射说明-业务...
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  
  **翻译规则:**
  - 根据租户配置的 `primary_language` 确定主语言
  - 如果配置了 `translate_to_en=true`,且主语言不是英文,则翻译为英文
  - 如果配置了 `translate_to_zh=true`,且主语言不是中文,则翻译为中文
  
  ### 2.3 标签字段
  
  | ES 字段 | 数据来源表 | 表中字段 | 转换说明 |
  |---------|-----------|----------|----------|
  | `tags` | SPU 表 | `tags` | 逗号分隔的字符串 → 数组<br/>示例:`"标签1,标签2"` → `["标签1", "标签2"]` |
  
  ### 2.4 图片字段
  
  | ES 字段 | 数据来源表 | 表中字段 | 转换说明 |
  |---------|-----------|----------|----------|
2e48a32d   tangwang   doc
55
  | `image_url` | SPU 表 | `image_src` |  |
768ad710   tangwang   MySQL到ES字段映射说明-业务...
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  
  ### 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_id` 和 `category` 字段构建),将ID转换为名称:
  
  ```
  映射表:{"1": "电子产品", "2": "手机", "3": "iPhone"}
  category_ids = ["1", "2", "3"]
  → category_names = ["电子产品", "手机", "iPhone"]
  ```
  
  **步骤 3:构建 ES 字段**
  
  | ES 字段 | 数据来源 | 转换说明 |
  |---------|----------|----------|
d7d48f52   tangwang   改动(mapping + 灌入结构)
107
  | `category_path.zh` | 类目名称列表 | 用 `/` 连接:`"电子产品/手机/iPhone"` |
768ad710   tangwang   MySQL到ES字段映射说明-业务...
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
  | `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` 字段结构:**
  
  ```json
  {
    "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) | 第三个选项的名称(如:"材质") |
  
  **查询逻辑:**
  
  ```sql
  SELECT position, name
  FROM shoplazza_product_option
  WHERE spu_id = ? AND deleted = 0
  ORDER BY position
  ```
  
  ### 4.4 选项值字段
  
  选项值来自所有 SKU 的 `option1`、`option2`、`option3` 字段,去重后形成列表。
  
  | ES 字段 | 数据来源表 | 表中字段 | 转换说明 |
  |---------|-----------|----------|----------|
  | `option1_values` | SKU 表 | `option1` | 收集所有 SKU 的 option1 值,去重<br/>示例:`["红色", "蓝色", "绿色"]` |
  | `option2_values` | SKU 表 | `option2` | 收集所有 SKU 的 option2 值,去重<br/>示例:`["S", "M", "L"]` |
  | `option3_values` | SKU 表 | `option3` | 收集所有 SKU 的 option3 值,去重<br/>示例:`["棉", "涤纶"]` |
  
  **转换逻辑:**
  
  ```
  遍历所有 SKU:
    - 收集 option1 值 → option1_values 列表
    - 收集 option2 值 → option2_values 列表
    - 收集 option3 值 → option3_values 列表
  去重后写入 ES
  ```
  
  **注意:** 只有配置在 `searchable_option_dimensions` 中的选项才会被索引。
  
  ### 4.5 规格(Specifications)字段
  
  规格字段用于支持按规格过滤和分面搜索,将 SKU 的选项值结构化存储。
  
  **ES 中的 `specifications` 字段结构:**
  
  ```json
  {
    "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` 数组<br/>示例:`[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` 数组<br/>示例:`[500, 500, 600]` |
  | `sku_weight_units` | SKU 表 | 所有 SKU 的 `weight_unit` 去重后的列表<br/>示例:`["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 字段 | 数据来源 | 转换说明 |
  |---------|----------|----------|
d7d48f52   tangwang   改动(mapping + 灌入结构)
303
  | `title_embedding` | SPU 表 `title` | 使用文本编码器(BGE)将标题转换为 1024 维向量<br/>优先使用 `title.en`,如果没有则使用 `title.zh` |
768ad710   tangwang   MySQL到ES字段映射说明-业务...
304
305
306
307
308
  
  **生成逻辑:**
  
  ```
  如果启用向量搜索:
d7d48f52   tangwang   改动(mapping + 灌入结构)
309
    文本 = title.en 或 title.zh
768ad710   tangwang   MySQL到ES字段映射说明-业务...
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
    向量 = 文本编码器.encode(文本)
    title_embedding = 向量(1024 维浮点数组)
  ```
  
  ---
  
  ## 6. 完整字段映射表
  
  ### 6.1 字段来源汇总
  
  | ES 字段 | 数据来源表 | 表中字段 | 说明 |
  |---------|-----------|----------|------|
  | **基础字段** |
  | `tenant_id` | SPU | `tenant_id` | 租户ID |
  | `spu_id` | SPU | `id` | 商品ID |
d7d48f52   tangwang   改动(mapping + 灌入结构)
325
326
327
328
  | `title.zh/en` | SPU | `title` | 标题(多语言) |
  | `brief.zh/en` | SPU | `brief` | 简介(多语言) |
  | `description.zh/en` | SPU | `description` | 描述(多语言) |
  | `vendor.zh/en` | SPU | `vendor` | 品牌(多语言) |
768ad710   tangwang   MySQL到ES字段映射说明-业务...
329
330
331
332
333
334
  | `tags` | SPU | `tags` | 标签数组 |
  | `image_url` | SPU | `image_src` | 主图URL |
  | `sales` | SPU | `fake_sales` | 销量 |
  | `create_time` | SPU | `create_time` | 创建时间 |
  | `update_time` | SPU | `update_time` | 更新时间 |
  | **类别字段** |
d7d48f52   tangwang   改动(mapping + 灌入结构)
335
  | `category_path.zh` | SPU + 类目映射 | `category_path` → 类目名称 | 类目路径 |
768ad710   tangwang   MySQL到ES字段映射说明-业务...
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
  | `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 数据
  
  ```sql
  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 数据
  
  ```sql
  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 数据
  
  ```sql
  SELECT 
      position, name
  FROM shoplazza_product_option
  WHERE tenant_id = ? AND spu_id = ? AND deleted = 0
  ORDER BY position
  ```
  
  ### 7.4 查询类目映射
  
  ```sql
  SELECT DISTINCT
      category_id, category
  FROM shoplazza_product_spu
  WHERE deleted = 0 AND category_id IS NOT NULL
  ```
  
  ---
  
  ## 8. ES 文档示例
  
  ```json
f1505d1b   tangwang   up
413
  GET /search_products/_search
768ad710   tangwang   MySQL到ES字段映射说明-业务...
414
  {
f1505d1b   tangwang   up
415
416
417
418
419
420
421
422
423
      "size": 1,
      "_source": "*",
      "query": {
        "bool": {
          "filter": [
            { "term": {"_id" : 74174} },
            { "term": { "tenant_id": "162" } }
          ]
        }
768ad710   tangwang   MySQL到ES字段映射说明-业务...
424
      }
f1505d1b   tangwang   up
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
    }
  ```
  
  结果
  
  ```json
  {
    "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",
d7d48f52   tangwang   改动(mapping + 灌入结构)
454
455
456
457
458
459
460
461
            "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",
f1505d1b   tangwang   up
462
463
464
465
466
467
468
469
470
            "title_embedding": [
              -0.005125104915350676,
  ...
              0.018752742558717728
            ],
            "tags": [
              "魔方",
              "ShunDa"
            ],
d7d48f52   tangwang   改动(mapping + 灌入结构)
471
472
            "category_path.zh": "玩具/汽车",
            "category_path.en": null,
f1505d1b   tangwang   up
473
474
            "category1_name": "玩具",
            "category2_name": "汽车",
d7d48f52   tangwang   改动(mapping + 灌入结构)
475
476
            "category_name_text.zh": "汽车",
            "category_name_text.en": null,
f1505d1b   tangwang   up
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
            "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"
          }
        }
      ]
    }
768ad710   tangwang   MySQL到ES字段映射说明-业务...
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
  }
  ```
  
  ---
  
  ## 9. 关键映射关系总结
  
  ### 9.1 类别映射
  
  ```
  SPU.category_path ("1,2,3")
  [解析ID列表]
  category_ids ["1", "2", "3"]
  [通过映射表转换]
  category_names ["电子产品", "手机", "iPhone"]
  [构建字段]
d7d48f52   tangwang   改动(mapping + 灌入结构)
602
  category_path.zh: "电子产品/手机/iPhone"
768ad710   tangwang   MySQL到ES字段映射说明-业务...
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
  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 |
d7d48f52   tangwang   改动(mapping + 灌入结构)
647
648
649
650
  | `title` | `title.zh/en` | 标题 |
  | `brief` | `brief.zh/en` | 简介 |
  | `description` | `description.zh/en` | 描述 |
  | `vendor` | `vendor.zh/en` | 品牌 |
768ad710   tangwang   MySQL到ES字段映射说明-业务...
651
  | `tags` | `tags` | 标签 |
d7d48f52   tangwang   改动(mapping + 灌入结构)
652
  | `category_path` | `category_path.zh` | 类目路径 |
768ad710   tangwang   MySQL到ES字段映射说明-业务...
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
  | `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` | 选项名称 |