15 Apr, 2026

1 commit

  •  修改内容
    
    1. **新增配置项** (`config/config.yaml`)
       - `exact_knn_rescore_enabled`: 是否开启精确向量重打分,默认 true
       - `exact_knn_rescore_window`: 重打分窗口大小,默认 160(与 rerank_window 解耦,可独立配置)
    
    2. **ES 查询层改造** (`search/searcher.py`)
       - 在第一次 ES 搜索中,根据配置为 window_size 内的文档注入 rescore 阶段
       - rescore_query 中包含两个 named script_score 子句:
         - `exact_text_knn_query`: 对文本向量执行精确点积
         - `exact_image_knn_query`: 对图片向量执行精确点积
       - 当前采用 `score_mode=total` 且 `rescore_query_weight=0.0`,**只补分不改排序**,exact 分仅出现在 `matched_queries` 中
    
    3. **统一向量得分 Boost 逻辑** (`search/es_query_builder.py`)
       - 新增 `_get_knn_plan()` 方法,集中管理文本/图片 KNN 的 boost 计算规则
       - 支持长查询(token 数超过阈值)时文本 boost 额外乘 1.4 倍
       - 精确 rescore 与 ANN 召回**共用同一套 boost 规则**,确保分数量纲一致
       - 原有 ANN 查询构建逻辑同步迁移至该统一入口
    
    4. **融合阶段得分优先级调整** (`search/rerank_client.py`)
       - `_build_hit_signal_bundle()` 中统一处理向量得分读取
       - 优先从 `matched_queries` 读取 `exact_text_knn_query` / `exact_image_knn_query`
       - 若不存在则回退到原 `knn_query` / `image_knn_query`(ANN 得分)
       - 覆盖 coarse_rank、fine_rank、rerank 三个阶段,避免重复补丁
    
    5. **测试覆盖**
       - `tests/test_es_query_builder.py`: 验证 ANN 与 exact 共用 boost 规则
       - `tests/test_search_rerank_window.py`: 验证 rescore 窗口及 named query 正确注入
       - `tests/test_rerank_client.py`: 验证 exact 优先、回退 ANN 的逻辑
    
     技术细节
    
    - **精确向量计算脚本** (Painless)
      ```painless
      // 文本 (dotProduct + 1.0) / 2.0
      (dotProduct(params.query_vector, 'title_embedding') + 1.0) / 2.0
      // 图片同理,字段为 'image_embedding.vector'
      ```
      乘以统一的 boost(来自配置 `knn_text_boost` / `knn_image_boost` 及长查询放大因子)。
    
    - **named query 保留机制**
      - 主查询中已开启 `include_named_queries_score: true`
      - rescore 阶段命名的脚本得分会合并到每个 hit 的 `matched_queries` 中
      - 通过 `_extract_named_score()` 按名称提取,与原始 ANN 得分访问方式完全一致
    
    - **性能影响** (基于 top160、6 条真实查询、warm-up 后 3 轮平均)
      - `elasticsearch_search_primary` 耗时: 124.71ms → 136.60ms (+11.89ms, +9.53%)
      - `total_search` 受其他组件抖动影响较大,不作为主要参考
      - 该开销在可接受范围内,未出现超时或资源瓶颈
    
     配置示例
    
    ```yaml
    search:
      exact_knn_rescore_enabled: true
      exact_knn_rescore_window: 160
      knn_text_boost: 4.0
      knn_image_boost: 4.0
      long_query_token_threshold: 8
      long_query_text_boost_factor: 1.4
    ```
    
     已知问题与后续计划
    
    - 当前版本经过调参实验发现,开启 exact rescore 后部分 query(强类型约束 + 多风格/颜色相似)的主指标相比 baseline(exact=false)下降约 0.031(0.6009 → 0.5697)
    - 根因:exact 将 KNN 从稀疏辅助信号变为 dense 排序因子,coarse 阶段排序语义变化,单纯调整现有 `knn_bias/exponent` 无法完全恢复
    - 后续迭代方向:**coarse 阶段暂不强制使用 exact**,仅 fine/rerank 优先 exact;或 coarse 采用“ANN 优先,exact 只补缺失”策略,再重新评估
    
     相关文件
    
    - `config/config.yaml`
    - `search/searcher.py`
    - `search/es_query_builder.py`
    - `search/rerank_client.py`
    - `tests/test_es_query_builder.py`
    - `tests/test_search_rerank_window.py`
    - `tests/test_rerank_client.py`
    - `scripts/evaluation/exact_rescore_coarse_tuning_round2.json` (调参实验记录)
    tangwang
     

30 Mar, 2026

2 commits

  • must里面的两个combined_fields查询,boost分别设置为2和0.6,和其他查询条件一起,都放到should里面,设置minimum_should_match==1
    2.
    如果keywords_query跟combined_fields主查询的query一样,那么不需要再添加了
    tangwang
     
  • tangwang
     

27 Mar, 2026

2 commits


24 Mar, 2026

1 commit

  • 加了一个过滤/降权词典,query中有独立分词匹配到指定的触发词,将过滤带某些分词的商品(比如fitted/修身,过滤宽松、loose、relaxed、baggy,slouchy等商品)
    2. reranker的query使用翻译后的
    tangwang
     

23 Mar, 2026

3 commits


22 Mar, 2026

1 commit


20 Mar, 2026

1 commit

  • ## 背景
    多语言索引下,用户查询常中英混写;需在解析阶段显式标记脚本类型,并在 BM25 子句中同时覆盖对应语言字段。
    
    ## 方案
    
    ### 1. Query 分析(query_parser.ParsedQuery)
    - 新增 `contains_chinese`:query 文本含 CJK(沿用 _contains_cjk)。
    - 新增 `contains_english`:分词结果中存在「纯英文、len>=3」token(fullmatch 字母及可选连字符)。
    - 写入 to_dict、请求 context 中间结果,便于调试与 API 透出。
    
    ### 2. ES 文本召回(es_query_builder._build_advanced_text_query)
    - 对每个 search_lang 子句:若含英文且子句语言非 en(且租户 index_languages 含 en),合并 en 列字段;若含中文且子句语言非 zh(且含 zh),合并 zh 列字段。
    - 合并进来的字段 boost 乘以 `mixed_script_merged_field_boost_scale`(默认 0.8,可在 ESQueryBuilder 构造参数调整)。
    - fallback_original_query_* 分支同样应用上述逻辑。
    
    ### 3. 实现整理
    - 引入 `MatchFieldSpec = (field_path, boost)`:`_build_match_field_specs` 为唯一权重来源;`_merge_supplemental_lang_field_specs` / `_expand_match_field_specs_for_mixed_script` 在 tuple 上合并与缩放;最后 `_format_match_field_specs` 再格式化为 ES `path^boost`,避免先拼字符串再解析。
    
    ## 测试
    - tests/test_query_parser_mixed_language.py:脚本标记与 token 规则。
    - tests/test_es_query_builder.py:合并字段、0.8 缩放、index_languages 限制。
    
    Made-with: Cursor
    tangwang
     

18 Mar, 2026

3 commits


11 Mar, 2026

1 commit