# 分面数据问题修复总结 ## 问题现象 前端显示的分面结果都是空的: - Category: 空 - Color: 空 - Size: 空 - Material: 空 ES的聚合查询结果也是空的。 ## 问题分析 ### 数据流程 1. **数据生成**(csv_to_excel_multi_variant.py): - 生成Excel文件,包含"专辑名称"(分类)和"款式1/2/3"(属性名称和值) 2. **Excel导入店匠** → MySQL: - "专辑名称" → 可能映射到 `category` 或 `category_path` 字段 - "款式1/2/3"(M行)→ `shoplazza_product_option.name` - "款式1/2/3"(P行)→ `shoplazza_product_sku.option1/2/3` 3. **MySQL → ES转换**(spu_transformer.py): - `category1_name` 从 `category_path` 解析 - `specifications` 从 `option表.name` + `sku表.option1/2/3` 构建 ### 根本原因 1. **category1_name 为空**: - MySQL的`category_path`字段可能为空 - Excel的"专辑名称"可能被映射到`category`字段而不是`category_path` - 原代码只从`category_path`解析,如果为空则`category1_name`不会被设置 2. **specifications 为空**: - `shoplazza_product_option`表可能没有数据 - 或`name`字段值不是英文(不是"color"、"size"、"material") ## 已实施的修复 ### 修复1:支持从category字段生成category1_name **文件**: `indexer/spu_transformer.py` **修改内容**: - 如果`category_path`为空,使用`category`字段作为备选 - 从`category`字段解析多级分类(如果包含"/") - 如果`category`不包含"/",直接作为`category1_name` **代码位置**:第241-259行 ```python elif pd.notna(spu_row.get('category')): # 如果category_path为空,使用category字段作为category1_name的备选 category = str(spu_row['category']) doc['category_name_zh'] = category doc['category_name_en'] = None doc['category_name'] = category # 尝试从category字段解析多级分类 if '/' in category: path_parts = category.split('/') if len(path_parts) > 0: doc['category1_name'] = path_parts[0].strip() if len(path_parts) > 1: doc['category2_name'] = path_parts[1].strip() if len(path_parts) > 2: doc['category3_name'] = path_parts[2].strip() else: # 如果category不包含"/",直接作为category1_name doc['category1_name'] = category.strip() ``` ## 诊断工具 已创建诊断脚本:`scripts/check_data_source.py` **使用方法**: ```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 \ --db-port 3316 \ --db-database saas \ --db-username saas \ --db-password ``` **检查内容**: 1. SPU汇总信息 2. category_path 字段是否有值 3. option 表的 name 字段值 4. SKU 表的 option1/2/3 字段值 ## 下一步操作 ### 步骤1:运行诊断脚本检查MySQL数据 ```bash python scripts/check_data_source.py --tenant-id 162 --db-host ... ``` ### 步骤2:根据检查结果修复数据 #### 如果 option 表的 name 值不对: 检查option表的name字段值: ```sql SELECT DISTINCT name, position FROM shoplazza_product_option WHERE tenant_id = 162 AND deleted = 0 ORDER BY position; ``` 如果需要,更新为英文: - position=1 的 name 应该是 "color" - position=2 的 name 应该是 "size" - position=3 的 name 应该是 "material" ### 步骤3:重新导入数据到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 ``` ### 步骤4:验证ES数据 检查ES索引中的文档是否包含: - `category1_name` 字段 - `specifications` 字段(包含color、size、material) - `option1_name`、`option2_name`、`option3_name` 字段 ```bash curl -X GET "http://localhost:9200/search_products/_search?pretty" -H 'Content-Type: application/json' -d' { "query": { "term": { "tenant_id": "162" } }, "size": 1, "_source": ["spu_id", "title_zh", "category1_name", "specifications", "option1_name", "option2_name", "option3_name"] }' ``` ## 预期结果 修复后,ES文档应该包含: ```json { "spu_id": "123", "title_zh": "商品标题", "category1_name": "电子产品", "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" } ``` 前端分面应该能正常显示分类和属性值。