分面问题诊断和修复指南.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 几乎都为空 ❌

原因分析

  1. MySQL数据层面

    • category_path字段几乎都是空的(只有1个,且是ID列表格式)
    • 需要检查category字段是否有值
  2. 数据转换层面

    • 原代码只从category_path解析category1_name
    • 如果category_path为空,category1_name不会被设置
    • 已修复:如果category_path为空,使用category字段作为备选(spu_transformer.py第241-259行)
  3. Excel导入映射

    • Excel的"专辑名称"字段可能映射到MySQL的category字段
    • 需要确认映射关系

问题2:specifications分面查询无结果

奇怪现象

  • ES聚合查询(查询所有文档)显示有数据
  • 但前端显示为空

可能原因

  1. 前端搜索时有查询条件,过滤后没有匹配的文档
  2. 分面聚合构建或解析有问题
  3. 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 '专辑名称' → MySQL shoplazza_product_spu.categorycategory_path
  • Excel '款式1/2/3'(M行)→ MySQL shoplazza_product_option.name + position
  • Excel '款式1/2/3'(P行)→ MySQL shoplazza_product_sku.option1/2/3

当前情况

  • ✅ option表有数据:885个SPU有color/size/material选项名称
  • ❓ category字段:需要检查是否有值

3. MySQL → ES转换

代码逻辑indexer/spu_transformer.py):

  1. 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()
    
  2. 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文档是否正确
  • [ ] 验证分面查询是否能正常返回结果