分面数据问题根源和解决方案.md
6.24 KB
分面数据问题根源和解决方案
📊 诊断结果总结
MySQL数据情况
- 总SPU数:11254
- category_path字段:只有1个有值(ID列表格式),11253个为空
- option表数据:
- 有option定义的SPU:886个
- position=1, name='color': 885个 ✅
- position=2, name='size': 885个 ✅
- position=3, name='material': 885个 ✅
ES索引数据情况
- 总文档数:10000
- category1_name字段:只有1个有值(ID列表格式),其他都是None ❌
- specifications聚合查询:有数据 ✅
- specifications.color: Beige: 1226, Khaki: 1176等
- specifications.size: 1: 1234, 12: 1234等
- specifications.material: 塑料英文包装: 17277等
🔍 问题根源
问题1:category1_name 几乎都为空
数据流分析:
Excel生成阶段(
csv_to_excel_multi_variant.py):- Excel字段:
'专辑名称': csv_data['categoryName'] - 从CSV的
categoryName字段读取,应该有值
- Excel字段:
Excel导入店匠 → MySQL:
- Excel的"专辑名称"字段 → 可能映射到MySQL的
category或category_path字段 - 问题:店匠系统可能将"专辑名称"映射到
category字段,而不是category_path - 诊断结果显示:
category_path几乎都是空的
- Excel的"专辑名称"字段 → 可能映射到MySQL的
MySQL → ES转换(
spu_transformer.py):- 原逻辑:只从
category_path解析category1_name - 如果
category_path为空,category1_name不会被设置 - 已修复:如果
category_path为空,使用category字段作为备选(第241-259行)
- 原逻辑:只从
关键检查点:
- MySQL的
category字段是否有值? - 如果
category字段也为空,说明Excel导入时"专辑名称"没有正确映射
问题2:specifications分面查询无结果
奇怪的现象:
- ES聚合查询显示有数据(Beige: 1226, Khaki: 1176等)
- 但前端显示为空
可能原因:
前端搜索时有查询条件:
- 如果搜索时添加了查询条件(如
query="手机"),ES会先过滤文档 - 过滤后的文档可能没有specifications数据,导致聚合结果为空
- 需要验证:不带查询条件的搜索,分面是否有数据
- 如果搜索时添加了查询条件(如
分面聚合构建或解析问题:
- 前端请求:
["category1_name", "specifications.color", "specifications.size", "specifications.material"] - ES构建的聚合名称:
specifications_color_facet - 前端解析时的字段匹配:
specifications.color - 需要验证:
format_facets函数是否正确匹配
- 前端请求:
tenant_id过滤问题:
- 如果tenant_id不匹配,会导致没有匹配的文档
✅ 已实施的修复
修复1:支持从category字段生成category1_name
文件:indexer/spu_transformer.py(第241-259行)
修改内容:
elif pd.notna(spu_row.get('category')):
# 如果category_path为空,使用category字段作为category1_name的备选
category = str(spu_row['category'])
# 从category字段解析多级分类
if '/' in category:
path_parts = category.split('/')
if len(path_parts) > 0:
doc['category1_name'] = path_parts[0].strip()
else:
# 直接作为category1_name
doc['category1_name'] = category.strip()
说明:如果MySQL的category字段有值,修复后的代码应该能生成category1_name
🔧 需要执行的操作
步骤1:检查MySQL的category字段
更新诊断脚本(已更新):scripts/check_data_source.py
运行检查:
python scripts/check_data_source.py --tenant-id 162 --db-host <host> ...
关键检查:
category字段是否有值- 如果有值,值的格式是什么(是否包含"/")
- 如果也为空,说明Excel导入映射有问题
步骤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字段是否有数据- 分面聚合查询是否有结果
📝 数据流程说明
Excel生成 → MySQL
Excel字段(csv_to_excel_multi_variant.py):
'专辑名称': csv_data['categoryName']- 分类信息'款式1': 'color'(M行)- 选项名称'款式2': 'size'(M行)- 选项名称'款式3': 'material'(M行)- 选项名称'款式1': 'Red'(P行)- 选项值'款式2': '5'(P行)- 选项值'款式3': '塑料'(P行)- 选项值
Excel导入店匠 → MySQL映射(需要确认):
'专辑名称'→shoplazza_product_spu.category或category_path'款式1/2/3'(M行)→shoplazza_product_option.name+position'款式1/2/3'(P行)→shoplazza_product_sku.option1/2/3
MySQL → ES转换
当前逻辑(spu_transformer.py):
category1_name生成:
- 优先从
category_path解析(第228-240行) - 如果
category_path为空,从category字段解析(第241-259行)✅ 已修复
- 优先从
specifications生成(第351-370行):
- 从
option表获取name(position → name映射) - 从
SKU表获取option1/2/3值 - 构建
specifications数组
- 从
关键点:
- 需要确保MySQL的
category字段有值 - 需要确保
option表有数据且name是英文(color/size/material) - 需要确保SKU的
option1/2/3字段有值
🎯 关键发现
- specifications数据是存在的:ES聚合查询能正常返回color/size/material的分面数据
- category1_name几乎都是空的:这是因为
category_path为空,需要从category字段生成 - 需要重新导入数据:修复代码后,需要重新导入数据到ES才能生效
🔄 下一步
- ✅ 代码已修复:支持从
category字段生成category1_name - ⏳ 需要检查MySQL数据:确认
category字段是否有值 - ⏳ 需要重新导入数据:将修复后的数据导入ES
- ⏳ 需要验证:检查ES数据是否正确,分面是否能正常显示