Commit 670c701f0ec255b609be6d2272e5efd27208bb73

Authored by tangwang
1 parent 331ea682

文档完善

Showing 2 changed files with 194 additions and 652 deletions   Show diff stats
README.md
1   -# 电商搜索引擎 SaaS 系统
  1 +# 电商搜索引擎 SaaS
2 2  
3   -一个可配置的多租户搜索引擎,专为跨境电商独立站(店匠 Shoplazza)设计
  3 +一个针对跨境独立站(店匠 Shoplazza 等)的多租户可配置搜索平台。README 作为项目导航入口,帮助你在不同阶段定位到更详细的文档
4 4  
5   -## 系统特性
  5 +## 核心能力速览
6 6  
7   -- **多语言支持**:支持中文、英文、俄文、阿拉伯文、西班牙文、日文,支持自动翻译
8   -- **语义搜索**:基于 BGE-M3 文本向量和 CN-CLIP 图片向量的语义检索
9   -- **混合排序**:结合 BM25 文本相关性和语义相似度
10   -- **布尔表达式**:支持 AND、OR、RANK、ANDNOT 操作符,支持括号优先级
11   -- **灵活过滤**:精确匹配过滤器和数值范围过滤器
12   -- **分面搜索**:动态生成过滤选项,提供分组统计
13   -- **可配置化**:客户特定的字段定义、分析器、排序表达式
14   -- **多租户隔离**:通过 `tenant_id` 实现数据隔离,共享统一索引
15   -- **RESTful API**:基于 FastAPI 的完整 API 服务
16   -- **前端界面**:提供可视化搜索测试界面
  7 +- **多语言 + 自动翻译**:中文、英文、俄文等语言检测与路由(BGE-M3、DeepL)
  8 +- **语义 + 关键词混排**:BM25、dense vector(BGE-M3/CN-CLIP)融合
  9 +- **布尔与分面**:AND / OR / ANDNOT / RANK、Terms & Range facets
  10 +- **多租户隔离**:共享 `search_products` 索引,通过 `tenant_id` 严格隔离
  11 +- **可配置化**:字段/索引域/排序表达式/查询改写全部配置驱动
  12 +- **脚本化流水线**:Mock/CSV 数据 → MySQL → Elasticsearch → API/前端
17 13  
18   -## 系统架构
  14 +## 快速上手(概览)
19 15  
20   -### 数据模型
  16 +| 步骤 | 去哪里看 | 摘要 |
  17 +|------|---------|------|
  18 +| 1. 准备环境 | `环境相关.md` / `USAGE_GUIDE.md` | Conda/依赖、Elasticsearch、MySQL、必需的变量 |
  19 +| 2. 构造测试数据 | `TEST_DATA_GUIDE.md` | Tenant1 Mock、Tenant2 CSV、`mock_data.sh` / `ingest.sh` |
  20 +| 3. 启动与验证 | `USAGE_GUIDE.md` | `run.sh` 一键启动、分步脚本、日志与健康检查 |
  21 +| 4. 理解架构 | `设计文档.md` | 数据流、配置系统、查询/搜索/索引模块 |
  22 +| 5. 接入搜索 API | `API_DOCUMENTATION.md` / `API_INTEGRATION_GUIDE.md` | REST 端点、参数、响应、最佳实践 |
  23 +| 6. 查字段定义 | `INDEX_FIELDS_DOCUMENTATION.md` | `search_products` 映射、字段来源、类型与用途 |
21 24  
22   -- **SPU 级别索引**:所有租户共享 `search_products` 索引
23   -- **嵌套结构**:每个 SPU 文档包含嵌套的 `variants` 数组(SKU 变体)
24   -- **租户隔离**:通过 `tenant_id` 字段实现多租户数据隔离
25   -- **数据源**:MySQL 数据库(`shoplazza_product_spu` 和 `shoplazza_product_sku` 表)
  25 +> README 仅保留最常用命令的“索引”。细节以主题文档为准。
26 26  
27   -### 技术栈
28   -
29   -- **后端框架**:Python 3.8+ / FastAPI
30   -- **搜索引擎**:Elasticsearch 8.x
31   -- **数据库**:MySQL(店匠数据表)
32   -- **向量模型**:
33   - - 文本向量:BGE-M3(1024维)
34   - - 图片向量:CN-CLIP(1024维)
35   -- **翻译服务**:DeepL API
36   -- **前端**:HTML + JavaScript
37   -
38   -## 快速开始
39   -
40   -### 1. 环境准备
41   -
42   -#### 安装依赖
43   -
44   -```bash
45   -pip install -r requirements.txt
46   -```
47   -
48   -#### 启动 Elasticsearch
49   -
50   -```bash
51   -# 使用 Docker
52   -docker run -d \
53   - --name elasticsearch \
54   - -p 9200:9200 \
55   - -e "discovery.type=single-node" \
56   - -e "ES_JAVA_OPTS=-Xms2g -Xmx2g" \
57   - elasticsearch:8.11.0
58   -```
59   -
60   -#### 配置环境变量(可选)
61   -
62   -创建 `.env` 文件:
  27 +### Runtimes & 命令示例
63 28  
64 29 ```bash
65   -DB_HOST=120.79.247.228
66   -DB_PORT=3316
67   -DB_DATABASE=saas
68   -DB_USERNAME=saas
69   -DB_PASSWORD=your_password
70   -ES_HOST=http://localhost:9200
71   -```
72   -
73   -### 2. 脚本体系
74   -
75   -项目提供统一的脚本系统,管理完整的工作流程:
76   -
77   -#### 脚本说明
  30 +# 1. 安装依赖与准备服务
  31 +pip install -r requirements.txt # 详见 USAGE_GUIDE.md
  32 +docker run -d --name es -p 9200:9200 elasticsearch:8.11.0
78 33  
79   -| 脚本 | 功能 | 说明 |
80   -|------|------|------|
81   -| `restart.sh` | 重启服务 | 停止并重新启动前后端服务 |
82   -| `run.sh` | 启动服务 | 启动前端和后端服务 |
83   -| `scripts/mock_data.sh` | 数据导入 | 将 Mock 数据或 CSV 数据导入 MySQL |
84   -| `scripts/ingest.sh` | 数据索引 | 从 MySQL 导入数据到 Elasticsearch |
85   -
86   -### 3. 手动启动 API 服务(可选)
87   -
88   -如果不想使用脚本,可以手动启动:
89   -
90   -```bash
91   -python -m api.app \
92   - --host 0.0.0.0 \
93   - --port 6002 \
94   - --es-host http://localhost:9200 \
95   - --reload
96   -```
  34 +# 2. 构造测试数据并导入 MySQL
  35 +./scripts/mock_data.sh # 详见 TEST_DATA_GUIDE.md
97 36  
98   -### 4. 测试搜索
  37 +# 3. 从 MySQL 注入到 Elasticsearch
  38 +./scripts/ingest.sh 1 true
  39 +./scripts/ingest.sh 2 true
99 40  
100   -#### 简单搜索
  41 +# 4. 启动服务
  42 +./run.sh
101 43  
102   -```bash
  44 +# 5. 调用文本搜索 API
103 45 curl -X POST http://localhost:6002/search/ \
104 46 -H "Content-Type: application/json" \
105   - -d '{
106   - "query": "蓝牙耳机",
107   - "size": 10
108   - }'
109   -```
110   -
111   -#### 带过滤器的搜索
112   -
113   -```bash
114   -curl -X POST http://localhost:6002/search/ \
115   - -H "Content-Type: application/json" \
116   - -d '{
117   - "query": "玩具",
118   - "size": 10,
119   - "filters": {
120   - "categoryName_keyword": "玩具"
121   - },
122   - "range_filters": {
123   - "min_price": {
124   - "gte": 50,
125   - "lte": 200
126   - }
127   - }
128   - }'
129   -```
130   -
131   -#### 布尔表达式搜索
132   -
133   -```bash
134   -curl -X POST http://localhost:6002/search/ \
135   - -H "Content-Type: application/json" \
136   - -d '{
137   - "query": "蓝牙 AND (耳机 OR 音响)",
138   - "size": 10
139   - }'
140   -```
141   -
142   -#### 图片搜索
143   -
144   -```bash
145   -curl -X POST http://localhost:6002/search/image \
146   - -H "Content-Type: application/json" \
147   - -d '{
148   - "image_url": "https://oss.essa.cn/example.jpg",
149   - "size": 10
150   - }'
151   -```
152   -
153   -#### 分面搜索
154   -
155   -```bash
156   -curl -X POST http://localhost:6002/search/ \
157   - -H "Content-Type: application/json" \
158   - -d '{
159   - "query": "玩具",
160   - "size": 10,
161   - "facets": [
162   - {
163   - "field": "categoryName_keyword",
164   - "label": "分类"
165   - },
166   - {
167   - "field": "brandName_keyword",
168   - "label": "品牌"
169   - }
170   - ]
171   - }'
172   -```
173   -
174   -## 项目结构
175   -
176   -```
177   -SearchEngine/
178   -├── api/ # API 服务
179   -│ ├── app.py # FastAPI 应用主入口
180   -│ ├── models.py # 请求/响应模型
181   -│ └── routes/ # API 路由
182   -│ ├── search.py # 搜索接口
183   -│ └── admin.py # 管理接口
184   -├── config/ # 配置系统
185   -│ ├── field_types.py # 字段类型定义
186   -│ ├── config_loader.py # 配置加载器
187   -│ └── schema/ # 租户配置文件
188   -│ └── base/ # Base 配置(店匠通用)
189   -│ └── config.yaml
190   -├── indexer/ # 数据索引
191   -│ ├── mapping_generator.py # ES mapping 生成器
192   -│ ├── spu_transformer.py # SPU 数据转换器
193   -│ ├── bulk_indexer.py # 批量索引器
194   -│ └── ingest_shoplazza.py # 店匠数据导入脚本
195   -├── query/ # 查询处理
196   -│ ├── query_parser.py # 查询解析器
197   -│ ├── language_detector.py # 语言检测
198   -│ ├── translator.py # 翻译服务
199   -│ └── query_rewriter.py # 查询改写
200   -├── search/ # 搜索执行
201   -│ ├── searcher.py # 主搜索器
202   -│ ├── multilang_query_builder.py # 多语言查询构建器
203   -│ ├── boolean_parser.py # 布尔表达式解析器
204   -│ ├── es_query_builder.py # ES 查询构建器
205   -│ └── ranking_engine.py # 排序引擎
206   -├── embeddings/ # 向量编码
207   -│ ├── text_encoder.py # BGE-M3 文本编码器
208   -│ └── image_encoder.py # CN-CLIP 图片编码器
209   -├── utils/ # 工具类
210   -│ ├── db_connector.py # MySQL 连接器
211   -│ ├── es_client.py # ES 客户端封装
212   -│ └── cache.py # 向量缓存
213   -├── scripts/ # 脚本工具
214   -│ ├── mock_data.sh # Mock 数据导入脚本
215   -│ ├── ingest.sh # 数据索引脚本
216   -│ ├── generate_test_data.py # 生成测试数据
217   -│ ├── import_tenant2_csv.py # Tenant2 CSV 导入脚本
218   -│ └── import_test_data.py # 数据导入脚本
219   -├── frontend/ # 前端界面
220   -│ └── unified.html # 统一搜索界面
221   -├── data/ # 数据文件
222   -│ └── customer1/ # customer1 测试数据
223   -├── run.sh # 启动脚本
224   -├── restart.sh # 重启脚本
225   -└── requirements.txt # Python 依赖
226   -```
227   -
228   -## 配置系统
229   -
230   -### 配置文件结构
231   -
232   -配置文件位于 `config/schema/{tenant_id}/config.yaml`,Base 配置位于 `config/schema/base/config.yaml`。
233   -
234   -### 配置内容
235   -
236   -#### 1. 字段定义 (fields)
237   -
238   -定义 ES 索引的字段结构:
239   -
240   -```yaml
241   -fields:
242   - title_zh:
243   - type: TEXT
244   - analyzer: chinese_ecommerce
245   - index: true
246   - store: true
247   - boost: 2.0
248   - title_en:
249   - type: TEXT
250   - analyzer: english
251   - index: true
252   - store: true
253   - categoryName_keyword:
254   - type: KEYWORD
255   - index: true
256   - store: true
257   - min_price:
258   - type: FLOAT
259   - index: true
260   - store: true
261   - title_embedding:
262   - type: TEXT_EMBEDDING
263   - dimension: 1024
264   - similarity: dot_product
265   -```
266   -
267   -#### 2. 查询域配置 (indexes)
268   -
269   -定义多域查询配置:
270   -
271   -```yaml
272   -indexes:
273   - default:
274   - fields: ["title_zh", "title_en", "title_ru"]
275   - weights: {"title_zh": 2.0, "title_en": 1.5}
276   - title:
277   - fields: ["title_zh", "title_en"]
278   - brand:
279   - fields: ["brandName_keyword"]
280   -```
281   -
282   -#### 3. 查询配置 (query_config)
283   -
284   -多语言和翻译配置:
285   -
286   -```yaml
287   -query_config:
288   - languages: ["zh", "en", "ru"]
289   - auto_translate: true
290   - translation_api: "deepl"
291   - enable_embeddings: true
292   - embedding_model: "bge-m3"
293   -```
294   -
295   -#### 4. 排序配置 (ranking)
296   -
297   -相关性排序表达式:
298   -
299   -```yaml
300   -ranking:
301   - expression: "bm25() + 0.2*text_embedding_relevance() + general_score*2"
302   - enable_function_score: true
303   -```
304   -
305   -#### 5. SPU 配置 (spu_config)
306   -
307   -SPU 聚合配置:
308   -
309   -```yaml
310   -spu_config:
311   - enabled: true
312   - spu_field: "product_id"
313   - inner_hits_size: 3
314   -```
315   -
316   -### 字段类型
317   -
318   -| 类型 | 说明 | 示例 |
319   -|------|------|------|
320   -| `TEXT` | 文本字段,支持分词 | 商品标题、描述 |
321   -| `KEYWORD` | 关键词字段,精确匹配 | 分类、品牌 |
322   -| `TEXT_EMBEDDING` | 文本向量(1024维) | 语义搜索 |
323   -| `IMAGE_EMBEDDING` | 图片向量(1024维) | 图片搜索 |
324   -| `INT/LONG` | 整数类型 | 库存、ID |
325   -| `FLOAT/DOUBLE` | 浮点数类型 | 价格 |
326   -| `DATE` | 日期类型 | 创建时间 |
327   -| `BOOLEAN` | 布尔类型 | 是否上架 |
328   -
329   -### 分析器
330   -
331   -| 分析器 | 说明 | 适用语言 |
332   -|--------|------|----------|
333   -| `chinese_ecommerce` | 中文电商分词器(Ansj) | 中文 |
334   -| `english` | 英文分析器 | 英文 |
335   -| `russian` | 俄文分析器 | 俄文 |
336   -| `arabic` | 阿拉伯文分析器 | 阿拉伯文 |
337   -| `spanish` | 西班牙文分析器 | 西班牙文 |
338   -| `japanese` | 日文分析器 | 日文 |
339   -| `standard` | 标准分析器 | 通用 |
340   -| `keyword` | 关键词分析器 | 精确匹配 |
341   -
342   -## API 接口
343   -
344   -### 搜索接口
345   -
346   -#### 1. 文本搜索
347   -
348   -**端点**: `POST /search/`
349   -
350   -**请求示例**:
351   -
352   -```json
353   -{
354   - "query": "蓝牙耳机",
355   - "size": 10,
356   - "from": 0,
357   - "filters": {
358   - "categoryName_keyword": "电子产品"
359   - },
360   - "range_filters": {
361   - "min_price": {
362   - "gte": 50,
363   - "lte": 500
364   - }
365   - },
366   - "facets": [
367   - {
368   - "field": "categoryName_keyword",
369   - "label": "分类"
370   - }
371   - ],
372   - "sort_by": "min_price",
373   - "sort_order": "asc"
374   -}
  47 + -H "X-Tenant-ID: 1" \
  48 + -d '{"query": "玩具", "size": 10}'
375 49 ```
376 50  
377   -#### 2. 图片搜索
  51 +## 文档地图
378 52  
379   -**端点**: `POST /search/image`
  53 +| 文档 | 内容提要 | 适用场景 |
  54 +|------|----------|----------|
  55 +| `环境相关.md` | 系统要求、Conda/依赖、外部服务账号、常用端口 | 首次部署、环境核对 |
  56 +| `USAGE_GUIDE.md` | 环境准备、服务启动、配置、日志、验证手册 | 日常运维、调试 |
  57 +| `TEST_DATA_GUIDE.md` | 两个租户的模拟/CSV数据构造 & MySQL→ES流程 | 数据准备、联调 |
  58 +| `设计文档.md` | 架构、配置系统、索引/查询/排序模块细节 | 研发/扩展功能 |
  59 +| `INDEX_FIELDS_DOCUMENTATION.md` | `search_products` 字段、类型、来源、嵌套结构 | 新增字段、数据对齐 |
  60 +| `API_DOCUMENTATION.md` | REST API(搜索/图片/管理)详解、示例、响应格式 | API 使用、测试 |
  61 +| `API_INTEGRATION_GUIDE.md` | 客户对接指引、最佳实践、错误处理、语言说明 | 第三方集成、SDK 开发 |
  62 +| `API_QUICK_REFERENCE.md` | 常用请求体速查表 | 支持团队快速查阅 |
  63 +| `环境相关.md` + `.env` 模板 | 运行依赖账号、端口、密钥对照表 | 交付 & 运维 |
380 64  
381   -**请求示例**:
  65 +更多补充材料:
382 66  
383   -```json
384   -{
385   - "image_url": "https://oss.essa.cn/example.jpg",
386   - "size": 10,
387   - "filters": {
388   - "categoryName_keyword": "玩具"
389   - }
390   -}
391   -```
392   -
393   -#### 3. 获取文档
394   -
395   -**端点**: `GET /search/{doc_id}`
396   -
397   -### 管理接口
398   -
399   -#### 1. 健康检查
400   -
401   -**端点**: `GET /admin/health`
402   -
403   -#### 2. 获取配置
404   -
405   -**端点**: `GET /admin/config?tenant_id=1`
406   -
407   -#### 3. 索引统计
408   -
409   -**端点**: `GET /admin/stats?tenant_id=1`
410   -
411   -#### 4. 查询改写规则
  67 +- `TEST_DATA_GUIDE.md`:包含完整工作流脚本示例
  68 +- `商品数据源入ES配置规范.md`:数据源映射约定
  69 +- `MULTILANG_FEATURE.md`:多语言处理细节
412 70  
413   -**端点**:
414   -- `GET /admin/rewrite-rules?tenant_id=1` - 获取规则
415   -- `POST /admin/rewrite-rules` - 更新规则
  71 +## 关键工作流指引
416 72  
417   -详细 API 文档请参考 `API_DOCUMENTATION.md`。
  73 +- **数据构建 → MySQL → Elasticsearch**
  74 + - `scripts/mock_data.sh`:Tenant1 Mock + Tenant2 CSV 一条龙
  75 + - `scripts/ingest.sh <tenant_id> [recreate]`:驱动 `indexer/` 模块写入 `search_products`
  76 + - 详解:`TEST_DATA_GUIDE.md`
418 77  
419   -## 高级功能
420   -
421   -### 布尔表达式
422   -
423   -支持的操作符(优先级从高到低):
424   -
425   -1. `()` - 括号
426   -2. `ANDNOT` - 排除
427   -3. `AND` - 必须全部匹配
428   -4. `OR` - 任意匹配
429   -5. `RANK` - 排序提升
430   -
431   -**示例**:
432   -
433   -```
434   -蓝牙 AND (耳机 OR 音响) ANDNOT 便宜
435   -laptop AND (gaming OR professional) ANDNOT cheap
436   -```
437   -
438   -### 查询改写
439   -
440   -配置品牌/分类映射:
441   -
442   -```yaml
443   -rewrite_dictionary:
444   - "苹果": "brand:苹果 OR name:iPhone"
445   - "玩具": "category:玩具"
446   -```
  78 +- **搜索服务 & API**
  79 + - `api/`(FastAPI)承载 REST API,`search/` + `query/` 负责查询解析与下发
  80 + - API、分页、过滤、Facet、KNN 等:`API_DOCUMENTATION.md`
  81 + - 对接案例与错误码:`API_INTEGRATION_GUIDE.md`
447 82  
448   -### 排序表达式
  83 +- **配置驱动能力**
  84 + - `config/schema/{tenant_id}/config.yaml`:字段定义、索引域、排序表达式、SPU 聚合
  85 + - 详解与设计理念:`设计文档.md`、`INDEX_FIELDS_DOCUMENTATION.md`
449 86  
450   -可配置的相关性排序:
  87 +## 仓库结构(概览)
451 88  
452 89 ```
453   -bm25() + 0.2*text_embedding_relevance() + general_score*2 + timeliness(end_time)
  90 +api/ FastAPI 服务与路由
  91 +config/ 字段/索引/查询配置体系
  92 +indexer/ MySQL → ES 管道(mapping / transformer / bulk)
  93 +query/ 查询解析、改写、翻译、embedding
  94 +search/ 多语言构建、布尔解析、排序引擎
  95 +scripts/ 数据/服务脚本(mock_data, ingest, run 等)
  96 +frontend/ 简易调试页面
  97 +docs/ 运营及中文资料
454 98 ```
455 99  
456   -支持的函数:
457   -- `bm25()` - BM25 相关性分数
458   -- `text_embedding_relevance()` - 文本向量相似度
459   -- `image_embedding_relevance()` - 图片向量相似度
460   -- `field_value(field_name)` - 字段值
461   -- `timeliness(date_field)` - 时间衰减
462   -
463   -### 多语言查询
464   -
465   -系统自动检测查询语言,并支持:
466   -
467   -- **自动翻译**:将查询翻译到配置的所有语言
468   -- **语言路由**:根据语言选择对应的字段
469   -- **混合查询**:同时查询多个语言字段
470   -
471   -### SPU 聚合
472   -
473   -启用 SPU 聚合后,每个 SPU 只返回一个代表性 SKU:
474   -
475   -```yaml
476   -spu_config:
477   - enabled: true
478   - spu_field: "product_id"
479   - inner_hits_size: 3 # 每个 SPU 内部返回的 SKU 数量
480   -```
481   -
482   -## 数据导入
483   -
484   -### MySQL 表结构
485   -
486   -系统使用店匠的标准表结构:
487   -
488   -- **SPU 表**: `shoplazza_product_spu`
489   -- **SKU 表**: `shoplazza_product_sku`
490   -
491   -### 数据导入流程
492   -
493   -1. **生成 SQL**:使用 `scripts/generate_test_data.py` 或 `scripts/import_tenant2_csv.py` 生成 SQL 文件
494   -2. **导入 MySQL**:使用 `scripts/mock_data.sh` 或 `scripts/import_test_data.py` 导入数据
495   -3. **索引到 ES**:使用 `scripts/ingest.sh` 或 `scripts/ingest_shoplazza.py` 将数据索引到 Elasticsearch
496   -
497   -### CSV 数据格式
498   -
499   -CSV 文件应包含以下字段:
500   -
501   -- `skuId` - SKU ID
502   -- `name` - 商品名称(中文)
503   -- `name_pinyin` - 拼音
504   -- `create_time` - 创建时间
505   -- `ruSkuName` - 俄文名称
506   -- `enSpuName` - 英文名称
507   -- `categoryName` - 分类名称
508   -- `supplierName` - 供应商名称
509   -- `brandName` - 品牌名称
510   -- `file_id` - 文件 ID
511   -- `id` - 商品 ID
512   -- `imageUrl` - 图片 URL
513   -
514   -## 性能优化
515   -
516   -### 1. 向量缓存
517   -
518   -启用向量缓存可以避免重复计算:
519   -
520   -```python
521   -# 在配置中启用缓存
522   -cache:
523   - enabled: true
524   - ttl: 3600 # 缓存过期时间(秒)
525   -```
  100 +## 常用参考
526 101  
527   -### 2. 批量处理
528   -
529   -调整批量大小以优化性能:
530   -
531   -- **数据转换批量大小**:默认 100(根据内存调整)
532   -- **索引批量大小**:默认 500(根据 ES 性能调整)
533   -
534   -### 3. GPU 加速
535   -
536   -使用 GPU 加速向量计算:
537   -
538   -```bash
539   -# 安装 CUDA 版本的 PyTorch
540   -pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118
541   -```
542   -
543   -### 4. ES 分片配置
544   -
545   -根据数据量配置 ES 分片:
546   -
547   -```yaml
548   -# 在 mapping 生成器中配置
549   -settings:
550   - number_of_shards: 3
551   - number_of_replicas: 1
552   -```
553   -
554   -## 开发指南
555   -
556   -### 运行测试
557   -
558   -```bash
559   -pytest tests/
560   -```
561   -
562   -### 代码格式化
563   -
564   -```bash
565   -black .
566   -```
567   -
568   -### 类型检查
569   -
570   -```bash
571   -mypy .
572   -```
573   -
574   -### 日志查看
575   -
576   -```bash
577   -# 查看服务日志
578   -tail -f logs/search_service.log
579   -```
580   -
581   -## 常见问题
582   -
583   -### 1. 如何添加新的租户?
584   -
585   -1. 创建配置文件 `config/schema/{tenant_id}/config.yaml`
586   -2. 导入数据到 MySQL(使用 `scripts/mock_data.sh`)
587   -3. 索引数据到 ES(使用 `scripts/ingest.sh {tenant_id}`)
588   -
589   -### 2. 如何修改排序规则?
590   -
591   -编辑配置文件中的 `ranking.expression` 字段。
592   -
593   -### 3. 如何添加新的分析器?
594   -
595   -在 `config/field_types.py` 中定义新的分析器,然后在字段配置中使用。
596   -
597   -### 4. 向量计算很慢怎么办?
598   -
599   -- 启用向量缓存
600   -- 使用 GPU 加速
601   -- 减少批量大小
602   -
603   -### 5. 如何调试搜索查询?
604   -
605   -在 API 请求中设置 `debug: true`,返回详细的调试信息。
606   -
607   -## 相关文档
608   -
609   -- **API 文档**: `API_DOCUMENTATION.md`
610   -- **设计文档**: `设计文档.md`
611   -- **部署指南**: `DEPLOYMENT.md`
612   -- **用户指南**: `USER_GUIDE.md`
  102 +- **运行/排障**:`USAGE_GUIDE.md`、`环境相关.md`
  103 +- **功能设计**:`设计文档.md`
  104 +- **字段/数据对齐**:`INDEX_FIELDS_DOCUMENTATION.md`
  105 +- **API 对接**:`API_DOCUMENTATION.md`、`API_INTEGRATION_GUIDE.md`
  106 +- **测试数据**:`TEST_DATA_GUIDE.md`
613 107  
614 108 ## 许可证
615 109  
616 110 专有软件 - 保留所有权利
  111 +
... ...
环境相关.md
1 1  
2   -环境使用:
  2 +
  3 +
  4 +## 2. Python 运行环境
  5 +
  6 +```bash
  7 +# 1. 激活 Conda
3 8 source /home/tw/miniconda3/etc/profile.d/conda.sh
4 9 conda activate searchengine
5 10  
  11 +# 如果部署到新机器,不存在 searchengine 环境时,需要初始化环境:
  12 +cd /home/tw/SearchEngine
  13 +pip install -r requirements.txt
  14 +```
  15 +
  16 +---
  17 +
  18 +## 3. 外部服务与端口
  19 +
  20 +| 服务 | 默认地址 | 说明 |
  21 +|------|----------|------|
  22 +| Elasticsearch | `http://localhost:9200` | 可通过 Docker 单节点启动 |
  23 +| MySQL | `120.79.247.228:3316` | 存放店匠 SPU/SKU 数据 |
  24 +| Redis(可选) | `localhost:6479` | Embedding/翻译缓存 |
  25 +
  26 +示例:使用 Docker 启动 Elasticsearch
  27 +
  28 +```bash
  29 +docker run -d \
  30 + --name elasticsearch \
  31 + -p 9200:9200 \
  32 + -e "discovery.type=single-node" \
  33 + -e "ES_JAVA_OPTS=-Xms2g -Xmx2g" \
  34 + elasticsearch:8.11.0
  35 +```
  36 +
  37 +---
  38 +
  39 +## 4. 环境变量与 `.env` 模板
  40 +
  41 +在项目根目录创建 `.env`,并根据环境替换敏感信息:
  42 +
  43 +```env
  44 +# MySQL
  45 +DB_HOST=120.79.247.228
  46 +DB_PORT=3316
  47 +DB_DATABASE=saas
  48 +DB_USERNAME=saas
  49 +DB_PASSWORD=P89cZHS5d7dFyc9R
  50 +
  51 +# Elasticsearch
  52 +ES_HOST=http://localhost:9200
  53 +ES_USERNAME=essa
  54 +ES_PASSWORD=4hOaLaf41y2VuI8y
  55 +
  56 +# Redis(可选)
  57 +REDIS_HOST=localhost
  58 +REDIS_PORT=6479
  59 +REDIS_PASSWORD=BMfv5aI31kgHWtlx
  60 +
  61 +# DeepL 翻译
  62 +DEEPL_AUTH_KEY=c9293ab4-ad25-479b-919f-ab4e63b429ed
  63 +
  64 +# API
  65 +API_HOST=0.0.0.0
  66 +API_PORT=6002
  67 +```
  68 +
  69 +---
  70 +
  71 +## 5. 服务凭证速查
  72 +
  73 +| 项目 | 值 |
  74 +|------|----|
  75 +| **MySQL** | host `120.79.247.228`, port `3316`, user `saas`, password `P89cZHS5d7dFyc9R` |
  76 +| **Elasticsearch** | host `http://localhost:9200`, user `essa`, password `4hOaLaf41y2VuI8y` |
  77 +| **Redis(可选)** | host `localhost`, port `6479`, password `BMfv5aI31kgHWtlx` |
  78 +| **DeepL** | `c9293ab4-ad25-479b-919f-ab4e63b429ed` |
  79 +
  80 +> 所有凭证仅用于本地/测试环境,生产环境需替换并妥善保管。
  81 +
  82 +---
  83 +
  84 +## 6. 店匠数据源说明
  85 +
  86 +SearchEngine 以 MySQL 中的店匠标准表为权威数据源:
  87 +
  88 +- `shoplazza_product_spu`:SPU 商品主表
  89 +- `shoplazza_product_sku`:SKU 变体表
  90 +
  91 +### `shoplazza_product_sku` 字段节选
  92 +
  93 +| 字段 | 类型 | 描述 |
  94 +|------|------|------|
  95 +| `id` | bigint(20) | SKU 主键 |
  96 +| `spu_id` | bigint(20) | 对应 SPU |
  97 +| `shop_id` | bigint(20) | 店铺 ID |
  98 +| `shoplazza_product_id` | varchar(64) | 店匠商品 ID |
  99 +| `title` | varchar(500) | 变体标题 |
  100 +| `sku` | varchar(100) | SKU 编码 |
  101 +| `price` | decimal(10,2) | 售价 |
  102 +| `compare_at_price` | decimal(10,2) | 原价 |
  103 +| `option1/2/3` | varchar(255) | 颜色/尺码等选项 |
  104 +| `inventory_quantity` | int(11) | 库存 |
  105 +| `image_src` | varchar(500) | 图片 |
  106 +| `tenant_id` | bigint(20) | 租户 |
  107 +| `create_time` | datetime | 创建时间 |
  108 +| `update_time` | datetime | 更新时间 |
  109 +| `deleted` | bit(1) | 逻辑删除标记 |
  110 +
  111 +> 完整字段、索引映射与 ES 对应关系详见 `INDEX_FIELDS_DOCUMENTATION.md`。
  112 +
  113 +---
  114 +
  115 +## 7. 相关脚本
  116 +
  117 +- `scripts/mock_data.sh`:一次性生成 Tenant1 Mock + Tenant2 CSV 数据并导入 MySQL
  118 +- `scripts/ingest.sh <tenant_id> [recreate]`:从 MySQL 写入 Elasticsearch
  119 +- `run.sh` / `restart.sh`:服务启动/重启
  120 +
  121 +更多脚本参数、日志与验证命令参见 `USAGE_GUIDE.md` 与 `TEST_DATA_GUIDE.md`。
6 122  
7   -店匠是类似于shopify的独立站SAAS。我们要为基于店匠的独立站(一般为跨境电商独立站)做搜索SAAS。
8   -
9   -
10   -## 商品数据 - 数据源 - mysql
11   -店匠的商品结构如下:
12   -
13   -数据库配置:
14   -
15   -## mysql数据源
16   -host: 120.79.247.228
17   -port: 3316
18   -username: saas
19   -password: P89cZHS5d7dFyc9R
20   -
21   -
22   -ES_CONFIG = {
23   - 'host': 'http://localhost:9200',
24   - 'username': 'essa',
25   - 'password': '4hOaLaf41y2VuI8y'
26   -}
27   -
28   -REDIS_CONFIG = {
29   - 'host': 'localhost',
30   - 'port': 6479,
31   - 'password': 'BMfv5aI31kgHWtlx'
32   -}
33   -
34   -DEEPL_AUTH_KEY = "c9293ab4-ad25-479b-919f-ab4e63b429ed"
35   -
36   -
37   -
38   -
39   -
40   -### 店匠主表
41   -shoplazza_product_sku
42   -shoplazza_product_spu
43   -
44   -主表sku表的结构为:
45   -id bigint(20)
46   -spu_id bigint(20)
47   -shop_id bigint(20)
48   -shoplazza_id varchar(64)
49   -shoplazza_product_id varchar(64)
50   -shoplazza_image_id varchar(64)
51   -title varchar(500)
52   -sku varchar(100)
53   -barcode varchar(100)
54   -position int(11)
55   -price decimal(10,2)
56   -compare_at_price decimal(10,2)
57   -cost_price decimal(10,2)
58   -option1 varchar(255)
59   -option2 varchar(255)
60   -option3 varchar(255)
61   -inventory_quantity int(11)
62   -weight decimal(10,2)
63   -weight_unit varchar(10)
64   -image_src varchar(500)
65   -wholesale_price json
66   -note text
67   -extend json
68   -shoplazza_created_at datetime
69   -shoplazza_updated_at datetime
70   -tenant_id bigint(20)
71   -creator varchar(64)
72   -create_time datetime
73   -updater varchar(64)
74   -update_time datetime
75   -deleted bit(1)
76 123  
... ...