分面数据问题完整分析.md 5.53 KB

分面数据问题完整分析报告

问题现象

前端显示的分面结果都是空的:

  • Category: 空
  • Color: 空
  • Size: 空
  • Material: 空

ES的聚合查询结果也是空的。

诊断结果分析

MySQL数据检查结果

  1. category_path字段

    • 总SPU数:11254
    • 有category_path的SPU:只有1个
    • 该值:593389466647815326,593389582007954165,593389582008019701(ID列表格式,逗号分隔)
  2. option表数据

    • 总option记录数:2658
    • 有option定义的SPU数量:886个
    • position=1, name='color': 885个SPU ✅
    • position=2, name='size': 885个SPU ✅
    • position=3, name='material': 885个SPU ✅
  3. SKU数据

    • 总SKU数:43109
    • 应该有option1/2/3值

ES数据检查结果

  1. category1_name字段

    • 总文档数:10000
    • 有category1_name的文档:只有1个
    • 该值:593389466647815326,593389582007954165,593389582008019701(ID列表格式)
  2. specifications字段

    • ES聚合查询显示有数据
      • specifications.color: Beige: 1226, Khaki: 1176, Red: 1168等
      • specifications.size: 1: 1234, 12: 1234等
      • specifications.material: 塑料英文包装: 17277等

问题根源

问题1:category1_name 几乎都为空 ✅ 已找到原因

原因

  1. MySQL的category_path字段几乎都是空的(只有1个,而且是ID列表格式)
  2. category_path为空时,代码会使用category字段作为备选(代码已修复)
  3. 但需要检查MySQL的category字段是否有值

数据流转

  • Excel "专辑名称" → 店匠系统 → MySQL categorycategory_path 字段
  • 如果Excel导入时"专辑名称"没有正确映射,或者category字段也为空,就会导致category1_name为空

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

ES聚合查询显示有数据,但前端显示为空,可能原因:

  1. 前端搜索时有查询条件

    • 如果有查询条件(如query="手机"),ES会先过滤文档
    • 过滤后的文档如果没有specifications数据,聚合结果就会为空
    • 但这不应该导致所有分面都为空
  2. 分面聚合构建问题

    • 前端请求:["category1_name", "specifications.color", "specifications.size", "specifications.material"]
    • ES构建的聚合名称:category1_name_facet, specifications_color_facet
    • 可能聚合构建或解析有问题
  3. tenant_id过滤问题

    • 如果搜索时tenant_id不匹配,可能导致没有匹配的文档

需要检查的关键点

1. MySQL的category字段是否有值

需要运行SQL查询

SELECT 
    COUNT(*) as total,
    COUNT(category) as has_category,
    COUNT(*) - COUNT(category) as null_category
FROM shoplazza_product_spu
WHERE tenant_id = 162 AND deleted = 0;

如果category字段也为空

  • 说明Excel导入时"专辑名称"字段没有正确映射到MySQL的category字段
  • 需要检查店匠系统的字段映射配置

2. SKU的option1/2/3字段是否有值

需要运行SQL查询

SELECT 
    COUNT(*) as total_skus,
    COUNT(option1) as has_option1,
    COUNT(option2) as has_option2,
    COUNT(option3) as has_option3
FROM shoplazza_product_sku
WHERE tenant_id = 162 AND deleted = 0;

3. 检查ES聚合查询

运行检查脚本

python scripts/check_es_data.py --tenant-id 162

查看:

  • 是否有category1_name数据
  • specifications聚合是否有数据

解决方案

方案1:修复category1_name字段生成(代码已修复)

已修复的代码indexer/spu_transformer.py第241-259行):

  • 如果category_path为空,使用category字段作为备选
  • category字段解析多级分类

但需要确保

  1. MySQL的category字段有值
  2. 重新导入数据到ES

方案2:检查并修复MySQL数据

如果MySQL的category字段也为空:

  1. 检查Excel导入映射

    • 确认"专辑名称"字段是否正确映射到MySQL的category字段
    • 如果不正确,需要修复映射或重新导入
  2. 如果category字段有值但category1_name仍为空

    • 说明数据导入时使用的是旧代码
    • 需要重新导入数据到ES

方案3:验证specifications分面查询

虽然ES聚合查询显示有数据,但需要验证:

  1. 检查前端搜索请求

    • 确认分面请求是否正确发送
    • 确认tenant_id是否正确
  2. 检查ES聚合结果解析

    • 确认format_facets函数是否正确解析specifications分面
    • 确认字段名匹配是否正确(specifications.color vs specifications_color_facet

立即执行的操作

步骤1:检查MySQL的category字段

更新诊断脚本,添加category字段检查:

# 需要手动运行SQL或更新诊断脚本

步骤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

关键发现

  1. specifications数据是存在的:ES聚合查询能正常返回color/size/material的分面数据
  2. category1_name几乎都是空的:这是因为category_path为空,需要从category字段生成
  3. 需要重新导入数据:修复代码后,需要重新导入数据到ES才能生效