# 分面数据问题诊断和修复指南 ## 问题现象 前端显示的分面结果都是空的: - 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.category` 或 `category_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行): ```python 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行): ```python # 从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字段 **运行更新后的诊断脚本**: ```bash 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 ... ``` **关键检查**: - `category`字段是否有值 - 如果有值,值的格式是什么(是否包含"/") **如果category字段也为空**: - 说明Excel导入时"专辑名称"没有正确映射到MySQL - 需要检查店匠系统的字段映射配置 ### 步骤2:重新导入数据到ES **修复代码后,必须重新导入数据才能生效**: ```bash python scripts/recreate_and_import.py \ --tenant-id 162 \ --db-host \ --db-database saas \ --db-username saas \ --db-password \ --es-host http://localhost:9200 ``` ### 步骤3:验证ES数据 **运行ES数据检查脚本**: ```bash python scripts/check_es_data.py --tenant-id 162 ``` **检查内容**: - `category1_name`字段是否有值 - `specifications`字段是否有数据 - 分面聚合查询是否有结果 ## 预期结果 修复后,ES文档应该包含: ```json { "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文档是否正确 - [ ] 验证分面查询是否能正常返回结果