11 Mar, 2026
1 commit
10 Mar, 2026
4 commits
-
- 配置改为“字段基名 + 动态语言后缀”方案,已不再依赖旧 `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
09 Mar, 2026
2 commits
-
CNCLIP_DEVICE=cuda TEI_USE_GPU=1 ./scripts/service_ctl.sh start 搜索后端+indexer+测试前段+4个微服务 跑通
07 Mar, 2026
2 commits
05 Feb, 2026
2 commits
-
- 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>
27 Jan, 2026
2 commits
-
- config: 新增 SUPPORTED_INDEX_LANGUAGES(38 种语言)、DEFAULT_INDEX_LANGUAGES、 normalize_index_languages、resolve_index_languages;get_tenant_config 统一注入 index_languages - config.yaml: 租户配置改用 index_languages,默认 [en,zh],保留 translate_to_* 兼容解析 - query/translator: translate_for_indexing 改为接收 index_languages,返回多语言 Dict - query/query_parser: 翻译目标从 index_languages 解析,need_wait_translation 按 index_langs 判断 - search/searcher: enable_translation 改为基于 index_languages 是否非空 - indexer: document_transformer 按 index_languages 填多语言字段;indexing_utils 仅多语言时初始化翻译器 - tests: 租户配置与索引测试改为断言 index_languages - README: 更新 TODO 说明已支持 index_languages
-
2. 返回query_normlized
06 Jan, 2026
1 commit
31 Dec, 2025
1 commit
27 Dec, 2025
1 commit
20 Dec, 2025
1 commit
18 Dec, 2025
1 commit
-
config/config_loader.py: 从 QueryConfig 类中删除 enable_translation 字段 config/config.yaml: 删除 enable_translation: true 配置项 config/config_loader.py: 从 to_dict() 方法中删除相关输出 2. 索引阶段(离线)- 使用租户配置 indexer/indexing_utils.py: 根据 tenant_config.translate_to_en 和 translate_to_zh 决定是否初始化 translator 只有任一方向开启时才创建 translator indexer/document_transformer.py: _fill_text_fields 从 tenant_config 读取 translate_to_en 和 translate_to_zh 调用 translate_for_indexing 时传递这两个参数 更新了文档注释 3. 查询阶段(在线)- 使用租户配置 query/query_parser.py: parse() 方法新增 tenant_id 参数 根据租户配置决定翻译目标语言(translate_to_zh / translate_to_en) 如果两个都是 false,跳过翻译阶段 translator 属性不再依赖 enable_translation,总是可以初始化 search/searcher.py: search() 方法中根据租户配置计算 enable_translation(用于日志和 metadata) 调用 query_parser.parse() 时传递 tenant_id 4. 翻译器方法更新 query/translator.py: translate_for_indexing() 新增 translate_to_en 和 translate_to_zh 参数(默认 True 保持向后兼容) 根据这两个参数决定翻译目标 更新了文档注释
08 Dec, 2025
1 commit
05 Dec, 2025
1 commit
-
将 must 子句改为 should 子句的多查询策略 实现以下查询类型: base_query:主查询,使用 AND 操作符和 75% minimum_should_match 翻译查询:跨语言查询,boost=0.4 短语查询:短查询的精确短语匹配 关键词查询:基于提取名词的查询,boost=0.1 添加 _get_match_fields() 方法,支持中英文字段动态映射 4. 关键改进点 minimum_should_match 从 67% 提升到 75% 添加 operator: "AND" 确保所有词都匹配 使用 should 子句实现多策略融合 支持短语查询和关键词查询的智能触发
04 Dec, 2025
1 commit
-
核心功能: - 添加 multi_select 字段到 FacetConfig(默认为 true) - 实现 post_filter 支持 disjunctive faceting - 后端自动标记 facet 值的 selected 状态 - 支持 specifications 和普通字段的 multi-select 技术改进: - ESQueryBuilder: 分离 conjunctive/disjunctive filters - ResultFormatter: 根据 current_filters 标记 selected - Searcher: 传递 facet_configs 给 query builder 文档更新: - 添加 multi_select_faceting.md 详细文档 - 更新 API 对接指南,说明新功能 - 添加测试脚本 test_multi_select_facet.py 业界标准: - 遵循 Elasticsearch/Algolia/Amazon 的最佳实践 - 提供探索式搜索体验 - 前后端职责清晰分离
03 Dec, 2025
2 commits
-
{ "facets": [ { "field": "category1_name", "size": 15, "type": "terms" }, "specifications.color", "specifications.size" ] } { "facets": [ {"field": "category1_name", "size": 15, "type": "terms"}, {"field": "specifications.color", "size": 10, "type": "terms"}, {"field": "specifications.size", "size": 10, "type": "terms"} ] } 之前是上面的接口形式,主要是考虑 属性的分面, 因为 款式都是有限的 不需要设定 "size": 10, "type": "terms" 这些参数。 但是从接口设计层面,最好按下面这样,这样的话 specifications.color 和 category1_name 的组装格式 完全一样。前端不需要感知 属性分面 和 类别等其他字段分面的差异。
02 Dec, 2025
2 commits
-
后端请求模型变更(api/models.py) SearchRequest.sku_filter_dimension 从 Optional[str] 改为 Optional[List[str]]。 语义:列表表示一个或多个“维度标签”,例如: 单维度:["color"]、["option1"] 多维度:["color", "size"]、["option1", "option2"] 描述更新为:对 维度组合进行分组,每个组合只保留一个 SKU。 结果格式化与去重逻辑(api/result_formatter.py) ResultFormatter.format_search_results(..., sku_filter_dimension: Optional[List[str]] = None),调用处已同步更新。 单维度旧逻辑升级为多维度逻辑: 新方法:_filter_skus_by_dimensions(skus, dimensions, option1_name, option2_name, option3_name, specifications)。 维度解析规则(按顺序处理,并去重): 若维度是 option1 / option2 / option3 → 对应 option1_value / option2_value / option3_value。 否则,将维度字符串转小写后,分别与 option1_name / option2_name / option3_name 对比,相等则映射到对应的 option*_value。 未能映射到任何字段的维度会被忽略。 对每个 SKU: 按解析出的字段列表(例如 ["option1_value", "option2_value"])取值,组成 key,如 ("red", "L");None 用空串 ""。 按 key 分组,每个 key 只保留遇到的第一个 SKU。 若列表为空或所有维度都无法解析,则 不做过滤,返回原始 skus。 Searcher 参数类型同步(search/searcher.py) Searcher.search(...) 中 sku_filter_dimension 参数类型从 Optional[str] 改为 Optional[List[str]]。 传给 ResultFormatter.format_search_results 时,直接传该列表。 前端参数格式调整(frontend/static/js/app.js) 输入框 #skuFilterDimension 依旧是一个文本框,但解析方式改为: 函数 getSkuFilterDimension(): 读取文本,如:"color" 或 "color,size" 或 "option1, color"。 用逗号 , 拆分,trim() 后过滤空串,返回 字符串数组,例如: "color" → ["color"] "color,size" → ["color", "size"] 若最终数组为空,则返回 null。 搜索请求体中仍使用字段名 sku_filter_dimension,但现在值是 string[] 或 null: body: JSON.stringify({ // ... sku_filter_dimension: skuFilterDimension, // 例如 ["color", "size"] debug: state.debug }) 文档更新(docs/搜索API对接指南.md) 请求体示例中的类型由: "sku_filter_dimension": "string" 改为: "sku_filter_dimension": ["string"] 参数表中: 从 string 改为 array[string],说明为“维度列表,按组合分组,每个组合保留一个 SKU”。 功能说明章节“SKU筛选维度 (sku_filter_dimension)”已调整为 列表语义 + 组合去重,并补充了示例: 单维度: { "query": "芭比娃娃", "sku_filter_dimension": ["color"] } 多维度组合: { "query": "芭比娃娃", "sku_filter_dimension": ["color", "size"] } 使用方式总结 单维度去重(保持旧行为的等价写法) 旧:"sku_filter_dimension": "color" 新:"sku_filter_dimension": ["color"] 多维度组合去重(你新提的需求) 例如希望“每个 SPU 下,同一颜色+尺码组合只保留一个 SKU”: { "query": "芭比娃娃", "sku_filter_dimension": ["color", "size"] } -
query config/ranking config优化
01 Dec, 2025
1 commit
27 Nov, 2025
2 commits
-
1. 搜索API对接指南.md 在“精确匹配过滤器”部分添加了 specifications 嵌套过滤说明 支持单个规格过滤和多个规格过滤(OR 逻辑) 在“分面配置”部分完善了 specifications 分面说明 添加了两种分面模式:所有规格名称和指定规格名称 在“常见场景示例”部分添加了场景5-8,包含规格过滤和分面的完整示例 2. 搜索API速查表.md 在“精确匹配过滤”部分添加了 specifications 过滤的快速参考 在“分面搜索”部分添加了 specifications 分面的快速参考 更新了完整示例,包含 specifications 的使用 3. Search-API-Examples.md 在“过滤器使用”部分添加了示例4-6,展示 specifications 过滤 在“分面搜索”部分添加了示例2-3,展示 specifications 分面 更新了 Python 和 JavaScript 完整示例,包含 specifications 的使用 在“常见使用场景”部分添加了场景2.1,展示带规格过滤的搜索结果页 4. 索引字段说明v2.md 更新了 specifications 字段的查询示例,包含 API 格式和 ES 查询结构 添加了两种分面模式的说明和示例 更新了“分面字段”说明,明确支持指定规格名称的分面 5. 补充参数 参数说明:sku_filter_dimension 是可选参数,用于按指定维度过滤每个SPU下的SKU 支持的维度: 直接选项字段:option1、option2、option3 规格名称:通过 option1_name、option2_name、option3_name 匹配(如 color、size)
-
1. 前端传递的过滤条件永远是要起作用的 2. 然后召回模块包括文本相关性召回(中英文都是用)和向量召回,两者相互补充。 3. 套用function_score以支持两种打分融合和各种提权字段 4. 只需要build_query 这一层。 实际操作: 1. 架构简化 移除了 MultiLanguageQueryBuilder 层级 只保留单层的 ESQueryBuilder.build_query 方法 2. 查询结构重构 实现了 filters and (text_recall or embedding_recall) 结构: 前端过滤条件:永远起作用(放在 filter 中) 文本召回:同时搜索中英文字段(multi_match 覆盖 title_zh/en, brief_zh/en 等) 向量召回:KNN 查询(独立参数,ES 会自动合并) Function_score:包装召回部分,支持提权字段配置 3. 文本匹配字段更新 在 DEFAULT_MATCH_FIELDS 中添加了中英文字段: 中文:title_zh, brief_zh, description_zh, vendor_zh, category_path_zh, category_name_zh 英文:title_en, brief_en, description_en, vendor_en, category_path_en, category_name_en 语言无关:tags 4. Function_score 框架保留 保留了 function_score 配置框架(FUNCTION_SCORE_CONFIG) 支持 filter_weight、field_value_factor、decay 等提权函数 可以从配置中扩展提权字段 5. 测试验证 所有功能测试通过: 基本文本搜索 带过滤条件的搜索 范围过滤 分面搜索 英文查询
26 Nov, 2025
2 commits
14 Nov, 2025
3 commits
-
2. 向量服务不用本地预估,改用网络服务
13 Nov, 2025
2 commits
-
主要变更: 1. 去掉数据源应用结构配置化,我们只针对店匠的spu sku表设计索引,数据灌入流程是写死的(只是满足测试需求,后面外层应用负责数据全量+增量灌入)。搜索系统主要关注如何适配外部搜索需求 目前有两个数据灌入脚本,一种是之前的,一种是现在的从两个店匠的表sku表+spu表读取并且以spu为单位组织doc。 - 配置只关注ES搜索相关配置,提高可维护性 - 创建base配置(店匠通用配置) 2. 索引结构重构(SPU维度) - 所有客户共享search_products索引,通过tenant_id隔离 - 支持嵌套variants字段(SKU变体数组) - 创建SPUTransformer用于SPU数据转换 3. API响应格式优化 - 约定一套搜索结果的格式,而不是直接暴露ES doc的结构(_id _score _source内的字段) - 添加ProductResult和VariantResult模型 - 添加suggestions和related_searches字段 (预留接口,逻辑暂未实现) 4. 数据导入流程 - 创建店匠数据导入脚本(ingest_shoplazza.py) - Pipeline层决定数据源,配置不包含数据源信息 - 创建测试数据生成和导入脚本 5. 文档更新 - 更新设计文档,反映新架构 - 创建BASE_CONFIG_GUIDE.md使用指南
12 Nov, 2025
4 commits
-
核心改动: 1. 修复facets类型问题 - 统一使用Pydantic模型(FacetResult, FacetValue) - SearchResult.facets改为List[FacetResult] - _standardize_facets直接构建Pydantic对象 2. 修复RangeFilter支持日期时间 - RangeFilter字段改为Union[float, str] - 支持数值范围和ISO日期时间字符串 - 修复前端listing time筛选422错误 3. 重构ES查询结构(核心) - 使用function_score包裹整个查询 - 文本和KNN放入内层bool.should(minimum_should_match=1) - Filter在外层bool,同时作用于文本和KNN查询 - 添加时效性加权函数(days_since_last_update<=30 weight:1.1) 4. RankingEngine重构 - 重命名为RerankEngine(语义更准确) - 默认禁用(enabled=False) - 优先使用ES的function_score打分 5. 统一约定原则 - 移除所有字典兼容代码 - 全系统统一使用Pydantic模型 - build_facets只接受str或FacetConfig - _build_filters直接接受RangeFilter模型 修改文件: - search/multilang_query_builder.py: 重构查询构建逻辑 - search/es_query_builder.py: 统一Pydantic模型支持 - search/searcher.py: 使用RerankEngine,更新导入 - search/rerank_engine.py: 新建(从ranking_engine.py重命名) - search/ranking_engine.py: 删除 - search/__init__.py: 更新导出 - api/models.py: RangeFilter支持Union[float, str] 测试验证: ✓ Facets正常返回 ✓ Filter同时作用于文本和KNN ✓ 日期时间范围过滤正常 ✓ Function score时效性加权正常 ✓ 所有测试通过 架构原则:统一约定,不做兼容,保持简单
11 Nov, 2025
1 commit