分面问题诊断和修复指南.md
5.92 KB
分面数据问题诊断和修复指南
问题现象
前端显示的分面结果都是空的:
- Category: 空
- Color: 空
- Size: 空
- Material: 空
ES的聚合查询结果也是空的。
诊断结果分析
MySQL数据情况
| 字段/表 | 有数据的数量 | 说明 |
|---|---|---|
| 总SPU数 | 11254 | - |
| category_path有值 | 1个 | 该值是ID列表格式(不是路径格式) |
| category字段 | 需要检查 | 可能是空的 |
| option表记录 | 2658条 | 886个SPU有option定义 |
| position=1, name='color' | 885个SPU | ✅ 数量足够 |
| position=2, name='size' | 885个SPU | ✅ 数量足够 |
| position=3, name='material' | 885个SPU | ✅ 数量足够 |
| 总SKU数 | 43109 | option1/2/3字段需要检查 |
ES索引数据情况
| 字段 | 有数据的数量 | 说明 |
|---|---|---|
| 总文档数 | 10000 | - |
| category1_name有值 | 1个 | 该值是ID列表格式 ❌ |
| specifications聚合查询 | 有数据 | ✅ color/size/material都有数据 |
问题根源
问题1:category1_name 几乎都为空 ❌
原因分析:
MySQL数据层面:
category_path字段几乎都是空的(只有1个,且是ID列表格式)- 需要检查
category字段是否有值
数据转换层面:
- 原代码只从
category_path解析category1_name - 如果
category_path为空,category1_name不会被设置 - ✅ 已修复:如果
category_path为空,使用category字段作为备选(spu_transformer.py第241-259行)
- 原代码只从
Excel导入映射:
- Excel的"专辑名称"字段可能映射到MySQL的
category字段 - 需要确认映射关系
- Excel的"专辑名称"字段可能映射到MySQL的
问题2:specifications分面查询无结果
奇怪现象:
- ES聚合查询(查询所有文档)显示有数据
- 但前端显示为空
可能原因:
- 前端搜索时有查询条件,过滤后没有匹配的文档
- 分面聚合构建或解析有问题
- tenant_id不匹配
数据流程分析
1. Excel生成阶段
脚本:scripts/csv_to_excel_multi_variant.py
生成的数据:
'专辑名称': csv_data['categoryName']- 从CSV的categoryName字段读取'款式1': 'color'(M行主商品)- 选项名称'款式2': 'size'(M行主商品)- 选项名称'款式3': 'material'(M行主商品)- 选项名称'款式1': 'Red'(P行子款式)- 选项值(从COLORS列表随机选择)'款式2': '5'(P行子款式)- 选项值(1-30随机选择)'款式3': '塑料'(P行子款式)- 选项值(从商品标题提取)
2. Excel导入店匠 → MySQL
映射关系(需要确认):
- Excel
'专辑名称'→ MySQLshoplazza_product_spu.category或category_path - Excel
'款式1/2/3'(M行)→ MySQLshoplazza_product_option.name+position - Excel
'款式1/2/3'(P行)→ MySQLshoplazza_product_sku.option1/2/3
当前情况:
- ✅ option表有数据:885个SPU有color/size/material选项名称
- ❓ category字段:需要检查是否有值
3. MySQL → ES转换
代码逻辑(indexer/spu_transformer.py):
category1_name生成(第228-259行):
if pd.notna(spu_row.get('category_path')): # 从category_path解析 path_parts = category_path.split('/') doc['category1_name'] = path_parts[0].strip() elif pd.notna(spu_row.get('category')): # 从category字段解析(已修复) doc['category1_name'] = category.strip()specifications生成(第351-370行):
# 从option表获取name映射 option_name_map = {position: name} # 从SKU表获取option值 if pd.notna(sku_row.get('option1')) and 1 in option_name_map: specifications.append({ 'name': option_name_map[1], # 'color' 'value': str(sku_row['option1']) # 'Red' })
解决方案
步骤1:检查MySQL的category字段
运行更新后的诊断脚本:
cd /home/tw/SearchEngine
source /home/tw/miniconda3/etc/profile.d/conda.sh
conda activate searchengine
python scripts/check_data_source.py --tenant-id 162 --db-host <host> ...
关键检查:
category字段是否有值- 如果有值,值的格式是什么(是否包含"/")
如果category字段也为空:
- 说明Excel导入时"专辑名称"没有正确映射到MySQL
- 需要检查店匠系统的字段映射配置
步骤2:重新导入数据到ES
修复代码后,必须重新导入数据才能生效:
python scripts/recreate_and_import.py \
--tenant-id 162 \
--db-host <host> \
--db-database saas \
--db-username saas \
--db-password <password> \
--es-host http://localhost:9200
步骤3:验证ES数据
运行ES数据检查脚本:
python scripts/check_es_data.py --tenant-id 162
检查内容:
category1_name字段是否有值specifications字段是否有数据- 分面聚合查询是否有结果
预期结果
修复后,ES文档应该包含:
{
"spu_id": "123",
"title_zh": "商品标题",
"category1_name": "电子产品", // 从category字段生成
"specifications": [
{"sku_id": "456", "name": "color", "value": "Red"},
{"sku_id": "456", "name": "size", "value": "5"},
{"sku_id": "456", "name": "material", "value": "塑料"}
],
"option1_name": "color",
"option2_name": "size",
"option3_name": "material"
}
关键检查点
1. MySQL数据检查
- [ ]
category字段是否有值 - [ ]
category_path字段是否为空 - [ ]
option表的name字段是否是英文(color/size/material) - [ ] SKU表的
option1/2/3字段是否有值
2. ES数据检查
- [ ]
category1_name字段是否有值 - [ ]
specifications字段是否有数据 - [ ] 分面聚合查询是否有结果
3. 数据导入验证
- [ ] 重新导入数据后,检查ES文档是否正确
- [ ] 验证分面查询是否能正常返回结果