Commit 3a950275b31399928b9d15724fc6b7d0fb14e2dd

Authored by tangwang
1 parent b926f678

导入测试数据

data/customer1/ingest_customer1.py
@@ -9,9 +9,11 @@ import sys @@ -9,9 +9,11 @@ import sys
9 import os 9 import os
10 import pandas as pd 10 import pandas as pd
11 import argparse 11 import argparse
  12 +from typing import Optional
12 13
13 -# Add parent directory to path  
14 -sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 14 +# Add parent directory to path (go up 3 levels: customer1 -> data -> SearchEngine -> root)
  15 +project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  16 +sys.path.insert(0, project_root)
15 17
16 from config import ConfigLoader 18 from config import ConfigLoader
17 from utils import ESClient, get_connection_from_config 19 from utils import ESClient, get_connection_from_config
@@ -53,6 +55,8 @@ def main(): @@ -53,6 +55,8 @@ def main():
53 parser.add_argument('--batch-size', type=int, default=100, help='Batch size for processing') 55 parser.add_argument('--batch-size', type=int, default=100, help='Batch size for processing')
54 parser.add_argument('--recreate-index', action='store_true', help='Recreate index if exists') 56 parser.add_argument('--recreate-index', action='store_true', help='Recreate index if exists')
55 parser.add_argument('--es-host', default='http://localhost:9200', help='Elasticsearch host') 57 parser.add_argument('--es-host', default='http://localhost:9200', help='Elasticsearch host')
  58 + parser.add_argument('--es-username', default=None, help='Elasticsearch username (or set ES_USERNAME env var)')
  59 + parser.add_argument('--es-password', default=None, help='Elasticsearch password (or set ES_PASSWORD env var)')
56 parser.add_argument('--skip-embeddings', action='store_true', help='Skip embedding generation') 60 parser.add_argument('--skip-embeddings', action='store_true', help='Skip embedding generation')
57 args = parser.parse_args() 61 args = parser.parse_args()
58 62
@@ -80,11 +84,40 @@ def main(): @@ -80,11 +84,40 @@ def main():
80 84
81 # Initialize Elasticsearch client 85 # Initialize Elasticsearch client
82 print(f"\n[2/6] Connecting to Elasticsearch: {args.es_host}") 86 print(f"\n[2/6] Connecting to Elasticsearch: {args.es_host}")
83 - os.environ['ES_HOST'] = args.es_host  
84 - es_client = ESClient(hosts=[args.es_host]) 87 +
  88 + # Get credentials: prioritize command-line args, then environment variables, then .env file
  89 + es_username = args.es_username
  90 + es_password = args.es_password
  91 +
  92 + # If not provided via args, try to load from .env file via env_config
  93 + if not es_username or not es_password:
  94 + try:
  95 + from config.env_config import get_es_config
  96 + es_config = get_es_config()
  97 + es_username = es_username or es_config.get('username')
  98 + es_password = es_password or es_config.get('password')
  99 + except Exception:
  100 + # Fallback to environment variables
  101 + es_username = es_username or os.getenv('ES_USERNAME')
  102 + es_password = es_password or os.getenv('ES_PASSWORD')
  103 +
  104 + # Create ES client with credentials if available
  105 + if es_username and es_password:
  106 + print(f" Using authentication: {es_username}")
  107 + es_client = ESClient(hosts=[args.es_host], username=es_username, password=es_password)
  108 + else:
  109 + print(f" Warning: No authentication credentials found")
  110 + print(f" Attempting connection without authentication (will fail if ES requires auth)")
  111 + es_client = ESClient(hosts=[args.es_host])
85 112
86 if not es_client.ping(): 113 if not es_client.ping():
87 print("Failed to connect to Elasticsearch") 114 print("Failed to connect to Elasticsearch")
  115 + print("\nTroubleshooting:")
  116 + print(" 1. Check if Elasticsearch is running: curl http://localhost:9200")
  117 + print(" 2. If ES requires authentication, provide credentials:")
  118 + print(" - Use --es-username and --es-password arguments, or")
  119 + print(" - Set ES_USERNAME and ES_PASSWORD environment variables")
  120 + print(" 3. Verify the host URL is correct: --es-host")
88 return 1 121 return 1
89 122
90 print("Connected to Elasticsearch successfully") 123 print("Connected to Elasticsearch successfully")
@@ -3,7 +3,6 @@ @@ -3,7 +3,6 @@
3 # One-click startup script for SearchEngine 3 # One-click startup script for SearchEngine
4 # This script starts everything you need 4 # This script starts everything you need
5 5
6 -source /home/tw/miniconda3/etc/profile.d/conda.sh  
7 6
8 set -e 7 set -e
9 8
当前开发进度.md
  1 +# 搜索引擎通用化开发进度
1 2
  3 +## 项目概述
2 4
3 对后端搜索技术 做通用化。 5 对后端搜索技术 做通用化。
4 -  
5 通用化的本质 是 对于各种业务数据、各种检索需求,都可以 用少量定制+配置化 来实现效果。 6 通用化的本质 是 对于各种业务数据、各种检索需求,都可以 用少量定制+配置化 来实现效果。
6 7
7 -## 1. 原始数据层的约定。  
8 -### 店匠主表  
9 -shoplazza_product_sku  
10 -shoplazza_product_spu  
11 -所有租户共用这个主表  
12 8
13 -### 每个租户的辅表  
14 -各个租户,有自己的扩展表。 入索引的时候,商品主表 shoplazza_product_sku 的 id + shopid,拼接租户自己单独的扩展表(比如可以放一些自己的属性体系、各种语言的商品名、品牌名、标签、分类等) 9 +**通用化的本质**:对于各种业务数据、各种检索需求,都可以用少量定制+配置化来实现效果。
  10 +
  11 +---
  12 +
  13 +## 1. 原始数据层的约定
  14 +
  15 +所有租户共用主表、独立配置和扩展表,有自己独立的ES索引。
  16 +
  17 +### 1.1 店匠主表
  18 +
  19 +所有租户共用以下主表:
  20 +- `shoplazza_product_sku` - SKU级别商品数据
  21 +- `shoplazza_product_spu` - SPU级别商品数据
  22 +
  23 +### 1.2 每个租户的扩展表
  24 +
  25 +各个租户有自己的扩展表,不同的租户根据不同的业务需要、以及不同的数据源,来定制自己的扩展表:
  26 +- 自定义属性体系
  27 +- 多语言商品标题(中文、英文、俄文等)
  28 +- 品牌名、不同的类目和标签体系
  29 +- 业务过滤和聚合字段
  30 +- 权重(提权)字段
  31 +
  32 +**数据关联方式**:
  33 +- 入索引时,商品主表 `shoplazza_product_sku` 的 `id` + `shopid` 与租户扩展表关联
  34 +- 例如:`customer1_extension` 表存储 customer1 的自定义字段
  35 +
  36 +### 1.3 配置化方案
  37 +
  38 +统一通过配置文件定义:
  39 +1. ES 字段定义(字段类型、分析器、来源表/列)
  40 +2. ES mapping 结构生成
  41 +3. 数据入库映射关系
  42 +
  43 +---
  44 +
  45 +## 2. 配置系统实现
  46 +
  47 +### 2.1 应用结构配置(字段定义)
  48 +
  49 +**配置文件位置**:`config/schema/{customer_id}_config.yaml`
  50 +
  51 +**配置内容**:定义了 ES 的输入数据有哪些字段、关联 MySQL 的哪些字段。
  52 +
  53 +**实现情况**:
  54 +
  55 +#### 字段类型支持
  56 +- **TEXT**:文本字段,支持多语言分析器
  57 +- **KEYWORD**:关键词字段,用于精确匹配和聚合
  58 +- **TEXT_EMBEDDING**:文本向量字段(1024维,dot_product相似度)
  59 +- **IMAGE_EMBEDDING**:图片向量字段(1024维,dot_product相似度)
  60 +- **INT/LONG**:整数类型
  61 +- **FLOAT/DOUBLE**:浮点数类型
  62 +- **DATE**:日期类型
  63 +- **BOOLEAN**:布尔类型
  64 +
  65 +#### 分析器支持
  66 +- **chinese_ecommerce**:中文电商分词器(index_ansj/query_ansj)
  67 +- **english**:英文分析器
  68 +- **russian**:俄文分析器
  69 +- **arabic**:阿拉伯文分析器
  70 +- **spanish**:西班牙文分析器
  71 +- **japanese**:日文分析器
  72 +- **standard**:标准分析器
  73 +- **keyword**:关键词分析器
  74 +
  75 +#### 字段配置示例
  76 +
  77 +```yaml
  78 +fields:
  79 + # 主键字段
  80 + - name: "skuId"
  81 + type: "LONG"
  82 + source_table: "main" # 主表
  83 + source_column: "id"
  84 + required: true
  85 + index: true
  86 + store: true
  87 +
  88 + # 多语言文本字段
  89 + - name: "name"
  90 + type: "TEXT"
  91 + source_table: "extension" # 扩展表
  92 + source_column: "name"
  93 + analyzer: "chinese_ecommerce"
  94 + boost: 2.0
  95 + index: true
  96 + store: true
  97 +
  98 + - name: "enSpuName"
  99 + type: "TEXT"
  100 + source_table: "extension"
  101 + source_column: "enSpuName"
  102 + analyzer: "english"
  103 + boost: 2.0
  104 +
  105 + - name: "ruSkuName"
  106 + type: "TEXT"
  107 + source_table: "extension"
  108 + source_column: "ruSkuName"
  109 + analyzer: "russian"
  110 + boost: 2.0
  111 +
  112 + # 文本向量字段
  113 + - name: "name_embedding"
  114 + type: "TEXT_EMBEDDING"
  115 + source_table: "extension"
  116 + source_column: "name"
  117 + embedding_dims: 1024
  118 + embedding_similarity: "dot_product"
  119 + index: true
  120 +
  121 + # 图片向量字段
  122 + - name: "image_embedding"
  123 + type: "IMAGE_EMBEDDING"
  124 + source_table: "extension"
  125 + source_column: "imageUrl"
  126 + embedding_dims: 1024
  127 + embedding_similarity: "dot_product"
  128 + nested: false
  129 +```
  130 +
  131 +**实现模块**:
  132 +- `config/config_loader.py` - 配置加载器
  133 +- `config/field_types.py` - 字段类型定义
  134 +- `indexer/mapping_generator.py` - ES mapping 生成器
  135 +- `indexer/data_transformer.py` - 数据转换器
  136 +
  137 +### 2.2 索引结构配置(查询域配置)
  138 +
  139 +**配置内容**:定义了 ES 的字段索引 mapping 配置,支持各个域的查询,包括默认域的查询。
  140 +
  141 +**实现情况**:
  142 +
  143 +#### 域(Domain)配置
  144 +每个域定义了:
  145 +- 域名称(如 `default`, `title`, `category`, `brand`)
  146 +- 域标签(中文描述)
  147 +- 搜索字段列表
  148 +- 默认分析器
  149 +- 权重(boost)
  150 +- **多语言字段映射**(`language_field_mapping`)
  151 +
  152 +#### 多语言字段映射
  153 +
  154 +支持将不同语言的查询路由到对应的字段:
  155 +
  156 +```yaml
  157 +indexes:
  158 + - name: "default"
  159 + label: "默认索引"
  160 + fields:
  161 + - "name"
  162 + - "enSpuName"
  163 + - "ruSkuName"
  164 + - "categoryName"
  165 + - "brandName"
  166 + analyzer: "chinese_ecommerce"
  167 + boost: 1.0
  168 + language_field_mapping:
  169 + zh:
  170 + - "name"
  171 + - "categoryName"
  172 + - "brandName"
  173 + en:
  174 + - "enSpuName"
  175 + ru:
  176 + - "ruSkuName"
  177 +
  178 + - name: "title"
  179 + label: "标题索引"
  180 + fields:
  181 + - "name"
  182 + - "enSpuName"
  183 + - "ruSkuName"
  184 + analyzer: "chinese_ecommerce"
  185 + boost: 2.0
  186 + language_field_mapping:
  187 + zh:
  188 + - "name"
  189 + en:
  190 + - "enSpuName"
  191 + ru:
  192 + - "ruSkuName"
  193 +```
  194 +
  195 +**工作原理**:
  196 +1. 检测查询语言(中文、英文、俄文等)
  197 +2. 如果查询语言在 `language_field_mapping` 中,使用原始查询搜索对应语言的字段
  198 +3. 将查询翻译到其他支持的语言,分别搜索对应语言的字段
  199 +4. 组合多个语言查询的结果,提高召回率
  200 +
  201 +**实现模块**:
  202 +- `search/multilang_query_builder.py` - 多语言查询构建器
  203 +- `query/query_parser.py` - 查询解析器(支持语言检测和翻译)
  204 +
  205 +---
  206 +
  207 +## 3. 测试数据灌入
  208 +
  209 +### 3.1 数据源
  210 +
  211 +**主表**:`shoplazza_product_sku`
  212 +- 所有租户共用
  213 +- 包含基础商品信息(id, shopid 等)
  214 +
  215 +**扩展表**:`customer1_extension`
  216 +- 每个租户独立
  217 +- 包含自定义字段和多语言字段
  218 +
  219 +### 3.2 数据灌入方式
  220 +
  221 +**实现情况**:
  222 +
  223 +#### 命令行工具
  224 +```bash
  225 +python main.py ingest \
  226 + --customer customer1 \
  227 + --csv-file data/customer1_data.csv \
  228 + --es-host http://localhost:9200 \
  229 + --recreate \
  230 + --batch-size 100
  231 +```
  232 +
  233 +#### 数据流程
  234 +1. **数据加载**:从 CSV 文件或 MySQL 数据库加载数据
  235 +2. **数据转换**:
  236 + - 字段映射(根据配置将源字段映射到 ES 字段)
  237 + - 类型转换(字符串、数字、日期等)
  238 + - 向量生成(文本向量、图片向量)
  239 + - 向量缓存(避免重复计算)
  240 +3. **索引创建**:
  241 + - 根据配置生成 ES mapping
  242 + - 创建或更新索引
  243 +4. **批量入库**:
  244 + - 批量写入 ES(默认每批 500 条)
  245 + - 错误处理和重试机制
  246 +
  247 +#### 配置映射示例
  248 +
  249 +**customer1_config.yaml** 配置:
  250 +```yaml
  251 +main_table: "shoplazza_product_sku"
  252 +extension_table: "customer1_extension"
  253 +es_index_name: "search_customer1"
  254 +
  255 +fields:
  256 + - name: "skuId"
  257 + source_table: "main"
  258 + source_column: "id"
  259 + - name: "name"
  260 + source_table: "extension"
  261 + source_column: "name"
  262 + - name: "enSpuName"
  263 + source_table: "extension"
  264 + source_column: "enSpuName"
  265 +```
  266 +
  267 +**数据转换**:
  268 +- 主表字段:直接从 `shoplazza_product_sku` 表的 `id` 字段读取
  269 +- 扩展表字段:从 `customer1_extension` 表的对应列读取
  270 +- 向量字段:对源文本/图片生成向量并缓存
  271 +
  272 +**实现模块**:
  273 +- `indexer/data_transformer.py` - 数据转换器
  274 +- `indexer/bulk_indexer.py` - 批量索引器
  275 +- `indexer/indexing_pipeline.py` - 索引流水线
  276 +- `embeddings/bge_encoder.py` - 文本向量编码器
  277 +- `embeddings/clip_image_encoder.py` - 图片向量编码器
  278 +
  279 +---
  280 +
  281 +## 4. QueryParser 实现
  282 +
  283 +
  284 +### 4.1 查询改写(Query Rewriting)
  285 +
  286 +配置词典的key是query,value是改写后的查询表达式,比如。比如品牌词 改写为在brand|query OR name|query,类别词、标签词等都可以放进去。纠错、规范化、查询改写等 都可以通过这个词典来配置。
  287 +**实现情况**:
  288 +
  289 +#### 配置方式
  290 +在 `query_config.rewrite_dictionary` 中配置查询改写规则:
  291 +
  292 +```yaml
  293 +query_config:
  294 + enable_query_rewrite: true
  295 + rewrite_dictionary:
  296 + "芭比": "brand:芭比 OR name:芭比娃娃"
  297 + "玩具": "category:玩具"
  298 + "消防": "category:消防 OR name:消防"
  299 +```
  300 +
  301 +#### 功能特性
  302 +- **精确匹配**:查询完全匹配词典 key 时,替换为 value
  303 +- **部分匹配**:查询包含词典 key 时,替换该部分
  304 +- **支持布尔表达式**:value 可以是复杂的布尔表达式(AND, OR, 域查询等)
  305 +
  306 +#### 实现模块
  307 +- `query/query_rewriter.py` - 查询改写器
  308 +- `query/query_parser.py` - 查询解析器(集成改写功能)
  309 +
  310 +### 4.2 翻译(Translation)
  311 +
  312 +**实现情况**:
  313 +
  314 +#### 配置方式
  315 +```yaml
  316 +query_config:
  317 + supported_languages:
  318 + - "zh"
  319 + - "en"
  320 + - "ru"
  321 + default_language: "zh"
  322 + enable_translation: true
  323 + translation_service: "deepl"
  324 + translation_api_key: null # 通过环境变量设置
  325 +```
  326 +
  327 +#### 功能特性
  328 +1. **语言检测**:自动检测查询语言
  329 +2. **智能翻译**:
  330 + - 如果查询是中文,翻译为英文、俄文
  331 + - 如果查询是英文,翻译为中文、俄文
  332 + - 如果查询是其他语言,翻译为所有支持的语言
  333 +3. **域感知翻译**:
  334 + - 如果域有 `language_field_mapping`,只翻译到映射中存在的语言
  335 + - 避免不必要的翻译,提高效率
  336 +4. **翻译缓存**:缓存翻译结果,避免重复调用 API
  337 +
  338 +#### 工作流程
  339 +```
  340 +查询输入 → 语言检测 → 确定目标语言 → 翻译 → 多语言查询构建
  341 +```
  342 +
  343 +#### 实现模块
  344 +- `query/language_detector.py` - 语言检测器
  345 +- `query/translator.py` - 翻译器(DeepL API)
  346 +- `query/query_parser.py` - 查询解析器(集成翻译功能)
  347 +
  348 +### 4.3 文本向量化(Text Embedding)
  349 +
  350 +如果配置打开了text_embedding查询,并且query 包含了default域的查询,那么要把default域的查询词转向量,后面searcher会用这个向量参与查询。
  351 +
  352 +**实现情况**:
  353 +
  354 +#### 配置方式
  355 +```yaml
  356 +query_config:
  357 + enable_text_embedding: true
  358 +```
  359 +
  360 +#### 功能特性
  361 +1. **条件生成**:
  362 + - 仅当 `enable_text_embedding=true` 时生成向量
  363 + - 仅对 `default` 域查询生成向量
  364 +2. **向量模型**:BGE-M3 模型(1024维向量)
  365 +3. **用途**:用于语义搜索(KNN 检索)
  366 +
  367 +#### 实现模块
  368 +- `embeddings/bge_encoder.py` - BGE 文本编码器
  369 +- `query/query_parser.py` - 查询解析器(集成向量生成)
  370 +
  371 +---
  372 +
  373 +## 5. Searcher 实现
  374 +
  375 +参考opensearch,他们自己定义的一套索引结构配置、支持自定义的一套检索表达式、排序表达式,这是各个客户进行配置化的基础,包括索引结构配置、排序策略配置。
  376 +比如各种业务过滤策略 可以简单的通过表达式满足,比如brand|耐克 AND cate2|xxx。指定字段排序可以通过排序的表达式实现。
  377 +
  378 +查询默认在default域,相也会对这个域的查询做一些相关性的重点优化,包括融合语义相关性、多语言相关性(可以基于配置 将查询翻译到指定语言并在对应的语言的字段进行查询)来弥补传统查询分析手段(比如查询改写 纠错 词权重等)的不足,也支持通过配置一些词表转为泛查询模式来优化相关性。
  379 +
  380 +### 5.1 布尔表达式解析
  381 +
  382 +**实现情况**:
  383 +
  384 +#### 支持的运算符
  385 +- **AND**:所有项必须匹配
  386 +- **OR**:任意项匹配
  387 +- **RANK**:排序增强(类似 OR 但影响排序)
  388 +- **ANDNOT**:排除(第一项匹配,第二项不匹配)
  389 +- **()**:括号分组
  390 +
  391 +#### 优先级(从高到低)
  392 +1. `()` - 括号
  393 +2. `ANDNOT` - 排除
  394 +3. `AND` - 与
  395 +4. `OR` - 或
  396 +5. `RANK` - 排序
  397 +
  398 +#### 示例
  399 +```
  400 +laptop AND (gaming OR professional) ANDNOT cheap
  401 +```
  402 +
  403 +#### 实现模块
  404 +- `search/boolean_parser.py` - 布尔表达式解析器
  405 +- `search/searcher.py` - 搜索器(集成布尔解析)
  406 +
  407 +### 5.2 多语言搜索
  408 +
  409 +**实现情况**:
  410 +
  411 +#### 工作原理
  412 +1. **查询解析**:
  413 + - 提取域(如 `title:查询` → 域=`title`,查询=`查询`)
  414 + - 检测查询语言
  415 + - 生成翻译
  416 +2. **多语言查询构建**:
  417 + - 如果域有 `language_field_mapping`:
  418 + - 使用检测到的语言查询对应字段(boost * 1.5)
  419 + - 使用翻译后的查询搜索其他语言字段(boost * 1.0)
  420 + - 如果域没有 `language_field_mapping`:
  421 + - 使用所有字段进行搜索
  422 +3. **查询组合**:
  423 + - 多个语言查询组合为 `should` 子句
  424 + - 提高召回率
  425 +
  426 +#### 示例
  427 +```
  428 +查询: "芭比娃娃"
  429 +域: default
  430 +检测语言: zh
  431 +
  432 +生成的查询:
  433 +- 中文查询 "芭比娃娃" → 搜索 name, categoryName, brandName (boost * 1.5)
  434 +- 英文翻译 "Barbie doll" → 搜索 enSpuName (boost * 1.0)
  435 +- 俄文翻译 "Кукла Барби" → 搜索 ruSkuName (boost * 1.0)
  436 +```
  437 +
  438 +#### 实现模块
  439 +- `search/multilang_query_builder.py` - 多语言查询构建器
  440 +- `search/searcher.py` - 搜索器(使用多语言构建器)
  441 +
  442 +### 5.3 相关性计算(Ranking)
  443 +
  444 +**实现情况**:
  445 +
  446 +#### 当前实现
  447 +**公式**:`bm25() + 0.2 * text_embedding_relevance()`
  448 +
  449 +- **bm25()**:BM25 文本相关性得分
  450 + - 包括多语言打分
  451 + - 内部通过配置翻译为多种语言
  452 + - 分别到对应的字段搜索
  453 + - 中文字段使用中文分词器,英文字段使用英文分词器
  454 +- **text_embedding_relevance()**:文本向量相关性得分(KNN 检索的打分)
  455 + - 权重:0.2
  456 +
  457 +#### 配置方式
  458 +```yaml
  459 +ranking:
  460 + expression: "bm25() + 0.2*text_embedding_relevance()"
  461 + description: "BM25 text relevance combined with semantic embedding similarity"
  462 +```
  463 +
  464 +#### 扩展性
  465 +- 支持表达式配置(未来可扩展)
  466 +- 支持自定义函数(如 `timeliness()`, `field_value()`)
  467 +
  468 +#### 实现模块
  469 +- `search/ranking_engine.py` - 排序引擎
  470 +- `search/searcher.py` - 搜索器(集成排序功能)
15 471
16 -但是,各个租户,可能有不一样的业务数据,比如不同租户有不同的属性的体系、不同语言的商品标题(一般至少有中英文两种满足跨境的搜索需求),有不同的权重(提权)字段、业务过滤和聚合字段。  
17 -能够统一的 只能是 sku表 按照一套配置规范、做一个配置文件,按照配置文件建设ES mapping结构以及做数据的入库。 472 +---
18 473
19 -1. 应用结构配置 : 定义了ES的输入数据有哪些字段、关联mysql的哪些字段.  
20 - 请帮我补充具体实现的一些配置 474 +## 6. 已完成功能总结
21 475
  476 +### 6.1 配置系统
  477 +- ✅ 字段定义配置(类型、分析器、来源表/列)
  478 +- ✅ 索引域配置(多域查询、多语言映射)
  479 +- ✅ 查询配置(改写词典、翻译配置)
  480 +- ✅ 排序配置(表达式配置)
  481 +- ✅ 配置验证(字段存在性、类型检查、分析器匹配)
22 482
23 -2。 索引结构配置 : 定义了ES的字段,每个字段的索引mapping配置,支持各个域的查询,包括默认的域的查询。索引配置预定一号了一堆分析方式  
24 - 请帮我补充具体实现的一些配置 483 +### 6.2 数据索引
  484 +- ✅ 数据转换(字段映射、类型转换)
  485 +- ✅ 向量生成(文本向量、图片向量)
  486 +- ✅ 向量缓存(避免重复计算)
  487 +- ✅ 批量索引(错误处理、重试机制)
  488 +- ✅ ES mapping 自动生成
25 489
26 -## 测试数据灌入 490 +### 6.3 查询处理
  491 +- ✅ 查询改写(词典配置)
  492 +- ✅ 语言检测
  493 +- ✅ 多语言翻译(DeepL API)
  494 +- ✅ 文本向量化(BGE-M3)
  495 +- ✅ 域提取(支持 `domain:query` 语法)
27 496
28 -灌入数据、mysql到ES的自动同步,不在本项目的范围内,但是,该项目 为了提供测试数据,需要 构造一个实例 customer1.  
29 -我们为他构造一套应用配置和索引配置。  
30 -暂时是随机抽了我们自己的1w数据,建设辅助表,然后写一个程序,将数据分别灌入主表和辅表。 497 +### 6.4 搜索功能
  498 +- ✅ 布尔表达式解析(AND, OR, RANK, ANDNOT, 括号)
  499 +- ✅ 多语言查询构建(语言路由、字段映射)
  500 +- ✅ 语义搜索(KNN 检索)
  501 +- ✅ 相关性排序(BM25 + 向量相似度)
  502 +- ✅ 结果聚合(Faceted Search)
31 503
32 -请帮我补充具体,当前测试数据灌入的具体的配置和方式,比如辅助表的内容 对应的应用结构配置 索引配置 等等。 504 +### 6.5 API 服务
  505 +- ✅ RESTful API(FastAPI)
  506 +- ✅ 搜索接口(文本搜索、图片搜索)
  507 +- ✅ 文档查询接口
  508 +- ✅ 前端界面(HTML + JavaScript)
33 509
34 -## queryParser 510 +---
35 511
36 -1. 查询改写。 配置词典的key是query,value是改写后的查询表达式,比如。比如品牌词 改写为在brand|query OR name|query,类别词、标签词等都可以放进去。纠错、规范化、查询改写等 都可以通过这个词典来配置。  
37 -2. 翻译。配置需要得到的几种目标语言。 在customer1测试案例中,我们配置 zh en两种语言。先对query做语言检测,如果query是中文那么要翻译一下en,如果是en那么要翻译zh,如果两者都不是那么zh en都需要翻译。  
38 -3. 如果配置打开了text_embedding查询,并且query 包含了default域的查询,那么要把default域的查询词转向量,后面searcher会用这个向量参与查询。 512 +## 7. 技术栈
39 513
40 -也帮我补充一些具体实现情况 514 +- **后端**:Python 3.6+
  515 +- **搜索引擎**:Elasticsearch
  516 +- **数据库**:MySQL(Shoplazza)
  517 +- **向量模型**:BGE-M3(文本)、CN-CLIP(图片)
  518 +- **翻译服务**:DeepL API
  519 +- **API 框架**:FastAPI
  520 +- **前端**:HTML + JavaScript
41 521
42 -## searcher 522 +---
43 523
44 -支持多种检索表达式:  
45 -支持多种匹配方式,如AND、OR、RANK、NOTAND以及(),优先级从高到低为(),ANDNOT,AND,OR,RANK。 524 +## 8. 配置文件示例
46 525
47 -## default域的相关性,是代码里面单独计算,是特定的深度定制优化的,暂时不做配置化。 526 +完整配置示例请参考:`config/schema/customer1_config.yaml`
48 527
49 -暂时具体实现为 bm25()+0.2*text_embedding_relevence(也就是knn检索表达式的打分)  
50 -bm25() 包括多语言的打分:内部需要通过配置翻译为多种语言(配置几种目标语言 默认中文、英文,并且设置对应的检索域),然后分别到对应的字段搜索,中文字段到配置的中文title搜索,英文到对应的英文title搜索。 528 +---
51 529
52 -也帮我补充一些具体实现情况 530 +## 9. 相关文档
53 531
  532 +- `MULTILANG_FEATURE.md` - 多语言功能详细说明
  533 +- `QUICKSTART.md` - 快速开始指南
  534 +- `HighLevelDesign.md` - 高层设计文档
  535 +- `IMPLEMENTATION_SUMMARY.md` - 实现总结
  536 +- `商品数据源入ES配置规范.md` - 数据源配置规范