API响应格式优化与SPU索引重构.2.md 8.52 KB

<!-- b5a93a00-49d7-4266-8dbf-3d3f708334ed 9b4e4bac-df19-49d4-a775-e5ec954010bd -->

API响应格式优化与SPU索引重构

概述

重构搜索系统以支持:

  1. 外部接口友好的API响应格式(移除ES内部格式)
  2. SPU维度的索引结构(包含嵌套variants数组)
  3. 所有客户共用同一索引(使用tenant_id隔离)
  4. 配置简化(移除MySQL相关配置,只保留ES搜索配置)
  5. 添加新客户(customer2)测试数据和配置

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结构定义

1.2 创建customer2配置文件

文件: <code>config/schema/customer2/config.yaml</code> (NEW)

基于BASE配置,为customer2创建配置文件:

  • 继承BASE配置结构
  • 定义customer2特定的字段和搜索域
  • 支持多语言(中文、英文)

1.3 更新配置加载器

文件: <code>config/config_loader.py</code>

修改:

  • 移除 mysql_config, main_table, extension_table 解析
  • 移除字段配置中的 source_table, source_column 解析
  • 固定 es_index_namesearch_products
  • 添加 tenant_id 字段验证(必需字段)
  • 支持嵌套字段配置(variants)

1.4 更新字段类型定义

文件: <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
  • 移除SKU级别的字段映射

2.2 创建SPU数据转换器

文件: <code>indexer/spu_transformer.py</code> (NEW)

创建SPU数据转换器:

  • 从MySQL读取SPU和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_spushoplazza_product_sku
  • spu_idtenant_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 格式
  • 添加 suggestionsrelated_searches 字段(暂时返回空数组)

3.2 创建结果转换器

文件: <code>api/result_formatter.py</code> (NEW)

创建结果格式化器:

  • 将ES返回的 _hits 格式转换为外部接口格式
  • 提取SPU级别字段
  • 提取嵌套variants数组
  • 计算 relevance_score(从 _score 转换)
  • 格式化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 参数(从请求头或查询参数获取)
  • 在搜索请求中添加 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_spushoplazza_product_sku
  • 设置 tenant_id 为customer2的ID
  • 验证数据导入结果

Phase 5: 测试脚本和文档

5.1 创建测试脚本

文件: <code>scripts/test_customer2.py</code> (NEW)

创建customer2测试脚本:

  • 测试数据导入
  • 测试搜索API
  • 测试多语言搜索
  • 测试facets聚合
  • 验证响应格式

5.2 创建说明文档

文件: <code>docs/CUSTOMER2_TEST_GUIDE.md</code> (NEW)

创建customer2测试指南:

  • 数据导入步骤
  • 配置说明
  • API测试示例
  • 常见问题解答

Phase 6: 更新设计文档

6.1 更新设计文档

文件: <code>设计文档.md</code>

修改:

  • 更新索引结构说明(SPU维度,所有客户共用)
  • 更新配置说明(移除MySQL相关配置)
  • 更新API响应格式说明
  • 更新数据导入流程说明
  • 添加customer2测试说明

关键修改点

  1. 索引结构
  • 索引名称:search_products(所有客户共用)
  • 索引粒度:SPU级别
  • 租户隔离:使用 tenant_id 字段过滤
  • 嵌套结构:variants 数组包含SKU数据
  1. 配置简化
  • 移除 mysql_config, main_table, extension_table
  • 移除字段配置中的 source_table, source_column
  • 只保留ES搜索相关配置
  1. API响应格式
  • _hits, _source, _score 改为 results, product_id, title, relevance_score
  • 添加 variants 数组
  • 添加 suggestionsrelated_searches(暂时返回空数组)
  1. 数据导入
  • 从MySQL读取SPU和SKU数据
  • 按SPU聚合SKU数据
  • 生成SPU级别的ES文档
  • 注入 tenant_id 字段

To-dos

  • [ ] 创建BASE配置文件(config/schema/base/config.yaml),移除MySQL相关配置,定义SPU级别字段和嵌套variants结构
  • [ ] 创建customer2配置文件(config/schema/customer2/config.yaml),基于BASE配置定义customer2特定字段
  • [ ] 更新配置加载器(config/config_loader.py),移除MySQL相关配置解析,支持嵌套字段和tenant_id验证
  • [ ] 更新字段类型定义(config/field_types.py),移除source_table和source_column,添加嵌套字段支持
  • [ ] 更新Mapping生成器(indexer/mapping_generator.py),生成SPU级别mapping,添加tenant_id和嵌套variants字段
  • [ ] 创建SPU数据转换器(indexer/spu_transformer.py),从MySQL读取SPU和SKU数据,按SPU聚合为variants数组
  • [ ] 创建店匠数据导入脚本(scripts/ingest_shoplazza.py),支持从MySQL导入SPU和SKU数据到ES
  • [ ] 更新响应模型(api/models.py),添加ProductResult和VariantResult模型,修改SearchResponse格式
  • [ ] 创建结果格式化器(api/result_formatter.py),将ES返回格式转换为外部接口友好格式
  • [ ] 更新搜索器(search/searcher.py),添加tenant_id过滤,使用结果格式化器格式化响应
  • [ ] 更新API路由(api/routes/search.py),添加tenant_id参数,返回新的响应格式
  • [ ] 创建测试数据生成脚本(scripts/generate_test_data.py),生成100条SPU测试数据
  • [ ] 创建数据导入脚本(scripts/import_test_data.py),导入测试数据到MySQL
  • [ ] 创建customer2测试脚本(scripts/test_customer2.py),测试数据导入和搜索API
  • [ ] 创建customer2测试指南(docs/CUSTOMER2_TEST_GUIDE.md),包含数据导入步骤和API测试示例
  • [ ] 更新设计文档(设计文档.md),更新索引结构、配置说明和API响应格式说明