USER_GUIDE.md 12.2 KB

使用指南 - SearchEngine

快速启动(推荐)

一键启动所有服务

cd /data/tw/SearchEngine
./start_all.sh

这个脚本会自动完成:

  1. 设置conda环境
  2. 检查并导入测试数据(如果需要)
  3. 启动后端API服务(后台运行)
  4. 启动前端Web界面

启动完成后,访问:

停止服务

# 停止后端
kill $(cat logs/backend.pid)

# 前端按 Ctrl+C

分步启动(自定义)

1. 环境设置

cd /data/tw/SearchEngine
./setup.sh

这会:

  • 创建/激活conda环境 searchengine
  • 加载配置文件
  • 检查Elasticsearch连接

2. 数据导入

2.1 从MySQL导入到Elasticsearch

数据导入脚本需要指定 tenant_id 参数,用于从MySQL中筛选对应租户的数据。

基本用法

./scripts/ingest.sh <tenant_id> [recreate_index]

参数说明:

  • tenant_id: 必需,租户ID,用于筛选数据库中的数据
  • recreate_index: 可选,是否删除并重建索引(true/false,默认:false)

示例

快速测试(tenant_id=2,重建索引):

./scripts/ingest.sh 2 true

增量导入(tenant_id=2,不重建索引):

./scripts/ingest.sh 2 false

检查可用的 tenant_id

如果导入时显示 "No documents to index",脚本会自动显示调试信息,包括:

  • 该 tenant_id 的统计信息(总数、活跃数、已删除数)
  • 数据库中存在的其他 tenant_id 列表

2.2 构造测试数据(Mock Data)

mock_data.sh 脚本用于构造完整的测试数据,包含两部分:

  1. tenant_id=1: 自动生成的mock数据(1000条SPU)
  2. tenant_id=2: 从CSV文件导入的数据(10000条SPU)

使用方法

将CSV文件放在 data/customer1/goods_with_pic.5years_congku.csv.shuf.1w,然后直接运行:

./scripts/mock_data.sh

脚本会自动:

  • 生成 tenant_id=1 的mock数据并导入MySQL
  • 从CSV文件读取数据,生成 tenant_id=2 的数据并导入MySQL
  • 自动计算起始ID,避免主键冲突

注意

  • 所有配置(数据库地址、CSV路径等)都写死在脚本中,这是测试数据构造脚本,不需要配置化
  • 如果CSV文件路径不同,需要修改 scripts/mock_data.sh 中的 TENANT2_CSV_FILE 变量

手动分步执行(如果需要自定义参数):

  1. 生成SQL文件

    python scripts/import_tenant2_csv.py \
    --csv-file data/customer1/goods_with_pic.5years_congku.csv.shuf.1w \
    --tenant-id 2 \
    --output customer1_data.sql \
    --db-host 120.79.247.228 \
    --db-port 3316 \
    --db-database saas \
    --db-username saas \
    --db-password <密码>
    
  2. 导入SQL到MySQL

    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_spushoplazza_product_sku 表)
  • 只有 deleted=0 的记录会被导入
  • CSV导入会先清理该 tenant_id 的旧数据,再导入新数据

3. 启动后端

./scripts/start_backend.sh

后端API会在 http://localhost:6002 启动

4. 启动前端

./scripts/start_frontend.sh

前端界面会在 http://localhost:6003 启动


配置说明

环境配置文件 (.env)

# 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):

curl -X POST http://localhost:6002/search/ \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: 2" \
  -d '{
    "query": "芭比娃娃",
    "size": 20
  }'

或者通过查询参数:

curl -X POST "http://localhost:6002/search/?tenant_id=2" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "芭比娃娃",
    "size": 20
  }'

带过滤器的搜索

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}
    }
  }'

带分面搜索

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}
    ]
  }'

图片搜索

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。

健康检查

curl http://localhost:6002/admin/health

查看配置

curl http://localhost:6002/admin/config

索引统计

curl http://localhost:6002/admin/stats

常见问题

1. Elasticsearch连接失败

问题: Failed to connect to Elasticsearch

解决:

# 检查ES是否运行
curl http://localhost:9200

# 检查配置
cat .env | grep ES_

2. 导入数据时内存不足

问题: Out of memory

解决:

# 减少batch size或跳过embedding
./scripts/ingest.sh 1000 true

3. 模型下载失败

问题: 模型文件下载超时

解决:

  • 检查网络连接
  • 使用国内镜像源
  • 手动下载模型到指定目录

4. 翻译不工作

问题: 翻译返回原文

解决:

  • 检查DEEPL_AUTH_KEY是否正确
  • 如果没有API key,系统会使用mock模式(返回原文)

5. 前端无法连接后端

问题: CORS错误

解决:

6. 数据导入时没有数据

问题: WARNING: No documents to indexTransformed 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确认数据

    -- 查看有哪些 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

开发和调试

查看日志

# 后端日志
tail -f logs/backend.log

# 实时日志(如果前台运行)
./scripts/start_backend.sh

Python命令行测试

# 激活环境
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})')
"

重新导入数据

# 删除现有索引并重新导入(需要指定 tenant_id)
./scripts/ingest.sh <tenant_id> true

# 例如:导入 tenant_id=2 的数据并重建索引
./scripts/ingest.sh 2 true

检查数据库中的 tenant_id

如果不知道应该使用哪个 tenant_id,可以:

  1. 运行导入脚本查看调试信息(即使没有数据也会显示):

    ./scripts/ingest.sh 999 true
    

    脚本会显示数据库中存在的 tenant_id 列表

  2. 直接查询数据库:

    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. 批量大小调整

# 修改批量大小(在ingest_tenant1.py中)
--batch-size 200  # 默认100

3. GPU加速

确保CUDA可用以加速embedding生成:

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

支持

遇到问题请查看: