Blame view

docs/temporary/sku_image_src问题诊断报告.md 3.88 KB
a866b688   tangwang   翻译接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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
107
108
109
110
111
112
113
114
115
116
117
  # SKU image_src 字段为空问题诊断报告
  
  ## 问题描述
  
  返回结果的每条结果中,多款式字段 `skus` 下面每个 SKU 的 `image_src` 为空。
  
  ## 问题分析
  
  ### 1. ES 数据检查
  
  通过查询 ES 数据,发现:
  - ES 中确实有 `skus` 数据(不是空数组)
  - 但是 `skus` 数组中的每个 SKU 对象**都没有 `image_src` 字段**
  
  示例 ES 文档:
  ```json
  {
    "spu_id": "68238",
    "skus": [
      {
        "sku_id": "3568395",
        "price": 329.61,
        "compare_at_price": 485.65,
        "sku_code": "3468269",
        "stock": 57,
        "weight": 0.26,
        "weight_unit": "kg",
        "option1_value": "",
        "option2_value": "",
        "option3_value": ""
        // 注意:这里没有 image_src 字段
      }
    ]
  }
  ```
  
  ### 2. 代码逻辑检查
  
  `indexer/document_transformer.py` 的 `_transform_sku_row` 方法中(第558-560行),原有逻辑为:
  
  ```python
  # Image src
  if pd.notna(sku_row.get('image_src')):
      sku_data['image_src'] = str(sku_row['image_src'])
  ```
  
  **问题根源**
  - 只有当 MySQL 中的 `image_src` 字段**非空**时,才会将其添加到 `sku_data` 字典中
  - 如果 MySQL 中的 `image_src` 是 `NULL` 或空字符串,这个字段就**不会出现在返回的字典中**
  - 导致 ES 文档中缺少 `image_src` 字段
  - API 返回时,`sku_entry.get('image_src')` 返回 `None`,前端看到的就是空值
  
  ### 3. MySQL 数据情况
  
  根据代码逻辑推断:
  - MySQL 的 `shoplazza_product_sku` 表中,`image_src` 字段可能为 `NULL` 或空字符串
  - 这导致索引时该字段没有被写入 ES
  
  ## 解决方案
  
  ### 修复方案
  
  修改 `indexer/document_transformer.py` 中的 `_transform_sku_row` 方法,**始终包含 `image_src` 字段**,即使值为空也设置为 `None`
  
  ```python
  # Image src - always include this field, even if empty
  # This ensures the field is present in ES documents and API responses
  image_src = sku_row.get('image_src')
  if pd.notna(image_src) and str(image_src).strip():
      sku_data['image_src'] = str(image_src).strip()
  else:
      # Set to None (will be serialized as null in JSON) instead of omitting the field
      sku_data['image_src'] = None
  ```
  
  ### 修复效果
  
  修复后:
  1. **即使 MySQL 中 `image_src` 为 NULL 或空字符串**,ES 文档中也会包含该字段(值为 `null`
  2. API 返回时,前端可以明确知道该字段存在但值为空
  3. 符合 API 模型定义:`image_src: Optional[str] = Field(None, ...)`
  
  ## 问题分类
  
  **问题类型****本项目填充的问题**
  
  -**不是 MySQL 原始数据的问题**:MySQL 中 `image_src` 字段可能确实为 NULL,但这是正常的业务数据
  -**不是 ES 数据的问题**:ES mapping 中 `image_src` 字段定义正确
  -**是本项目填充的问题**:代码逻辑导致当 MySQL 中 `image_src` 为空时,该字段没有被写入 ES 文档
  
  ## 后续操作
  
  1. **重新索引数据**:修复代码后,需要重新索引数据才能生效
     ```bash
     # 重新索引指定租户的数据
     ./scripts/ingest.sh <tenant_id> true
     ```
  
  2. **验证修复**:重新索引后,查询 ES 验证 `image_src` 字段是否已包含:
     ```bash
     curl -u 'essa:4hOaLaf41y2VuI8y' -X GET 'http://localhost:9200/search_products/_search?pretty' \
       -H 'Content-Type: application/json' \
       -d '{
         "size": 1,
         "query": {"nested": {"path": "skus", "query": {"exists": {"field": "skus"}}}},
         "_source": ["spu_id", "skus"]
       }'
     ```
  
  3. **可选优化**:如果业务需要,可以考虑当 SKU 的 `image_src` 为空时,使用 SPU 的主图(`image_url`)作为默认值
  
  ## 相关文件
  
  - `indexer/document_transformer.py` - 已修复
  - `api/models.py` - `SkuResult.image_src: Optional[str]` - 模型定义正确
  - `api/result_formatter.py` - `image_src=sku_entry.get('image_src')` - 读取逻辑正确
  - `mappings/search_products.json` - `skus.image_src` mapping 定义正确