<!-- 2bec2252-690d-478e-9ce8-bc9073ec23ae cee9ef6a-2da8-41b5-b37e-12464a8e129a -->
API响应格式优化与SPU索引重构
概述
重构搜索系统以支持:
- 外部接口友好的API响应格式(移除ES内部格式)
- SPU维度的索引结构(包含嵌套variants数组)
- 所有客户共用同一索引(使用tenant_id隔离)
- 配置简化(移除MySQL相关配置,只保留ES搜索配置)
- 创建base配置(店匠通用配置)和测试数据
Phase 1: 配置文件重构
1.1 创建BASE配置文件
文件: <code>config/schema/base/config.yaml</code> (NEW)
创建通用配置文件,所有使用店匠表的客户共用:
- 移除
mysql_config,main_table,extension_table - 移除字段配置中的
source_table,source_column - 固定索引名称:
search_products - SPU级别字段定义(包含嵌套variants)
- 必需字段:
tenant_id(KEYWORD, required) - 扁平化价格字段:
min_price,max_price,compare_at_price - 多语言字段:
title_zh,title_en,description_zh,description_en等 - 嵌套variants结构定义
注意:店匠的店铺都使用base配置,不需要单独配置。允许其他深度定制客户(如tenant1)有自己的配置。
1.2 更新配置加载器
文件: <code>config/config_loader.py</code>
修改:
- 移除
mysql_config,main_table,extension_table解析(设为可选,向后兼容) - 移除字段配置中的
source_table,source_column解析(设为可选) - 支持固定
es_index_name为search_products(base配置) - 添加
tenant_id字段验证(必需字段) - 支持嵌套字段配置(variants)
1.3 更新字段类型定义
文件: <code>config/field_types.py</code>
修改:
FieldConfig中的source_table,source_column设为可选(向后兼容)- 确保嵌套字段支持(nested fields)正常工作
- 添加扁平化价格字段类型支持
Phase 2: 索引结构重构(SPU维度)
2.1 更新Mapping生成器
文件: <code>indexer/mapping_generator.py</code>
修改:
- 生成SPU级别的mapping
- 添加
tenant_id字段(KEYWORD, required) - 添加嵌套
variants字段(nested type) - 添加扁平化价格字段(
min_price,max_price,compare_at_price) - 支持SPU级别字段映射
2.2 创建SPU数据转换器
文件: <code>indexer/spu_transformer.py</code> (NEW)
创建SPU数据转换器:
- 从MySQL读取SPU和SKU数据(
shoplazza_product_spu和shoplazza_product_sku表) - 按SPU聚合SKU数据为variants数组
- 计算扁平化价格字段(min_price, max_price, compare_at_price)
- 生成SPU级别的ES文档
- 注入
tenant_id字段
2.3 创建店匠数据导入脚本
文件: <code>scripts/ingest_shoplazza.py</code> (NEW)
创建店匠数据导入脚本:
- 从MySQL读取
shoplazza_product_spu和shoplazza_product_sku表 - 按
spu_id和tenant_id关联数据 - 使用SPU转换器转换数据
- 批量导入到ES索引
search_products - 支持
--tenant-id参数
Phase 3: API响应格式重构
3.1 更新响应模型
文件: <code>api/models.py</code>
修改 SearchResponse 模型:
- 将
hits改为results(List[ProductResult]) - 添加
ProductResult模型(包含product_id, title, variants, relevance_score等) - 添加
VariantResult模型(包含variant_id, title, price, sku等) - 保持
facets格式 - 添加
suggestions和related_searches字段(暂时返回空数组)
3.2 创建结果转换器
文件: <code>api/result_formatter.py</code> (NEW)
创建结果格式化器:
- 将ES返回的
_hits格式转换为外部接口格式 - 提取SPU级别字段
- 提取嵌套variants数组
- 计算
relevance_score(从_score转换,归一化到0-1) - 格式化facets结果
- 生成suggestions和related_searches(暂时返回空数组)
3.3 更新搜索器
文件: <code>search/searcher.py</code>
修改:
- 在搜索查询中添加
tenant_id过滤(必需,从请求参数或配置获取) - 更新结果处理逻辑,使用结果格式化器
- 移除ES内部格式字段(
_id,_score,_source) - 返回格式化的外部接口格式
3.4 更新API路由
文件: <code>api/routes/search.py</code>
修改:
- 添加
tenant_id参数(从请求头X-Tenant-ID或查询参数tenant_id获取) - 在搜索请求中添加
tenant_id过滤 - 使用结果格式化器格式化响应
- 返回新的响应格式
Phase 4: 测试数据生成
4.1 创建测试数据生成脚本
文件: <code>scripts/generate_test_data.py</code> (NEW)
创建测试数据生成脚本:
- 生成100条SPU测试数据
- 为每个SPU生成1-5个SKU变体
- 包含中文和英文标题
- 包含价格、库存、图片等字段
- 输出为MySQL INSERT语句或CSV文件
4.2 创建数据导入脚本
文件: <code>scripts/import_test_data.py</code> (NEW)
创建数据导入脚本:
- 连接MySQL数据库
- 导入测试数据到
shoplazza_product_spu和shoplazza_product_sku表 - 设置
tenant_id为base客户的ID(如 "base" 或 "1") - 验证数据导入结果
Phase 5: 测试脚本和文档
5.1 创建测试脚本
文件: <code>scripts/test_base.py</code> (NEW)
创建base配置测试脚本:
- 测试数据导入
- 测试搜索API
- 测试多语言搜索
- 测试facets聚合
- 验证响应格式(results格式,非_hits格式)
- 验证tenant_id过滤
5.2 创建说明文档
文件: <code>docs/BASE_CONFIG_GUIDE.md</code> (NEW)
创建base配置测试指南:
- 数据导入步骤
- 配置说明
- API测试示例
- 常见问题解答
Phase 6: 更新设计文档
6.1 更新设计文档
修改:
- 更新索引结构说明(SPU维度,所有客户共用
search_products索引) - 更新配置说明(移除MySQL相关配置,只保留ES搜索配置)
- 更新API响应格式说明(results格式,非_hits格式)
- 更新数据导入流程说明(Pipeline层决定数据源,配置不包含数据源信息)
- 添加base配置说明
关键修改点
- 索引结构:
- 索引名称:
search_products(所有客户共用) - 索引粒度:SPU级别
- 租户隔离:使用
tenant_id字段过滤 - 嵌套结构:
variants数组包含SKU数据
- 配置简化:
- 移除
mysql_config,main_table,extension_table(设为可选,向后兼容) - 移除字段配置中的
source_table,source_column(设为可选) - 只保留ES搜索相关配置
- API响应格式:
- 从
_hits,_source,_score改为results,product_id,title,relevance_score - 添加
variants数组 - 添加
suggestions和related_searches(暂时返回空数组)
- 数据导入:
- 从MySQL读取SPU和SKU数据(Pipeline层决定)
- 按SPU聚合SKU数据
- 生成SPU级别的ES文档
- 注入
tenant_id字段
- 配置架构:
- 配置文件只包含搜索引擎关注的内容
- 数据来源由Pipeline层(脚本/工具)决定
- 转换器类型由Pipeline选择,不由配置决定
- 配置文件不引入mysql到ES层次的东西
To-dos
- [ ] Create ResponseTransformer to convert ES hits to Shoplazza format (results, facets, suggestions, related_searches)
- [ ] Update API models: add VariantOption, ProductVariant, ProductResult, update SearchResponse with new format
- [ ] Update search route to use ResponseTransformer and return Shoplazza format
- [ ] Create script to generate 100 SPU+SKU test records for tenant2 in Shoplazza tables
- [ ] Create tenant2 config.yaml with search-only fields (no pipeline details)
- [ ] Create or update SPUDataTransformer to join SPU+SKU and create nested variants structure
- [ ] Create tenant2 ingestion script that loads from MySQL and uses SPU transformer
- [ ] Create test script and documentation for tenant2 setup and testing
- [ ] Update design document: SPU-level indexing, unified index, config separation, pipeline decisions