09 Apr, 2026

2 commits

  • category_taxonomy_profile
    
    - 原 analysis_kinds
      混用了“增强类型”(content/taxonomy)与“品类特定配置”,不利于扩展不同品类的
    taxonomy 分析(如 3C、家居等)
    - 新增 enrichment_scopes 参数:支持 generic(通用增强,产出
      qanchors/enriched_tags/enriched_attributes)和
    category_taxonomy(品类增强,产出 enriched_taxonomy_attributes)
    - 新增 category_taxonomy_profile 参数:指定品类增强使用哪套
      profile(当前内置 apparel),每套 profile 包含独立的
    prompt、输出列定义、解析规则及缓存版本
    - 保留 analysis_kinds 作为兼容别名,避免破坏现有调用方
    - 重构内部 taxonomy 分析为 profile registry 模式:新增
      _get_taxonomy_schema(profile_name) 函数,根据 profile 动态返回对应的
    AnalysisSchema
    - 缓存 key 现在按“分析类型 + profile + schema 指纹 +
      输入字段哈希”隔离,确保不同品类、不同 prompt 版本自动失效
    - 更新 API 文档及微服务接口文档,明确新参数语义与使用示例
    
    技术细节:
    - 修改入口:api/routes/indexer.py 中 enrich-content
      端点,解析新参数并向下传递
    - 核心逻辑:indexer/product_enrich.py 中 enrich_products_batch 增加
      profile 参数;_process_batch_for_schema 根据 scope 和 profile 动态获取
    schema
    - 兼容层:若请求同时提供 analysis_kinds,则映射为
      enrichment_scopes(content→generic,taxonomy→category_taxonomy),category_taxonomy_profile
    默认为 "apparel"
    - 测试覆盖:新增 enrichment_scopes 组合、profile 切换及兼容模式测试
    tangwang
     
  • - `/indexer/enrich-content` 路由`enriched_taxonomy_attributes` 与
      `enriched_attributes` 一并返回
    - 新增请求参数 `analysis_kinds`(可选,默认 `["content",
      "taxonomy"]`),允许调用方按需选择内容分析类型,为后续扩展和成本控制预留空间
    - 重构缓存策略:将 `content` 与 `taxonomy` 两类分析的缓存完全隔离,缓存
      key 包含 prompt 模板、表头、输出字段定义(即 schema
    指纹),确保提示词或解析规则变更时自动失效
    - 缓存 key 仅依赖真正参与 LLM
      输入的字段(`title`、`brief`、`description`),`image_url`、`tenant_id`、`spu_id`
    不再污染缓存键,提高缓存命中率
    - 更新 API
      文档(`docs/搜索API对接指南-05-索引接口(Indexer).md`),说明新增参数与返回字段
    
    技术细节:
    - 路由层调整:在 `api/routes/indexer.py` 的 enrich-content 端点中,将
      `product_enrich.enrich_products_batch` 返回的
    `enriched_taxonomy_attributes` 字段显式加入 HTTP 响应体
    - `analysis_kinds` 参数透传至底层
      `enrich_products_batch`,支持按需跳过某一类分析(如仅需 taxonomy
    时减少 LLM 调用)
    - 缓存指纹计算位于 `product_enrich.py` 的 `_get_cache_key` 函数,对每种
      `AnalysisSchema` 独立生成;版本号通过 `schema.version` 或 prompt
    内容哈希隐式包含
    - 测试覆盖:新增 `analysis_kinds` 组合场景及缓存隔离测试
    tangwang
     

30 Mar, 2026

2 commits


23 Mar, 2026

2 commits


19 Mar, 2026

2 commits


18 Mar, 2026

1 commit

  • 核心改动在 rerank_client.py (line 99):fuse_scores_and_resort 现在按
    rerank * knn * text 的平滑乘法公式计算,优先从 hit["matched_queries"]
    里取 base_query 和 knn_query,并把 _text_score / _knn_score
    一并写回调试字段。为了让 KNN 也有名字,我给 top-level knn 加了 name:
    "knn_query",见 es_query_builder.py (line 273)。搜索执行时会在 rerank
    窗口内打开 include_named_queries_score,并在显式排序时加上
    track_scores,见 searcher.py (line 400) 和 es_client.py (line 224)。
    tangwang
     

17 Mar, 2026

1 commit

  • - Rename indexer/product_annotator.py to indexer/product_enrich.py and remove CSV-based CLI entrypoint, keeping only in-memory analyze_products API
    - Introduce dedicated product_enrich logging with separate verbose log file for full LLM requests/responses
    - Change indexer and /indexer/enrich-content API wiring to use indexer.product_enrich instead of indexer.product_annotator, updating tests and docs accordingly
    - Switch translate_prompts to share SUPPORTED_INDEX_LANGUAGES from tenant_config_loader and reuse that mapping for language code → display name
    - Remove hard SUPPORTED_LANGS constraint from LLM content-enrichment flow, driving languages directly from tenant/indexer configuration
    - Redesign LLM prompt generation to support multi-round, multi-language tables: first round in English, subsequent rounds translate the entire table (headers + cells) into target languages using English instructions
    tangwang
     

16 Mar, 2026

2 commits


13 Mar, 2026

4 commits


12 Mar, 2026

1 commit


11 Mar, 2026

3 commits


10 Mar, 2026

3 commits

  • tangwang
     
  • - 配置改为“字段基名 + 动态语言后缀”方案,已不再依赖旧 `indexes`。
    [config.yaml](/data/saas-search/config/config.yaml#L17)
    - `search_fields` / `text_query_strategy` 已进入强校验与解析流程。
    [config_loader.py](/data/saas-search/config/config_loader.py#L254)
    
    2. 查询语言计划与翻译等待策略
    - `QueryParser` 现在产出
      `query_text_by_lang`、`search_langs`、`source_in_index_languages`。
    [query_parser.py](/data/saas-search/query/query_parser.py#L41)
    - 你要求的两种翻译路径都在:
      - 源语言不在店铺 `index_languages`:`translate_multi_async` + 等待
        future
      - 源语言在 `index_languages`:`translate_multi(...,
        async_mode=True)`,尽量走缓存
    [query_parser.py](/data/saas-search/query/query_parser.py#L284)
    
    3. ES 查询统一文本策略(无 AST 分支)
    - 主召回按 `search_langs` 动态拼 `field.{lang}`,翻译语种做次权重
      `should`。
    [es_query_builder.py](/data/saas-search/search/es_query_builder.py#L454)
    - 布尔 AST 路径已删除,仅保留统一文本策略。
    [es_query_builder.py](/data/saas-search/search/es_query_builder.py#L185)
    
    4. LanguageDetector 优化
    - 从“拉丁字母默认英文”升级为:脚本优先 +
      拉丁语系打分(词典/变音/后缀)。
    [language_detector.py](/data/saas-search/query/language_detector.py#L68)
    
    5. 布尔能力清理(补充)
    - 已删除废弃模块:
    [boolean_parser.py](/data/saas-search/search/boolean_parser.py)
    - `search/__init__` 已无相关导出。
    [search/__init__.py](/data/saas-search/search/__init__.py)
    
    6. `indexes` 过时收口(补充)
    - 兼容函数改为基于动态字段生成,不再依赖 `config.indexes`。
    [utils.py](/data/saas-search/config/utils.py#L24)
    - Admin 配置接口改为返回动态字段配置,不再暴露 `num_indexes`。
    [admin.py](/data/saas-search/api/routes/admin.py#L52)
    
    7. suggest
    tangwang
     
  • tangwang
     

09 Mar, 2026

2 commits


02 Mar, 2026

3 commits

  • - 新增 suggestion 模块(mapping/builder/service),支持按租户构建 `search_suggestions_tenant_{tenant_id}` 索引
    - 新增 `main.py build-suggestions` CLI 与 `scripts/build_suggestions.sh`,支持基于商品 title/qanchors 与近 365 天搜索日志的全量构建
    - 实现 `/search/suggestions` 接口(多语言 + 结果直达),并接入前端自动补全使用新的后端 API
    - 为 suggestion 增加 `README` / `RUNBOOK` / `TROUBLESHOOTING` 文档,更新搜索 API 对接指南与速查表
    - 补充 `tests/test_suggestions.py` 单元测试,覆盖语言解析和 SuggestionService 查询流程
    
    Made-with: Cursor
    tangwang
     
  • - 新增 `suggestion` 模块:
      - `suggestion/mapping.py`:`search_suggestions` mapping 生成(多语言 `completion` + `search_as_you_type`)
      - `suggestion/builder.py`:全量构建程序(扫描 `search_products` 的 `title/qanchors` + MySQL `shoplazza_search_log`)
      - `suggestion/service.py`:在线查询服务(suggestion 检索 + 结果直达商品二次查询)
      - `suggestion/__init__.py`
    
    - 接入 API 服务初始化:
      - `api/app.py` 新增 `SuggestionService` 初始化和 `get_suggestion_service()`
    
    - 接口实现:
      - `api/routes/search.py` 的 `GET /search/suggestions` 从“空框架”改为真实调用
      - 支持参数:
        - `q`, `size`, `language`
        - `with_results`(是否直达商品)
        - `result_size`(每条 suggestion 商品数)
        - `debug`
      - 继续要求 `X-Tenant-ID`(或 query 的 `tenant_id`)
    
    - 模型补充:
      - `api/models.py` 增加 suggestion 请求/响应字段(`language`, `resolved_language`, `with_results`, `result_size`)
    
    - CLI 全量构建命令:
      - `main.py` 新增 `build-suggestions`
      - 使用方式:
        - `python main.py build-suggestions --tenant-id 1 --recreate`
        - 可选:`--days 30 --batch-size 500 --min-query-len 1 --es-host ...`
    
    ---
    
     关键实现逻辑(已编码)
    
    - 语言归属优先级(按你要求):
      - `shoplazza_search_log.language` > `request_params.language` > 脚本/模型兜底
    - 候选词聚合键:
      - `(tenant_id, lang, text_norm)`(文档唯一)
    - 评分:
      - 基于 `query_count_30d/7d + qanchor_doc_count + title_doc_count` 的离线分
    - 结果直达:
      - 对每条 suggestion 在 `search_products_tenant_{id}` 做二次查询(`qanchors/title` 组合)
    
    ---
    
     变更文件
    
    - `api/app.py`
    - `api/models.py`
    - `api/routes/search.py`
    - `main.py`
    - `suggestion/__init__.py`
    - `suggestion/mapping.py`
    - `suggestion/builder.py`
    - `suggestion/service.py`
    tangwang
     
  • - 新增 /indexer/build-docs 与 /indexer/build-docs-from-db 接口:前者接收上游传入的 SPU/SKU/Option 原始行数据构建 ES doc(不写 ES),后者在测试场景下基于 tenant_id+spu_ids 内部查库并复用同一套文档构建逻辑
    - 调整增量与全量索引 SQL 与聚合逻辑:移除 shoplazza_product_spu.compare_at_price 读取,统一从 SKU 表聚合最大 compare_at_price,修复 1054 列不存在错误,保证 ES 字段 compare_at_price 来源与索引字段说明v2 保持一致
    - 更新 SPUDocumentTransformer:完善价格区间计算、compare_at_price 聚合以及多语言字段输出,确保输出结构与 mappings/search_products.json、Java 侧 ProductIndexDocument 完全对齐
    - 为 indexer 模块补充 README 与 prompts:系统化说明 Java 调度 + Python 富化的职责划分、翻译缓存方案(Redis translation:{tenant_id}:{target_lang}:{md5(text)})以及 HTTP 接口使用方式
    - 更新顶层 README、搜索API对接指南与测试Pipeline说明:增加关于 indexer 专用服务(serve-indexer, 端口6004)、正式文档构建接口以及手动链路验证(MySQL → build-docs → ES 查询对比)的说明
    - 清理并修正 ES 诊断脚本 docs/常用查询 - ES.md:统一改为 per-tenant 索引 search_products_tenant_{tenant_id},修正过期字段名(keywords 等)和分面聚合字段(去掉 .keyword,使用当前 mapping 中的字段)
    
    Made-with: Cursor
    tangwang
     

05 Feb, 2026

2 commits

  • tangwang
     
  • - API:新增请求参数 ai_search,开启时在窗口内走重排流程
    - 配置:RerankConfig 移除 enabled/expression/description,仅保留 rerank_window 及
      service_url/timeout_sec/weight_es/weight_ai;默认超时 15s
    - 重排流程:ai_search 且 from+size<=rerank_window 时,ES 取前 rerank_window 条,
      调用外部 /rerank 服务,融合 ES 与重排分数后按 from/size 分页;否则不重排
    - search/rerank_client:新增模块,封装 build_docs、call_rerank_service、
      fuse_scores_and_resort、run_rerank;超时单独捕获并简短日志
    - search/searcher:移除 RerankEngine,enable_rerank=ai_search,使用 config.rerank 参数
    - 删除 search/rerank_engine.py(本地表达式重排),统一为外部服务一种实现
    - 文档:搜索 API 对接指南补充 ai_search 与 relevance_score 说明
    - 测试:conftest 中 rerank 配置改为新结构
    
    Co-authored-by: Cursor <cursoragent@cursor.com>
    tangwang
     

26 Jan, 2026

1 commit


06 Jan, 2026

1 commit


27 Dec, 2025

1 commit


19 Dec, 2025

1 commit

  • 1. 添加 asyncio 导入
    在文件顶部添加 import asyncio,用于在线程池中执行同步阻塞操作
    2. 修改 /indexer/reindex 路由(全量索引)
    使用 loop.run_in_executor() 将 service.bulk_index() 放到线程池执行
    避免阻塞事件循环,允许其他请求并行处理
    3. 修改 /indexer/index 路由(增量索引)
    使用 loop.run_in_executor() 将 service.index_spus_to_es() 放到线程池执行
    确保全量索引和增量索引可以并行执行
    工作原理
    线程池执行:同步阻塞操作(如数据库查询、ES 写入)在线程池中执行,不阻塞事件循环
    并发支持:
    全量索引占用一个线程
    增量索引可同时使用其他线程
    多个增量请求可并行处理
    资源管理:
    数据库连接池(pool_size=10, max_overflow=20)可支持并发请求
    uvicorn 默认线程池(40 个线程)可处理多个并发请求
    tangwang
     

18 Dec, 2025

2 commits

  • 新增:scripts/recreate_index.py
    功能:初始化 indexer 的 ES/DB 服务,然后调用 BulkIndexingService.bulk_index(…, recreate_index=True) 为指定 tenant_id 做「删除并重建索引 + 全量导入」。
    用法示例:
    cd /home/tw/SearchEngine# 使用默认 batch_size=500python scripts/recreate_index.py 162# 指定 batch_sizepython scripts/recreate_index.py 162 --batch-size 1000
    脚本依赖和 Indexer API 一样的环境变量:DB_HOST/DB_PORT/DB_DATABASE/DB_USERNAME/DB_PASSWORD、ES_HOST/ES_USERNAME/ES_PASSWORD。
    2. 清理与引用更新
    原来的 scripts/recreate_index.sh 已经删除。
    api/routes/indexer.py 里的说明改成引用 scripts/recreate_index.py。
    docs/搜索API对接指南.md 中的提示也从 .sh 改为:
    > python scripts/recreate_index.py <tenant_id> [--batch-size 500]
    tangwang
     
  • 新增 api/indexer_app.py,在独立进程(默认 6004)中初始化 ES + DB + 索引服务,并复用 api/routes/indexer.py 一套路由
    新增 api/service_registry.py,通过注册表向索引路由注入 ES 客户端和索引服务,消除重复代码与循环依赖
    main.py 增加 serve-indexer 子命令;scripts/start.sh / stop.sh / start_backend.sh / start_indexer.sh 支持独立管理索引进程
    文档中所有索引相关示例由 6002/indexer/* 统一调整为 6004/indexer/*
    tangwang
     

09 Dec, 2025

2 commits


08 Dec, 2025

2 commits

  • 新增功能:
    - 新增 POST /indexer/index 增量索引接口,支持按SPU ID列表进行增量索引
    - 新增 indexer/indexer_logger.py 索引日志模块,统一记录全量和增量索引日志到 logs/indexer.log(JSON格式)
    - IncrementalIndexerService 新增 index_spus_to_es 方法,实现增量索引功能
    
    接口重命名:
    - POST /indexer/bulk -> POST /indexer/reindex(全量重建索引)
    - POST /indexer/incremental -> POST /indexer/index(增量索引)
    - POST /indexer/spus -> POST /indexer/documents(查询文档)
    
    日志系统:
    - 全量和增量索引操作统一记录到 logs/indexer.log
    - 记录请求参数、处理过程、ES写入结果、成功/失败统计等关键信息
    - 支持按索引类型、租户ID、SPU ID等维度查询日志
    
    文档更新:
    - 更新接口文档,包含新的接口命名和增量索引接口说明
    - 添加日志查询示例(grep和jq两种方式)
    tangwang
     
  • - 新增批量索引接口: POST /indexer/bulk - 全量索引功能
      - SPU接口改进: POST /indexer/spus - 支持批量获取SPU文档(最多100个)
    
    新增 全量索引服务
    indexer/bulk_indexing_service.py
    
    docs/搜索API对接指南.md
      - 新增索引接口文档: 详细的批量索引和SPU索引接口说明
      - 请求示例: 提供完整的curl命令示例
    tangwang