# 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 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 定义正确