# Base Configuration Guide 店匠通用配置(Base Configuration)使用指南 ## 概述 Base配置是店匠(Shoplazza)通用配置,适用于所有使用店匠标准表的客户。该配置采用SPU级别的索引结构,所有客户共享同一个Elasticsearch索引(`search_products`),通过`tenant_id`字段实现数据隔离。 ## 核心特性 - **SPU级别索引**:每个ES文档代表一个SPU,包含嵌套的skus数组 - **统一索引**:所有客户共享`search_products`索引 - **租户隔离**:通过`tenant_id`字段实现数据隔离 - **配置简化**:配置只包含ES搜索相关配置,不包含MySQL数据源配置 - **外部友好格式**:API返回格式不包含ES内部字段(`_id`, `_score`, `_source`) ## 配置说明 ### 配置文件位置 `config/schema/base/config.yaml` ### 配置内容 Base配置**不包含**以下内容: - `mysql_config` - MySQL数据库配置 - `main_table` - 主表配置 - `extension_table` - 扩展表配置 - `source_table` / `source_column` - 字段数据源映射 Base配置**只包含**: - ES字段定义(字段类型、分析器、boost等) - 查询域(indexes)配置 - 查询处理配置(query_config) - 排序和打分配置(function_score) - SPU配置(spu_config) ### 必需字段 - `tenant_id` (KEYWORD, required) - 租户隔离字段 ### 主要字段 - `spu_id` - SPU ID - `title`, `brief`, `description` - 文本搜索字段 - `seo_title`, `seo_description`, `seo_keywords` - SEO字段 - `vendor`, `tags`, `category` - 分类和标签字段(HKText,支持 `.keyword` 精确匹配) - `min_price`, `max_price`, `compare_at_price` - 价格字段 - `skus` (nested) - 嵌套SKU数组 ## 数据导入流程 ### 1. 生成测试数据 ```bash python scripts/generate_test_data.py \ --num-spus 100 \ --tenant-id "1" \ --start-spu-id 1 \ --start-sku-id 1 \ --output test_data.sql ``` ### 2. 导入测试数据到MySQL ```bash python scripts/import_test_data.py \ --db-host localhost \ --db-port 3306 \ --db-database saas \ --db-username root \ --db-password password \ --sql-file test_data.sql \ --tenant-id "1" ``` ### 3. 导入数据到Elasticsearch ```bash python scripts/ingest_shoplazza.py \ --db-host localhost \ --db-port 3306 \ --db-database saas \ --db-username root \ --db-password password \ --tenant-id "1" \ --config base \ --es-host http://localhost:9200 \ --recreate \ --batch-size 500 ``` ## API使用 ### 搜索接口 **端点**: `POST /search/` **请求头**: ``` X-Tenant-ID: 1 Content-Type: application/json ``` **请求体**: ```json { "query": "耳机", "size": 10, "from": 0, "filters": { "category.keyword": "电子产品" }, "facets": ["category.keyword", "vendor.keyword"] } ``` **响应格式**: ```json { "results": [ { "spu_id": "1", "title": "蓝牙耳机 Sony", "handle": "product-1", "description": "高品质无线蓝牙耳机", "vendor": "Sony", "category": "电子产品", "price": 199.99, "compare_at_price": 299.99, "currency": "USD", "image_url": "//cdn.example.com/products/1.jpg", "in_stock": true, "skus": [ { "sku_id": "1", "title": "黑色", "price": 199.99, "compare_at_price": 299.99, "sku": "SKU-1-1", "stock": 50, "options": { "option1": "黑色" } } ], "relevance_score": 0.95 } ], "total": 10, "max_score": 1.0, "facets": [ { "field": "category.keyword", "label": "category.keyword", "type": "terms", "values": [ { "value": "电子产品", "label": "电子产品", "count": 5, "selected": false } ] } ], "suggestions": [], "related_searches": [], "took_ms": 15, "query_info": {} } ``` ### 响应格式说明 #### 主要变化 1. **`results`替代`hits`**:返回字段从`hits`改为`results` 2. **结构化结果**:每个结果包含`spu_id`, `title`, `skus`, `relevance_score`等字段 3. **无ES内部字段**:不包含`_id`, `_score`, `_source`等ES内部字段 4. **嵌套skus**:每个商品包含skus数组,每个sku包含完整的变体信息 5. **相关性分数**:`relevance_score`是ES原始分数(不进行归一化) #### SpuResult字段 - `spu_id` - SPU ID - `title` - 商品标题 - `handle` - 商品handle - `description` - 商品描述 - `vendor` - 供应商/品牌 - `category` - 类目 - `tags` - 标签 - `price` - 最低价格(min_price) - `compare_at_price` - 原价 - `currency` - 货币单位(默认USD) - `image_url` - 主图URL - `in_stock` - 是否有库存 - `skus` - SKU列表 - `relevance_score` - 相关性分数(ES原始分数) #### SkuResult字段 - `sku_id` - SKU ID - `title` - 变体标题 - `price` - 价格 - `compare_at_price` - 原价 - `sku` - SKU编码 - `stock` - 库存数量 - `options` - 选项(颜色、尺寸等) ## 测试 ### 运行测试脚本 ```bash python scripts/test_base.py \ --api-url http://localhost:8000 \ --tenant-id "1" \ --test-tenant-2 "2" ``` ### 测试内容 1. **基本搜索**:测试搜索API基本功能 2. **响应格式验证**:验证返回格式是否符合要求 3. **Facets聚合**:测试分面搜索功能 4. **租户隔离**:验证不同租户的数据隔离 ## 常见问题 ### Q: 为什么配置中没有MySQL相关配置? A: 数据源配置和数据导入流程是写死的脚本,不在搜索配置中。搜索配置只关注ES搜索相关的内容。 ### Q: 如何为新的租户导入数据? A: 使用`ingest_shoplazza.py`脚本,指定不同的`--tenant-id`参数即可。 ### Q: 如何验证租户隔离是否生效? A: 使用`test_base.py`脚本,指定两个不同的`--tenant-id`,检查搜索结果是否隔离。 ### Q: API返回格式中为什么没有`_id`和`_score`? A: 为了提供外部友好的API格式,我们移除了ES内部字段,使用`spu_id`和`relevance_score`替代。 ### Q: 如何添加新的搜索字段? A: 在`config/schema/base/config.yaml`中添加字段定义,然后重新生成索引映射并重新导入数据。 ## 注意事项 1. **tenant_id必需**:所有API请求必须提供`tenant_id`(通过请求头`X-Tenant-ID`或查询参数`tenant_id`) 2. **索引共享**:所有客户共享`search_products`索引,确保`tenant_id`字段正确设置 3. **数据导入**:数据导入脚本是写死的,不依赖配置中的MySQL设置 4. **配置分离**:搜索配置和数据源配置完全分离,提高可维护性