# 使用指南 - SearchEngine ## 快速启动(推荐) ### 一键启动所有服务 ```bash cd /data/tw/SearchEngine ./start_all.sh ``` 这个脚本会自动完成: 1. 设置conda环境 2. 检查并导入测试数据(如果需要) 3. 启动后端API服务(后台运行) 4. 启动前端Web界面 启动完成后,访问: - **前端界面**: http://localhost:6003 - **后端API**: http://localhost:6002 - **API文档**: http://localhost:6002/docs ### 停止服务 ```bash # 停止后端 kill $(cat logs/backend.pid) # 前端按 Ctrl+C ``` --- ## 分步启动(自定义) ### 1. 环境设置 ```bash cd /data/tw/SearchEngine ./setup.sh ``` 这会: - 创建/激活conda环境 `searchengine` - 加载配置文件 - 检查Elasticsearch连接 ### 2. 数据导入 #### 2.1 从MySQL导入到Elasticsearch 数据导入脚本需要指定 `tenant_id` 参数,用于从MySQL中筛选对应租户的数据。 **基本用法**: ```bash ./scripts/ingest.sh [recreate_index] ``` 参数说明: - `tenant_id`: **必需**,租户ID,用于筛选数据库中的数据 - `recreate_index`: 可选,是否删除并重建索引(true/false,默认:false) **示例**: 快速测试(tenant_id=2,重建索引): ```bash ./scripts/ingest.sh 2 true ``` 增量导入(tenant_id=2,不重建索引): ```bash ./scripts/ingest.sh 2 false ``` **检查可用的 tenant_id**: 如果导入时显示 "No documents to index",脚本会自动显示调试信息,包括: - 该 tenant_id 的统计信息(总数、活跃数、已删除数) - 数据库中存在的其他 tenant_id 列表 #### 2.2 从CSV导入数据到MySQL 如果MySQL中没有数据,可以先从CSV文件导入数据到MySQL。 **使用 mock_data.sh 脚本(推荐)**: 将CSV文件放在 `data/customer1.csv`,然后直接运行: ```bash ./scripts/mock_data.sh ``` 脚本会自动: - 从 `data/customer1.csv` 读取数据 - 使用 tenant_id=2 - 生成SQL文件并导入到MySQL **注意**:如果CSV文件路径不同,需要修改 `scripts/mock_data.sh` 中的 `CSV_FILE` 变量。 **手动分步执行**(如果需要自定义参数): 1. **生成SQL文件**: ```bash python scripts/import_customer1_csv.py \ --csv-file data/customer1.csv \ --tenant-id 2 \ --start-spu-id 1 \ --output customer1_data.sql ``` 2. **导入SQL到MySQL**: ```bash python scripts/import_test_data.py \ --db-host 120.79.247.228 \ --db-port 3316 \ --db-database saas \ --db-username saas \ --db-password <密码> \ --sql-file customer1_data.sql \ --tenant-id 2 ``` **CSV文件格式要求**: CSV文件需要包含以下列(列名不区分大小写): - `skuId` - SKU ID - `name` - 商品名称 - `name_pinyin` - 拼音(可选) - `create_time` - 创建时间(格式:YYYY-MM-DD HH:MM:SS) - `ruSkuName` - 俄文SKU名称(可选) - `enSpuName` - 英文SPU名称(可选) - `categoryName` - 类别名称 - `supplierName` - 供应商名称 - `brandName` - 品牌名称 - `file_id` - 文件ID(可选) - `days_since_last_update` - 更新天数(可选) - `id` - 商品ID(可选) - `imageUrl` - 图片URL(可选) **注意**: - 首次运行会下载模型文件(BGE-M3和CN-CLIP),大约需要10-30分钟 - 确保MySQL中存在对应 tenant_id 的数据(`shoplazza_product_spu` 和 `shoplazza_product_sku` 表) - 只有 `deleted=0` 的记录会被导入 - CSV导入会先清理该 tenant_id 的旧数据,再导入新数据 ### 3. 启动后端 ```bash ./scripts/start_backend.sh ``` 后端API会在 http://localhost:6002 启动 ### 4. 启动前端 ```bash ./scripts/start_frontend.sh ``` 前端界面会在 http://localhost:6003 启动 --- ## 配置说明 ### 环境配置文件 (.env) ```bash # Elasticsearch配置 ES_HOST=http://localhost:9200 ES_USERNAME=essa ES_PASSWORD=4hOaLaf41y2VuI8y # Redis配置(可选,用于缓存) REDIS_HOST=localhost REDIS_PORT=6479 REDIS_PASSWORD=BMfv5aI31kgHWtlx # DeepL翻译API DEEPL_AUTH_KEY=c9293ab4-ad25-479b-919f-ab4e63b429ed # 客户配置 TENANT_ID=tenant1 # API服务配置 API_HOST=0.0.0.0 API_PORT=6002 ``` ### 修改配置 1. 编辑 `.env` 文件 2. 重启相关服务 --- ## 使用Web界面 ### 搜索功能 1. **简单搜索**: 直接输入关键词 - 中文: "芭比娃娃" - 英文: "fire control set" - 俄文: "Наборы для пожаротушения" 2. **布尔搜索**: 使用操作符 - AND: "toy AND barbie" - OR: "barbie OR doll" - ANDNOT: "toy ANDNOT cheap" - 组合: "toy AND (barbie OR doll) ANDNOT cheap" 3. **域搜索**: 指定搜索域 - 品牌: "brand:ZHU LIN" - 类别: "category:玩具" ### 搜索选项 - **启用翻译**: 自动翻译查询到其他语言 - **启用语义搜索**: 使用embedding进行语义匹配 - **启用自定义排序**: 使用配置的ranking表达式 - **结果数量**: 10/20/50条 --- ## API使用 ### 搜索接口(v3.0 更新) **基础搜索**(需要指定 tenant_id): ```bash curl -X POST http://localhost:6002/search/ \ -H "Content-Type: application/json" \ -H "X-Tenant-ID: 2" \ -d '{ "query": "芭比娃娃", "size": 20 }' ``` 或者通过查询参数: ```bash curl -X POST "http://localhost:6002/search/?tenant_id=2" \ -H "Content-Type: application/json" \ -d '{ "query": "芭比娃娃", "size": 20 }' ``` **带过滤器的搜索**: ```bash curl -X POST http://localhost:6002/search/ \ -H "Content-Type: application/json" \ -H "X-Tenant-ID: 2" \ -d '{ "query": "玩具", "size": 20, "filters": { "categoryName_keyword": ["玩具", "益智玩具"] }, "range_filters": { "price": {"gte": 50, "lte": 200} } }' ``` **带分面搜索**: ```bash curl -X POST http://localhost:6002/search/ \ -H "Content-Type: application/json" \ -H "X-Tenant-ID: 2" \ -d '{ "query": "玩具", "size": 20, "facets": [ {"field": "categoryName_keyword", "size": 15}, {"field": "brandName_keyword", "size": 15} ] }' ``` ### 图片搜索 ```bash curl -X POST http://localhost:6002/search/image \ -H "Content-Type: application/json" \ -H "X-Tenant-ID: 2" \ -d '{ "image_url": "https://oss.essa.cn/example.jpg", "size": 10 }' ``` **注意**: 所有搜索接口都需要通过 `X-Tenant-ID` 请求头或 `tenant_id` 查询参数指定租户ID。 ### 健康检查 ```bash curl http://localhost:6002/admin/health ``` ### 查看配置 ```bash curl http://localhost:6002/admin/config ``` ### 索引统计 ```bash curl http://localhost:6002/admin/stats ``` --- ## 常见问题 ### 1. Elasticsearch连接失败 **问题**: `Failed to connect to Elasticsearch` **解决**: ```bash # 检查ES是否运行 curl http://localhost:9200 # 检查配置 cat .env | grep ES_ ``` ### 2. 导入数据时内存不足 **问题**: `Out of memory` **解决**: ```bash # 减少batch size或跳过embedding ./scripts/ingest.sh 1000 true ``` ### 3. 模型下载失败 **问题**: 模型文件下载超时 **解决**: - 检查网络连接 - 使用国内镜像源 - 手动下载模型到指定目录 ### 4. 翻译不工作 **问题**: 翻译返回原文 **解决**: - 检查DEEPL_AUTH_KEY是否正确 - 如果没有API key,系统会使用mock模式(返回原文) ### 5. 前端无法连接后端 **问题**: CORS错误 **解决**: - 确保后端在 http://localhost:6002 运行 - 检查浏览器控制台错误信息 ### 6. 数据导入时没有数据 **问题**: `WARNING: No documents to index` 或 `Transformed 0 SPU documents` **可能原因**: 1. 数据库中不存在该 tenant_id 的数据 2. 数据都被标记为 `deleted=1` 3. tenant_id 类型不匹配 **解决步骤**: 1. **查看调试信息**: 脚本会自动显示调试信息,包括: ``` DEBUG: tenant_id=1000: total=0, active=0, deleted=0 DEBUG: Available tenant_ids in shoplazza_product_spu: tenant_id=1: total=100, active=100 tenant_id=2: total=50, active=50 ``` 2. **检查数据库**: 直接查询MySQL确认数据 ```sql -- 查看有哪些 tenant_id SELECT tenant_id, COUNT(*) as count, SUM(CASE WHEN deleted = 0 THEN 1 ELSE 0 END) as active FROM shoplazza_product_spu GROUP BY tenant_id; -- 检查特定 tenant_id 的数据 SELECT COUNT(*) FROM shoplazza_product_spu WHERE tenant_id = 1000 AND deleted = 0; ``` 3. **如果数据库中没有数据,需要先导入数据**: - 如果有CSV文件,使用CSV导入脚本(见"2.2 从CSV导入数据到MySQL") - 如果没有CSV文件,可以使用mock数据生成脚本 4. **使用正确的 tenant_id**: 根据调试信息显示的可用 tenant_id,使用正确的值重新导入 ```bash ./scripts/ingest.sh 2 true # 使用调试信息中显示的 tenant_id ``` --- ## 开发和调试 ### 查看日志 ```bash # 后端日志 tail -f logs/backend.log # 实时日志(如果前台运行) ./scripts/start_backend.sh ``` ### Python命令行测试 ```bash # 激活环境 source /home/tw/miniconda3/etc/profile.d/conda.sh conda activate searchengine # 测试搜索(需要指定 tenant_id) python -c " from config import ConfigLoader from utils.es_client import ESClient from search.searcher import Searcher from config.env_config import ES_CONFIG config_loader = ConfigLoader('config/config.yaml') config = config_loader.load_config() es_client = ESClient(hosts=[ES_CONFIG['host']], username=ES_CONFIG.get('username'), password=ES_CONFIG.get('password')) searcher = Searcher(config, es_client) result = searcher.search('芭比娃娃', tenant_id='2', size=5) print(f'找到 {result.total} 个结果') for hit in result.hits: print(f' - {hit[\"title\"]} (分数: {hit[\"_score\"]:.4f})') " ``` ### 重新导入数据 ```bash # 删除现有索引并重新导入(需要指定 tenant_id) ./scripts/ingest.sh true # 例如:导入 tenant_id=2 的数据并重建索引 ./scripts/ingest.sh 2 true ``` ### 检查数据库中的 tenant_id 如果不知道应该使用哪个 tenant_id,可以: 1. **运行导入脚本查看调试信息**(即使没有数据也会显示): ```bash ./scripts/ingest.sh 999 true ``` 脚本会显示数据库中存在的 tenant_id 列表 2. **直接查询数据库**: ```bash mysql -h 120.79.247.228 -P 3316 -u saas -p saas -e \ "SELECT tenant_id, COUNT(*) as count FROM shoplazza_product_spu GROUP BY tenant_id;" ``` --- ## 性能优化 ### 1. 使用embedding缓存 首次生成embedding后会自动缓存到 `.cache/` 目录,后续导入会更快。 ### 2. 批量大小调整 ```bash # 修改批量大小(在ingest_tenant1.py中) --batch-size 200 # 默认100 ``` ### 3. GPU加速 确保CUDA可用以加速embedding生成: ```bash python -c "import torch; print(f'CUDA available: {torch.cuda.is_available()}')" ``` --- ## 项目结构 ``` SearchEngine/ ├── .env # 环境配置 ├── setup.sh # 环境设置脚本 ├── start_all.sh # 一键启动脚本 ├── scripts/ # 运行脚本 │ ├── ingest.sh # 数据导入 │ ├── start_backend.sh # 启动后端 │ └── start_frontend.sh # 启动前端 ├── frontend/ # Web前端 │ ├── index.html │ └── static/ ├── logs/ # 日志文件 ├── config/ # 配置模块 ├── indexer/ # 数据导入 ├── query/ # 查询处理 ├── search/ # 搜索引擎 ├── embeddings/ # 向量模型 └── api/ # REST API ``` --- ## 支持 遇到问题请查看: - **日志**: `logs/backend.log` - **API文档**: http://localhost:6002/docs - **配置**: `config/schema/tenant1_config.yaml`