Commit 670c701f0ec255b609be6d2272e5efd27208bb73

Authored by tangwang
1 parent 331ea682

文档完善

Showing 2 changed files with 194 additions and 652 deletions   Show diff stats
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 ```bash 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 curl -X POST http://localhost:6002/search/ \ 45 curl -X POST http://localhost:6002/search/ \
104 -H "Content-Type: application/json" \ 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 +
1 1
2 -环境使用: 2 +
  3 +
  4 +## 2. Python 运行环境
  5 +
  6 +```bash
  7 +# 1. 激活 Conda
3 source /home/tw/miniconda3/etc/profile.d/conda.sh 8 source /home/tw/miniconda3/etc/profile.d/conda.sh
4 conda activate searchengine 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