From 001b488959c30296277dd112463ad004d81d4e3d Mon Sep 17 00:00:00 2001 From: tangwang Date: Sat, 24 Jan 2026 15:05:54 +0800 Subject: [PATCH] 1. docs 2. 设置sku_filter_dimension参数的默认值为option1 --- api/models.py | 2 +- docs/UA-站内全站埋点数据结构定义.md | 105 --------------------------------------------------------------------------------------------------------- docs/blog/语义搜索.md | 15 +-------------- docs/对话式智能导购设计.md | 464 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ docs/搜索推荐数据.md | 353 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/static/js/tenant_facets_config.js | 51 ++++++++++++++++++++++++++++++++++++--------------- 6 files changed, 855 insertions(+), 135 deletions(-) delete mode 100644 docs/UA-站内全站埋点数据结构定义.md create mode 100644 docs/对话式智能导购设计.md create mode 100644 docs/搜索推荐数据.md diff --git a/api/models.py b/api/models.py index 661c24d..9c741b3 100644 --- a/api/models.py +++ b/api/models.py @@ -154,7 +154,7 @@ class SearchRequest(BaseModel): # SKU筛选参数 sku_filter_dimension: Optional[List[str]] = Field( - None, + ["option1"], description=( "子SKU筛选维度(店铺配置),为字符串列表。" "指定后,每个SPU下的SKU将按这些维度的组合进行分组,每个维度组合只保留一个SKU返回。" diff --git a/docs/UA-站内全站埋点数据结构定义.md b/docs/UA-站内全站埋点数据结构定义.md deleted file mode 100644 index 03df517..0000000 --- a/docs/UA-站内全站埋点数据结构定义.md +++ /dev/null @@ -1,105 +0,0 @@ -# UA 站内全站埋点数据结构定义(推荐/搜索/画像统一口径) - -本文档用于定义站内全量行为采集(基于“全站埋点采集”,可落地到神策 JS SDK 二次开发),覆盖推荐、搜索、画像、转化分析等核心场景。 - -## 1. 目标与约束 - -- **目标**:用一套统一事件模型覆盖全站行为(Pageview / Exposure / Click / View Product / Add to Cart / Purchase / Search&Filtering / Cart&Checkout)。 -- **约束**:事件需要能在“推荐/搜索请求”与“曝光-点击-加购”等链路上串联;同时需要能表达购物车/结账阶段的状态快照,用于搭配、互补、凑单、替代品推荐。 - -## 2. 关键设计原则 - -- **统一事件骨架**:所有事件共享同一套顶层字段(用户标识、时间、页面、trace、设备、扩展字段),业务差异放到 `event`(oneof)里。 -- **可串联**:用 `trace_id` 串联一次搜索/推荐请求与后续点击、加购、详情浏览等行为;用 `session_id` 串联同一次访问会话。 -- **可回放/可训练**:曝光事件尽量携带曝光商品列表、位置、模块;购物车/结账事件携带快照(items + 国家/币种/价格等)。 -- **停留时长口径一致**:对 `page_view`/`view_item` 统一给出 `dwell_time_ms` 的采集口径与上报方式。 - -## 3. 顶层事件模型(概念) - -每条 UA 事件为一个 `UserActionEvent`,包含: - -- **identity**:tenant / user / anonymous / device / cookie -- **time**:事件发生时间(毫秒时间戳) -- **page**:页面类型、URL、来源、模块位置信息 -- **trace**:`trace_id`、`session_id`、实验信息 -- **device**:OS / UA / viewport 等 -- **event**:具体业务事件(page_view、exposure、click、view_item、search、filter、cart、checkout、purchase…) -- **extra**:业务扩展 KV - -> proto 草案见 `docs/proto/user_action.proto`(本次补充文件)。 - -## 4. 核心字段说明 - -### 4.1 标识体系(强烈建议) - -- **tenant_id**:租户/店铺/商家维度的隔离主键。 -- **user_id**:登录用户 ID(未登录可为空)。 -- **anonymous_id**:匿名用户 ID(建议 Cookie 级别稳定,登录后可与 user_id 做归因合并)。 -- **device_id**:设备指纹(可选;Web 端更推荐 anonymous_id + cookie_id)。 -- **cookie_id**:首次访问生成的持久化 Cookie ID(与 anonymous_id 可以一致,也可分开)。 - -### 4.2 trace_id(最重要) - -**定义**:串联一次“搜索/推荐请求(曝光)”与后续点击、详情、加购等行为的请求级会话 ID,同时用于串联内部技术模块(召回/排序/重排等子模块日志)。 - -**规则建议**: - -- **新搜索/新推荐刷新**:生成新的 `trace_id`。 -- **搜索翻页**:沿用原 `trace_id`,用 `page_number` 区分页(见 `SearchEvent`)。 -- **曝光 → 点击/详情/加购**:沿用产生曝光的 `trace_id`,用于表达“该转化源自哪一次曝光/哪一次请求”。 -- **购买/支付**:如果链路被购物车长时间阻隔,串联成本高,可不强制要求延续 `trace_id`;但建议在 `PurchaseEvent.attribution_trace_id` 上尽力保留“主要来源”的 trace(若可得)。 - -### 4.3 停留时长(dwell_time_ms) - -**适用事件**: - -- `PageViewEvent`:用户在该页面的停留时长 -- `ViewItemEvent`:用户在详情页/商品内容上的停留时长(可与 pageview 相同,也可更精细) - -**采集口径建议(Web)**: - -- 在 `pagehide` / `beforeunload` / SPA 路由切换时计算当前页面停留:`now - enter_time`。 -- 若页面进入后立即产生 `page_view`,则可在离开页面时补发一条 `page_view_end`(或在同一条事件里填充 `dwell_time_ms`,需要延迟上报)。 -- 对详情页:可按“进入详情页到离开详情页”计算;若停留时长无法计算,允许不上报或置 0,但需要在文档/ETL 中区分“缺失 vs 真实 0”。 - -## 5. 必须覆盖的事件清单(推荐) - -- **Pageview** - - 分类页、活动页、列表页、首页、店铺页、购物车页、结账页等 - - *最好携带该页面曝光的商品列表*(见 `ExposureEvent`,或在 `PageViewEvent.exposed_items` 携带“本页首屏/本次渲染”曝光) -- **Exposure / Click** - - 列表/推荐位曝光与点击(必须包含 position / module_id / item) -- **View product(详情页浏览)** - - 包含 `dwell_time_ms` -- **Add to cart** - - 商品信息 + 数量 + 价格(若可得)+ 当前 cart 快照(若可得) -- **Purchase** - - 订单信息(order_id / currency / total)+ 购买 items -- **On-site Search & Filtering** - - 搜索词、建议词、排序、筛选条件(结构化,避免仅 JSON 字符串) - - 搜索结果曝光/点击建议归入 Exposure/Click,但必须携带 `search_context` -- **Cart Logic / Checkout 状态** - - `cart_snapshot`:购物车当前 items 及属性(qty、price、category、brand…) - - `checkout`:shipping_country、step、payment_method(如可得) - -## 6. 落地建议(神策 JS SDK 二次开发) - -- **事件名**:建议统一用一个事件名(如 `ua_event`),将 `action_type`(主类型)+ `event_id`(子类型,可选)作为属性;或按神策习惯拆分事件名,但必须保证字段一致。 -- **批量上报**:曝光事件可批量(一屏/一次渲染一次上报)以降低量级;点击/加购/购买等强转化事件单条实时上报。 -- **字段扩展**:放入 `extra.debug_info`,严禁在顶层无限加字段造成版本失控。 - -## 7. proto 草案 - -见 `docs/proto/user_action.proto`。 - -### 7.1 枚举命名说明(避免 proto 枚举值冲突) - -为兼容较旧版本 `protoc`(枚举值采用 package 级作用域),本 proto 中枚举值都带前缀: - -- **ActionType**:`ACTION_TYPE_*`(如 `ACTION_TYPE_PAGEVIEW`) -- **EventId**:`EVENT_ID_*`(如 `EVENT_ID_ADD_TO_CART`) -- **PageType**:`PAGE_TYPE_*` -- **SortType**:`SORT_TYPE_*` -- **CheckoutStep**:`CHECKOUT_STEP_*` - - diff --git a/docs/blog/语义搜索.md b/docs/blog/语义搜索.md index 825f6b6..4ddb268 100644 --- a/docs/blog/语义搜索.md +++ b/docs/blog/语义搜索.md @@ -41,7 +41,7 @@ 搜索“sports shoes”时,系统自动识别并强化关键购买决策维度:“运动类型(跑步/篮球)”、“适用场地(户外/室内)”、“减震技术”等,使结果更聚焦于用户真实意图。 3. **跨语言自适应能力** - 采用先进的跨语言对齐模型,基于英语训练的系统无需重新训练即可理解泰语、越南语、西班牙语等查询,实测跨语言召回率提升40%,真正实现“一次训练,全球适用”。 + 商家上传的商品可以是任何一种语言,用户可以用英语、中文、法语、意大利语、波兰语、西班牙语等30多种语言进行查询。 **阶段二:语义重排——让业务目标融入排序决策** @@ -69,16 +69,3 @@ ### 3. 混合查询精准解析:拥抱语言多样性 针对东南亚、拉美等市场的混合语言查询,系统不再依赖简单的词典翻译,而是理解语言混合背后的完整意图。搜索“裙 kasual wanita”能够准确理解这是“女士休闲裙”的需求,即使查询中包含本地语言词汇。 - -## 实测效果:数据驱动的价值证明 - -采用语义搜索技术的独立站客户已观察到显著改善: - -- **搜索转化率提升**:平均提升35%,长尾查询提升尤为明显 -- **零结果率下降**:从行业平均12%降至2%以下 -- **运营效率飞跃**:同义词维护工作量减少80%,可专注于更高价值的优化 -- **跨语言覆盖扩展**:支持语言从5种扩展到30+种,无需为每种语言单独训练模型 -- **新品曝光加速**:新上架商品在首周获得搜索曝光的概率提升3倍 - ---- - diff --git a/docs/对话式智能导购设计.md b/docs/对话式智能导购设计.md new file mode 100644 index 0000000..509b5dd --- /dev/null +++ b/docs/对话式智能导购设计.md @@ -0,0 +1,464 @@ +# 对话式智能导购设计(服饰鞋帽独立站) + +## 1. 核心场景与用户旅程 + +### 1.1 典型对话流程示例 + +**场景 A:新用户首次咨询(需要完善档案)** +``` +用户: "我想买一件适合夏天的T恤" +导购: "好的,我来帮您找。请问您平时穿什么尺码?" +用户: "M码" +导购: "好的。您比较喜欢什么颜色?我们这里有白色、黑色、蓝色、灰色等" +用户: "白色或浅色都可以" +导购: "了解。您希望是休闲款还是运动款?" +用户: "休闲的" +导购: "好的,我为您找到了几款,价格在50-150元之间,您看看..." +[展示结果] +``` + +**场景 B:老用户(已有档案,快速推荐)** +``` +用户: "帮我找一条牛仔裤" +导购: "好的,根据您的尺码偏好(30码),我为您推荐..." +[直接展示结果,如不满意再细化] +``` + +**场景 C:模糊需求逐步明确** +``` +用户: "我想买件外套" +导购: "好的,请问是用于什么场合?日常通勤、运动、还是正式场合?" +用户: "日常通勤" +导购: "了解。您希望是薄款还是厚款?现在这个季节..." +用户: "薄款就行" +导购: "好的,我为您推荐几款适合通勤的薄外套..." +``` + +### 1.2 核心价值点 + +- **降低搜索门槛**:用户用自然语言表达,无需熟悉筛选器 +- **个性化合身推荐**:通过尺码/合身偏好,减少退货率 +- **提升转化**:多轮对话收集偏好,推荐更精准 +- **完善用户档案**:每次对话积累偏好,后续推荐更准 + +--- + +## 2. 技术架构 + +### 2.1 整体架构(LLM + 商品检索 + 推荐引擎 + 用户档案) + +``` +┌─────────────────────────────────────────────────────────┐ +│ 前端对话界面 │ +│ (Web Chat Widget / 小程序 / H5) │ +└────────────────────┬────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────┐ +│ 对话式导购服务层 (Conversational Service) │ +│ ┌──────────────────────────────────────────────────┐ │ +│ │ 对话状态管理 (Dialogue State Tracker, DST) │ │ +│ │ - 当前意图 (intent) │ │ +│ │ - 已收集的偏好 (collected_preferences) │ │ +│ │ - 待确认信息 (pending_confirmation) │ │ +│ │ - 对话历史 (dialogue_history) │ │ +│ └──────────────────────────────────────────────────┘ │ +│ ┌──────────────────────────────────────────────────┐ │ +│ │ LLM 对话引擎 (核心) │ │ +│ │ - 意图理解 (NLU) │ │ +│ │ - 实体抽取 (NER: 类目/颜色/尺码/价格/风格...) │ │ +│ │ - 回复生成 (NLG) │ │ +│ │ - 策略决策 (何时问问题/何时展示结果) │ │ +│ └──────────────────────────────────────────────────┘ │ +│ ┌──────────────────────────────────────────────────┐ │ +│ │ 商品检索与推荐引擎 │ │ +│ │ - 基于偏好生成 filters/range_filters │ │ +│ │ - 调用搜索 API (复用现有 /search/) │ │ +│ │ - 结果排序与多样性控制 │ │ +│ └──────────────────────────────────────────────────┘ │ +│ ┌──────────────────────────────────────────────────┐ │ +│ │ 用户档案管理 (User Profile) │ │ +│ │ - 尺码偏好 (size_preferences) │ │ +│ │ - 风格偏好 (style_preferences) │ │ +│ │ - 价格偏好 (price_range) │ │ +│ │ - 历史购买/浏览 │ │ +│ └──────────────────────────────────────────────────┘ │ +└────────────────────┬────────────────────────────────────┘ + │ + ┌────────────┼────────────┐ + ▼ ▼ ▼ +┌─────────────┐ ┌──────────┐ ┌──────────────┐ +│ 搜索 API │ │ 商品库 │ │ 用户行为库 │ +│ (现有) │ │ (ES/DB) │ │ (埋点数据) │ +└─────────────┘ └──────────┘ └──────────────┘ +``` + +### 2.2 核心组件说明 + +#### 2.2.1 对话状态管理 (DST) +- **存储位置**:Redis(key: `dialogue:{tenant_id}:{user_key}:{session_id}`) +- **状态结构**: + ```json + { + "intent": "find_product|refine_search|ask_question|...", + "collected_preferences": { + "category": "T恤", + "size": "M", + "color": ["白色", "浅色"], + "style": "休闲", + "price_range": {"min": 50, "max": 150}, + "occasion": "日常", + "season": "夏季" + }, + "pending_confirmation": ["size", "color"], + "dialogue_history": [ + {"role": "user", "content": "..."}, + {"role": "assistant", "content": "..."} + ], + "current_results": [...], // 当前推荐结果(如有) + "turn_count": 3 + } + ``` + +#### 2.2.2 LLM 对话引擎 +- **输入**:用户消息 + 对话状态 + 商品库元信息(可选:类目列表、颜色列表、尺码列表) +- **输出**: + - **结构化输出**(必须):`intent`、`extracted_entities`、`action`(ask_question|show_results|clarify) + - **自然语言回复**(用于前端展示) +- **LLM 选择**: + - **推荐**:GPT-4o / Claude 3.5 Sonnet(强推理、结构化输出) + - **成本优化**:GPT-4o-mini / Claude Haiku(简单场景) + - **私有化**:Qwen2.5 / GLM-4(如需要) + +#### 2.2.3 商品检索与推荐引擎 +- **输入**:对话状态中的 `collected_preferences` +- **处理**: + 1. 将偏好转换为搜索 API 的 `filters` / `range_filters` + 2. 调用现有 `/search/` API + 3. 结果排序(可结合用户历史、商品热度、多样性) +- **输出**:商品列表(含图片/标题/价格/链接) + +#### 2.2.4 用户档案管理 +- **存储位置**:MySQL/Redis(key: `user_profile:{tenant_id}:{user_key}`) +- **字段结构**: + ```json + { + "size_preferences": { + "tops": "M", + "bottoms": "30", + "shoes": "42" + }, + "style_preferences": ["休闲", "简约"], + "color_preferences": ["白色", "黑色", "灰色"], + "price_range": {"min": 50, "max": 300}, + "brand_preferences": ["品牌A", "品牌B"], + "last_updated": "2026-01-21T10:00:00Z" + } + ``` + +--- + +## 3. 主要能力清单 + +### 3.1 核心能力(MVP 必须) + +#### A. 意图理解与实体抽取 (NLU) +- **能力**:从用户自然语言中提取: + - **类目**:T恤、牛仔裤、运动鞋、外套... + - **属性**:颜色、尺码、材质、风格(休闲/正式/运动) + - **价格**:价格区间、预算 + - **场合**:日常、通勤、运动、正式 + - **季节**:春夏秋冬 + - **其他**:品牌、折扣、新品等 +- **实现**:LLM 做 NER(命名实体识别)+ 规则后处理(映射到商品库的 specifications) + +#### B. 偏好收集与确认 +- **能力**: + - 识别用户已表达的偏好 + - 判断哪些关键信息缺失(如尺码、颜色) + - 生成追问问题(基于店铺商品库的可用选项) +- **实现**: + - LLM 判断缺失项 + - 从商品库分面(facets)获取可用选项(如"我们这里有白色、黑色、蓝色...") + - 生成自然语言问题 + +#### C. 商品检索与筛选 +- **能力**: + - 将对话偏好转换为搜索 API 的 `filters` / `range_filters` + - 调用搜索 API 获取候选 + - 结果排序(相关性 + 个性化 + 多样性) +- **实现**: + - 偏好 → filters 映射规则(可配置) + - 复用现有 `/search/` API + - 排序可结合用户档案(如优先推荐用户偏好的品牌/价格带) + +#### D. 结果展示与解释 +- **能力**: + - 生成推荐理由("根据您的尺码偏好和风格,我为您推荐...") + - 展示商品卡片(图片/标题/价格/链接) + - 支持继续对话("不满意?告诉我您想要什么样的") +- **实现**:LLM 生成回复 + 前端渲染商品卡片 + +#### E. 用户档案管理 +- **能力**: + - 从对话中提取并持久化偏好(尺码/风格/价格/品牌) + - 后续对话自动使用档案(减少重复询问) + - 档案更新(用户纠正/新偏好) +- **实现**: + - 对话结束后更新 `user_profile` + - 下次对话时作为上下文输入 LLM + +### 3.2 进阶能力(后续迭代) + +#### F. 合身推荐(Size Fit) +- **能力**: + - 基于用户历史购买/浏览,学习"合身偏好"(如"这个品牌M码偏大,建议选S") + - 跨品牌尺码映射(如"您平时穿Nike 42码,这个品牌建议选41码") +- **实现**: + - 需要用户历史数据(购买/退货/评价) + - 可做简单的"品牌-尺码映射表"(运营配置) + - 或训练轻量模型(用户尺码偏好 → 商品推荐尺码) + +#### G. 搭配推荐(Outfit Recommendation) +- **能力**: + - 用户选中一件商品后,推荐搭配(如"这件T恤可以搭配这条牛仔裤") + - 基于商品属性相似度 + 历史共购数据 +- **实现**: + - 商品 embedding(文本/图片) + - 共购规则(FBT) + - LLM 生成搭配理由 + +#### H. 多轮对话策略优化 +- **能力**: + - 智能判断"何时该问问题" vs "何时该展示结果" + - 避免过度询问(用户流失) +- **实现**: + - 规则:关键信息(尺码/类目)缺失时必问;可选信息(颜色/风格)有足够候选时可不问 + - 或训练策略模型(RL/bandit) + +#### I. 上下文记忆与纠错 +- **能力**: + - 记住对话中提到的商品("刚才那件白色的") + - 支持用户纠正("不对,我要的是黑色") +- **实现**: + - 对话状态中维护 `mentioned_items` + - LLM 理解指代消解(coreference resolution) + +--- + +## 4. 数据层需求 + +### 4.1 对话事件表(DWD 层) + +- `dwd_conversation_turn`:每次对话轮次 + - `tenant_id`, `user_key`, `session_id`, `conversation_id` + - `turn_number`, `role` (user/assistant), `content` + - `intent`, `extracted_entities_json` + - `action` (ask_question|show_results|clarify) + - `created_at` + +- `dwd_conversation_result`:对话产生的推荐结果 + - `tenant_id`, `conversation_id`, `turn_number` + - `item_id`, `position`, `clicked` (是否被点击) + - `exposed_at` + +### 4.2 用户档案表(DIM 层) + +- `dim_user_profile`:用户偏好档案 + - `tenant_id`, `user_key` + - `size_preferences_json` + - `style_preferences_json` + - `color_preferences_json` + - `price_range_json` + - `brand_preferences_json` + - `last_updated`, `created_at` + +### 4.3 商品库元信息(用于 LLM 上下文) + +- **类目列表**:从商品库聚合 `category1_name`, `category2_name`, `category3_name` +- **颜色列表**:从 `specifications` 聚合 `name="color"` 的所有 `value` +- **尺码列表**:从 `specifications` 聚合 `name="size"` 的所有 `value` +- **风格标签**:从 `tags` 或自定义字段聚合 + +> **注意**:这些元信息需要定期更新(如每天),作为 LLM 的"知识库"输入,确保推荐的商品确实存在。 + +--- + +## 5. 技术实现要点 + +### 5.1 LLM Prompt 设计(关键) + +**系统提示词模板**: +``` +你是一个专业的服饰导购助手,帮助用户在店铺中找到合适的商品。 + +店铺信息: +- 类目:{category_list} +- 颜色:{color_list} +- 尺码:{size_list} +- 风格:{style_list} + +用户档案(如有): +{user_profile_json} + +当前对话状态: +{conversation_state_json} + +任务: +1. 理解用户意图 +2. 提取商品偏好(类目/颜色/尺码/价格/风格/场合等) +3. 判断缺失的关键信息 +4. 生成自然语言回复 + +输出格式(JSON): +{ + "intent": "find_product|refine_search|ask_question|...", + "extracted_entities": { + "category": "...", + "color": [...], + "size": "...", + "price_range": {"min": ..., "max": ...}, + "style": "...", + "occasion": "..." + }, + "action": "ask_question|show_results|clarify", + "missing_info": ["size", "color"], // 缺失的关键信息 + "reply": "自然语言回复" +} +``` + +### 5.2 偏好 → 搜索 Filters 映射规则 + +```python +def preferences_to_filters(collected_preferences, user_profile): + filters = {} + range_filters = {} + + # 类目 + if collected_preferences.get("category"): + filters["category_name"] = collected_preferences["category"] + + # 颜色(specifications) + if collected_preferences.get("color"): + filters["specifications"] = [ + {"name": "color", "value": c} + for c in collected_preferences["color"] + ] + + # 尺码(specifications) + if collected_preferences.get("size"): + # 优先用对话中的,否则用用户档案 + size = collected_preferences.get("size") or user_profile.get("size_preferences", {}).get("tops") + if size: + filters.setdefault("specifications", []).append({"name": "size", "value": size}) + + # 价格区间 + if collected_preferences.get("price_range"): + pr = collected_preferences["price_range"] + range_filters["min_price"] = {"gte": pr.get("min", 0), "lte": pr.get("max", 9999)} + + # 风格(tags 或自定义字段) + if collected_preferences.get("style"): + filters["tags"] = collected_preferences["style"] + + return filters, range_filters +``` + +### 5.3 对话流程控制(状态机) + +``` +初始状态: waiting_for_intent + ↓ 用户输入 +意图理解: extract_intent_and_entities + ↓ +判断缺失信息: + - 关键信息缺失(如尺码)→ ask_question + - 有足够信息 → show_results + ↓ +展示结果后: + - 用户满意 → end_conversation + - 用户不满意/继续提问 → refine_search (更新偏好,重新检索) +``` + +--- + +## 6. 产品形态建议 + +### 6.1 前端交互方式 + +- **Web Chat Widget**:右下角悬浮聊天框(类似客服) +- **全屏对话页**:独立页面,适合移动端 +- **搜索结果页集成**:在搜索结果页提供"智能导购"入口 + +### 6.2 回复展示格式 + +- **纯文本回复**:LLM 生成的自然语言 +- **商品卡片**:展示推荐结果(图片/标题/价格/加购按钮) +- **选项按钮**:快速选择(如"白色"、"黑色"、"蓝色") +- **追问输入框**:用户继续输入 + +--- + +## 7. 评估指标 + +### 7.1 对话质量 +- **平均对话轮次**:完成一次推荐的平均轮次(越少越好,但需平衡信息收集) +- **用户满意度**:对话结束后的反馈(如"有用"/"无用") +- **推荐点击率**:对话推荐的商品被点击的比例 + +### 7.2 业务指标 +- **转化率**:对话用户 → 加购/购买的转化 +- **AOV 提升**:对话用户的平均订单价值 vs 非对话用户 +- **档案完善率**:用户档案被更新的比例 + +--- + +## 8. 实施优先级 + +### Phase 1 (MVP - 2-3个月) +- ✅ 基础对话能力(LLM + 意图理解 + 实体抽取) +- ✅ 偏好收集(尺码/颜色/类目/价格) +- ✅ 商品检索(偏好 → filters → 搜索 API) +- ✅ 结果展示(商品卡片) +- ✅ 用户档案(基础字段:尺码/颜色/价格) + +### Phase 2 (增强 - 3-4个月) +- ✅ 合身推荐(尺码映射) +- ✅ 搭配推荐 +- ✅ 多轮对话策略优化 +- ✅ 上下文记忆 + +### Phase 3 (优化 - 持续) +- ✅ 个性化排序(结合用户历史) +- ✅ A/B 测试(不同 prompt/策略) +- ✅ 跨租户知识共享(可选) + +--- + +## 9. 技术栈建议 + +- **LLM 服务**:OpenAI API / Anthropic API / 私有化部署(Qwen/GLM) +- **对话状态存储**:Redis +- **用户档案存储**:MySQL + Redis(缓存) +- **商品检索**:复用现有搜索 API +- **后端框架**:Python FastAPI(与现有 API 保持一致) +- **前端**:React/Vue + WebSocket(实时对话) + +--- + +## 10. 注意事项 + +1. **成本控制**:LLM API 调用成本(每次对话可能 3-10 轮),建议: + - 简单场景用轻量模型(GPT-4o-mini) + - 复杂场景用强模型(GPT-4o) + - 缓存常见问题回复 + +2. **延迟**:LLM 生成回复通常 1-3 秒,需要: + - 前端显示"正在思考..." + - 考虑流式输出(streaming) + +3. **商品库同步**:确保 LLM 的"知识库"(类目/颜色/尺码列表)与商品库实时同步 + +4. **多语言**:如店铺支持多语言,LLM 需要支持对应语言 + +5. **隐私合规**:用户档案数据需符合 GDPR/CCPA 等要求 diff --git a/docs/搜索推荐数据.md b/docs/搜索推荐数据.md new file mode 100644 index 0000000..1de4da0 --- /dev/null +++ b/docs/搜索推荐数据.md @@ -0,0 +1,353 @@ + +## 1)BI 怎么设计(对标 Shopify/独立站“搜索/推荐”常见报表) +Shopify 的 Search & Discovery/行为报表里,搜索常看的就是 **query、no results、no clicks、click rate、purchase rate**(会话口径漏斗)。推荐系统的看板更强调 **曝光→点击→加购→购买→收入**,并按**推荐位/算法/实验**拆解。 + +### 1.1 搜索 BI(核心看板) +- **搜索总览(KPI + 漏斗)** + - **搜索 PV/UV**:search request 次数 / 搜索用户数 + - **Click rate(会话口径,Shopify 常用)**:有点击的搜索会话 / 搜索会话 + - **ATC rate**:有加购的搜索会话 / 搜索会话 + - **Purchase rate(会话口径,Shopify 常用)**:有购买的搜索会话 / 搜索会话 + - **结果曝光 CTR(结果口径)**:点击次数 / 结果曝光次数(更适合诊断排序/样式) + - **延迟&稳定性**:P50/P95 搜索耗时、错误率、空响应率 + +- **Query 分析(运营/选品/词库最常用)** + - **高热搜索词**:按搜索 UV、曝光 UV、点击 UV、购买 UV 排序 + - **飙升词/新词**:与过去 \(7/14/28\) 天对比的增速 + - **无结果 query**(no results) + - **有结果但无点击 query**(no clicks)——强信号:相关性差/图片价位不吸引/首屏无货等 + - **建议词(suggestion)**:suggest 点击发起的搜索占比、suggest→点击/购买转化 + +- **结果质量诊断(给算法/工程用)** + - **点击位置分布**:position=1/2/3… 的点击占比(反推排序质量) + - **类目/品牌/价格带分布**:哪些 query 对哪些类目贡献转化 + - **筛选/排序使用率**:filter 使用率、排序切换率、filter 后的 CTR/CVR 变化 + +- **用户与渠道拆解(增长/产品用)** + - **新/老客**、地域、语言、设备、来源(自然/广告/社媒) + - **页面维度**:首页搜索框 / 搜索页 / 分类页搜索 / 详情页内搜索等 + +- **Session/链路回放(你提到的 track_id/trace_id)** + - 单用户或单 trace:**搜索→换词→曝光→点击→详情→加购→支付** + - 支持按 **trace_id** 串联一次“搜索请求”与后续行为(你们文档也强调这一点) + +> 参考:Shopify 官方对搜索分析的核心指标包括 click rate、purchase rate、queries、no results、no clicks(见 [Shopify Search & Discovery analytics](https://help.shopify.com/en/manual/online-store/storefront-search/search-and-discovery-analytics))。 + +### 1.2 推荐 BI(核心看板) +- **推荐位总览(按 placement/module)** + - **Impressions/Clicks/CTR** + - **ATC、Purchase、Revenue** + - **Revenue per impression / per click** + - **AOV(推荐归因订单)** + - **覆盖与多样性**:覆盖商品数、长尾曝光占比、重复率(避免“只推爆款”) + +- **按算法/实验拆解** + - 算法版本(model_version/strategy_id) + - 实验(experiment_id/variant_id) + - **Lift(增量)**:相对对照组的 CTR/CVR/Revenue uplift(最好有 holdout) + +- **健康度与风控** + - 缺货/下架命中率、被过滤原因分布(无库存/不可售/地域不发货) + - 冷启动占比(新用户/新商品)与表现 + +--- + +## 2)数据层面的设计(埋点→数仓→指标→推荐特征) +你们已有统一事件骨架的方向(`tenant_id / session_id / trace_id / event(oneof)`)。建议在数据层分成 **ODS(原始)→DWD(清洗明细)→DWS(汇总)→ADS(看板语义层)**,同时给推荐做 **离线+在线特征库**。 + +### 2.1 关键 ID 设计(决定 BI/推荐能否串起来) +- **tenant_id**:多租户隔离必备(所有表分区/主键都带) +- **user_key**:归一后的用户主键(优先 login/user_id;否则 anonymous_id/cookie_id) +- **session_id**:会话(SDK 产生或用 30min inactivity 规则补齐) +- **trace_id(最重要)**:一次搜索/一次推荐刷新生成一个,后续点击/详情/加购尽量继承 +- **request_id**:后端请求日志关联(用于延迟、错误、召回/排序 debug) +- **order_id/cart_id/item_id(sku/spu)**:交易与商品归因 + +### 2.2 ODS:原始事件(“可回放、可重放”) +- `ods_ua_event_raw` + - tenant_id, event_time, received_time + - identities(原始字段:distinct_id/login_id/anonymous_id/cookie_id…) + - page/device/geo/referrer + - trace_id, session_id, experiment 信息 + - event_name + properties(原始 JSON,保留全量) + +> 你现在的 `$pageview/$WebClick` 自动采集能覆盖点击和页面,但 **推荐/搜索“曝光”必须补埋点**(否则 CTR、归因、训练样本都会缺)。 + +### 2.3 DWD:清洗后的事实表(BI/训练统一口径) +建议把“强分析对象”拆成事实表(便于 join、去重、做漏斗): + +- **搜索域** + - `dwd_search_request`:一次“搜索结果刷新/请求”的主表(强烈建议:**每次请求一个 request_id,同时每次请求一个 trace_id**) + - **用途**:search PV/UV、零结果、延迟、query 聚合、会话口径漏斗分母(search_session) + - **主键建议**:`(tenant_id, request_id)` + - **核心索引建议**: + - `(tenant_id, created_at)` + - `(tenant_id, user_key, created_at)` + - `(tenant_id, query_normalized, created_at)` + - `(tenant_id, trace_id)`(用于 join 曝光/点击) + - `(tenant_id, search_session_id, created_at)` + - **字段建议(MySQL 参考类型,可按你们存储调整)** + - `tenant_id` VARCHAR(64) NOT NULL:店铺/租户 + - `request_id` VARCHAR(64) NOT NULL:该次搜索请求唯一 ID(前端生成或后端返回) + - `trace_id` VARCHAR(64) NOT NULL:该次搜索链路 ID(一次结果集 = 一个 trace) + - `session_id` VARCHAR(64) NULL:访问会话(30min inactivity) + - `search_session_id` VARCHAR(64) NULL:搜索会话(一次“找东西”的连续过程) + - `user_id` VARCHAR(64) NULL:登录用户 ID + - `anonymous_id` VARCHAR(64) NULL:匿名用户(cookie 级稳定) + - `user_key` VARCHAR(64) NOT NULL:归一用户主键(ETL 生成) + - `query` TEXT NOT NULL:原始 query + - `query_normalized` VARCHAR(512) NOT NULL:归一化 query(聚合用) + - `is_suggestion` TINYINT NOT NULL DEFAULT 0:是否由 suggestion 触发 + - `suggestion_text` VARCHAR(512) NULL:命中的 suggestion(如有) + - `page_number` INT NOT NULL DEFAULT 1:翻页页码(1-based) + - `sort` VARCHAR(64) NULL:排序方式(如 relevance/price_asc/…) + - `filters_json` JSON NULL:结构化筛选条件(原子字段更好;JSON 为起步方案) + - `filters_hash` CHAR(32) NULL:filters 归一化后的 hash(便于聚合/去重) + - `results_count` INT NOT NULL DEFAULT 0:总命中数 + - `returned_count` INT NULL:本页返回数量(page size) + - `latency_ms` INT NULL:搜索耗时 + - `is_zero_result` TINYINT NOT NULL DEFAULT 0:是否零结果(可由 results_count=0 派生) + - `is_error` TINYINT NOT NULL DEFAULT 0:是否错误 + - `error_code` VARCHAR(64) NULL:错误码(如超时/限流等) + - `page_type` VARCHAR(64) NULL:发生搜索的页面(home/search/pdp/collection…) + - `referrer` TEXT NULL:来源页 + - `device_type` VARCHAR(32) NULL:pc/mobile(可从 UA 解析) + - `country` VARCHAR(8) NULL:国家(建议由 IP->Geo 派生;避免落全量 IP) + - `created_at` DATETIME(3) NOT NULL:事件时间(毫秒级可选) + + - `dwd_search_impression_item`:搜索结果“曝光明细”(**必须补**,否则无法算 position CTR、训练负样本) + - **用途**:曝光 PV/UV、位置 CTR、召回/排序诊断、训练样本(曝光未点为负样本) + - **主键建议**:`(tenant_id, trace_id, item_id, position)`(或 `(tenant_id, request_id, item_id, position)`,二选一但全局统一) + - **核心索引建议**: + - `(tenant_id, trace_id)` + - `(tenant_id, request_id)` + - `(tenant_id, item_id, exposed_at)` + - **字段建议** + - `tenant_id` VARCHAR(64) NOT NULL + - `request_id` VARCHAR(64) NOT NULL + - `trace_id` VARCHAR(64) NOT NULL + - `search_session_id` VARCHAR(64) NULL + - `user_key` VARCHAR(64) NOT NULL + - `query_normalized` VARCHAR(512) NOT NULL + - `item_id` VARCHAR(64) NOT NULL:spu 或 sku,需统一 + - `position` INT NOT NULL:在搜索结果中的排名(1-based) + - `score` DOUBLE NULL:排序分(如 ES score/learning-to-rank score) + - `price` DECIMAL(18,2) NULL:曝光时价格快照(可选但强烈建议) + - `currency` VARCHAR(8) NULL + - `in_stock` TINYINT NULL:曝光时库存可售快照(可选但强烈建议) + - `exposed_at` DATETIME(3) NOT NULL:曝光时间 + + - `dwd_search_click_item`:搜索结果点击明细(点击必须能回链到曝光/请求) + - **用途**:click UV、CTR(曝光口径/会话口径)、位置点击分布、归因触点 + - **主键建议**:`(tenant_id, click_id)`(若无 click_id,可用 `(tenant_id, trace_id, item_id, clicked_at)` 近似) + - **核心索引建议**: + - `(tenant_id, trace_id)` + - `(tenant_id, request_id)` + - `(tenant_id, item_id, clicked_at)` + - **字段建议** + - `tenant_id` VARCHAR(64) NOT NULL + - `click_id` VARCHAR(64) NULL:点击事件唯一 ID(推荐补) + - `request_id` VARCHAR(64) NOT NULL + - `trace_id` VARCHAR(64) NOT NULL + - `search_session_id` VARCHAR(64) NULL + - `user_key` VARCHAR(64) NOT NULL + - `query_normalized` VARCHAR(512) NOT NULL + - `item_id` VARCHAR(64) NOT NULL + - `position` INT NULL:点击时该商品所在排名(无法取到则置空) + - `clicked_at` DATETIME(3) NOT NULL + - `target_url` TEXT NULL:点击跳转 URL(可选) + +- **推荐域** + - `dwd_rec_request`:一次推荐请求/刷新主表(一次刷新 = 一个 trace_id) + - **用途**:推荐 PV/UV、分推荐位指标、实验/版本拆解、延迟与稳定性 + - **主键建议**:`(tenant_id, request_id)` + - **核心索引建议**: + - `(tenant_id, created_at)` + - `(tenant_id, placement, created_at)` + - `(tenant_id, trace_id)` + - `(tenant_id, algo_id, model_version, created_at)` + - **字段建议** + - `tenant_id` VARCHAR(64) NOT NULL + - `request_id` VARCHAR(64) NOT NULL + - `trace_id` VARCHAR(64) NOT NULL + - `session_id` VARCHAR(64) NULL + - `user_key` VARCHAR(64) NOT NULL + - `placement` VARCHAR(64) NOT NULL:推荐位(home/pdp/cart/checkout/search…) + - `module_id` VARCHAR(128) NULL:页面内模块标识(一个页面多个推荐模块) + - `trigger_item_id` VARCHAR(64) NULL:触发商品(PDP/Cart 场景常用) + - `candidates_count` INT NULL:候选数量 + - `returned_count` INT NULL:返回条数 + - `algo_id` VARCHAR(64) NULL:策略/算法标识(rule/i2i/embedding/…) + - `model_version` VARCHAR(64) NULL:模型版本 + - `experiment_id` VARCHAR(64) NULL:实验 ID(如有) + - `variant_id` VARCHAR(64) NULL:分桶/分组(如有) + - `latency_ms` INT NULL + - `is_error` TINYINT NOT NULL DEFAULT 0 + - `error_code` VARCHAR(64) NULL + - `created_at` DATETIME(3) NOT NULL + + - `dwd_rec_impression_item`:推荐曝光明细 + - **主键建议**:`(tenant_id, trace_id, item_id, position)` + - **核心索引建议**:`(tenant_id, trace_id)`、`(tenant_id, item_id, exposed_at)` + - **字段建议** + - `tenant_id` VARCHAR(64) NOT NULL + - `request_id` VARCHAR(64) NOT NULL + - `trace_id` VARCHAR(64) NOT NULL + - `user_key` VARCHAR(64) NOT NULL + - `placement` VARCHAR(64) NOT NULL + - `module_id` VARCHAR(128) NULL + - `trigger_item_id` VARCHAR(64) NULL + - `item_id` VARCHAR(64) NOT NULL + - `position` INT NOT NULL + - `score` DOUBLE NULL + - `price` DECIMAL(18,2) NULL + - `currency` VARCHAR(8) NULL + - `in_stock` TINYINT NULL + - `exposed_at` DATETIME(3) NOT NULL + + - `dwd_rec_click_item`:推荐点击明细 + - **主键建议**:`(tenant_id, click_id)`(或 `(tenant_id, trace_id, item_id, clicked_at)`) + - **核心索引建议**:`(tenant_id, trace_id)`、`(tenant_id, item_id, clicked_at)` + - **字段建议** + - `tenant_id` VARCHAR(64) NOT NULL + - `click_id` VARCHAR(64) NULL + - `request_id` VARCHAR(64) NOT NULL + - `trace_id` VARCHAR(64) NOT NULL + - `user_key` VARCHAR(64) NOT NULL + - `placement` VARCHAR(64) NOT NULL + - `module_id` VARCHAR(128) NULL + - `trigger_item_id` VARCHAR(64) NULL + - `item_id` VARCHAR(64) NOT NULL + - `position` INT NULL + - `clicked_at` DATETIME(3) NOT NULL + +- **转化域(全站通用)** + - `dwd_view_item`:商品详情页浏览(可承接 search/rec 的 trace,用于链路与兴趣序列) + - **主键建议**:`(tenant_id, view_id)`(或 `(tenant_id, user_key, item_id, viewed_at)`) + - **核心索引建议**:`(tenant_id, user_key, viewed_at)`、`(tenant_id, item_id, viewed_at)` + - **字段建议** + - `tenant_id` VARCHAR(64) NOT NULL + - `view_id` VARCHAR(64) NULL + - `session_id` VARCHAR(64) NULL + - `user_key` VARCHAR(64) NOT NULL + - `item_id` VARCHAR(64) NOT NULL + - `source_type` VARCHAR(32) NULL:来源(search/rec/direct/ads/…) + - `source_trace_id` VARCHAR(64) NULL:来源 trace(若来自 search/rec) + - `dwell_time_ms` INT NULL + - `viewed_at` DATETIME(3) NOT NULL + + - `dwd_add_to_cart`:加购事实表(全站统一) + - **主键建议**:`(tenant_id, atc_id)`(或 `(tenant_id, user_key, item_id, added_at)`) + - **核心索引建议**:`(tenant_id, user_key, added_at)`、`(tenant_id, item_id, added_at)` + - **字段建议** + - `tenant_id` VARCHAR(64) NOT NULL + - `atc_id` VARCHAR(64) NULL + - `session_id` VARCHAR(64) NULL + - `cart_id` VARCHAR(64) NULL + - `user_key` VARCHAR(64) NOT NULL + - `item_id` VARCHAR(64) NOT NULL + - `quantity` INT NOT NULL DEFAULT 1 + - `price` DECIMAL(18,2) NULL + - `currency` VARCHAR(8) NULL + - `source_type` VARCHAR(32) NULL:来源(search/rec/direct/…) + - `source_trace_id` VARCHAR(64) NULL:来源 trace(若来自 search/rec) + - `added_at` DATETIME(3) NOT NULL + - `cart_snapshot_json` JSON NULL:购物车快照(可选,体积大时可下沉到独立表) + + - `dwd_purchase`:订单事实表(全站统一) + - **主键建议**:`(tenant_id, order_id)` + - **核心索引建议**:`(tenant_id, user_key, paid_at)`、`(tenant_id, paid_at)` + - **字段建议** + - `tenant_id` VARCHAR(64) NOT NULL + - `order_id` VARCHAR(64) NOT NULL + - `user_key` VARCHAR(64) NOT NULL + - `currency` VARCHAR(8) NULL + - `total_amount` DECIMAL(18,2) NULL + - `paid_at` DATETIME(3) NOT NULL + + - `dwd_purchase_item`:订单明细事实表(全站统一) + - **主键建议**:`(tenant_id, order_id, item_id)`(若一单同商品可多行,则增加 `line_id`) + - **核心索引建议**:`(tenant_id, item_id, paid_at)`、`(tenant_id, order_id)` + - **字段建议** + - `tenant_id` VARCHAR(64) NOT NULL + - `order_id` VARCHAR(64) NOT NULL + - `line_id` VARCHAR(64) NULL + - `user_key` VARCHAR(64) NOT NULL + - `item_id` VARCHAR(64) NOT NULL + - `quantity` INT NOT NULL DEFAULT 1 + - `price` DECIMAL(18,2) NULL + - `paid_at` DATETIME(3) NOT NULL + + - **落库/分区建议(MySQL)** + - 量小:按 `tenant_id` + `created_at` 索引即可 + - 量大:建议按月分表/分区(`*_202601`),或落到 ClickHouse/ES/湖仓;DWD 保持明细可追溯,DWS/ADS 做聚合提速 + +- **归因桥(可选但强烈建议)** + - `dwd_attribution_touch` + - order_id, item_id, last_touch_trace_id, touch_type(search/rec), touch_time, window(如 7d click/1d view) + - 这样 BI 里的“搜索带来收入/推荐带来收入”不会口径混乱。 + +### 2.4 DWS/ADS:面向看板的汇总层(高性能) +- `dws_search_kpi_daily`(tenant_id, date, page_type/device/geo/new_vs_returning…) + - search_pv, search_uv, sessions_with_click, sessions_with_atc, sessions_with_purchase + - click_rate_session, purchase_rate_session, zero_result_rate, no_click_rate, p95_latency +- `dws_query_daily`(tenant_id, date, normalized_query) + - searches, exposure_uv, click_uv, purchase_uv, zero_cnt, no_click_cnt +- `dws_rec_kpi_daily`(tenant_id, date, placement, algo_id/model_version) + - impressions, clicks, ctr, atc, purchases, revenue, rpi(revenue per impression) +- `dws_item_daily`(tenant_id, date, item_id) + - search_impr/click/atc/purchase、rec_impr/click/…(用于“商品天级统计特征”与运营) + +--- + +## 3)推荐系统依赖的数据(“能训练、能实时、能解释”) +把特征分成 **用户/商品/上下文**,再分 **静态/快照/统计/序列(实时)**。 + +### 3.1 用户基础信息(dim) +- `dim_user`:user_key、注册时间、是否会员、国家/语言、获客渠道(如可得)、新老客标签 +- 合规:只存业务需要的最小信息,敏感字段做脱敏/哈希 + +### 3.2 用户实时特征(在线序列 + 聚合) +在线(Redis/Key-Value)建议保留: +- **最近 N 次行为序列**(按时间衰减) + - view_item_seq(最近浏览商品) + - search_query_seq(最近搜索词/类目) + - click_seq(点击的商品,区分来自 search/rec) + - cart_seq、purchase_seq +- **实时聚合** + - 最近 1h/24h 搜索次数、点击次数、加购次数 + - 最近一次偏好类目/品牌/价格带(从序列实时计算) + +离线(天/小时级)输出: +- RFM、长期偏好向量(类目/品牌 embedding)、价格敏感度、复购周期等 + +### 3.3 商品基础特征(静态) +- `dim_item`(sku/spu) + - 类目、品牌、属性(颜色/尺码/材质…)、标题/描述、价格、币种、图片 + - 文本/图片 embedding(你们已有 embeddings 模块可复用) + +### 3.4 商品快照(强业务约束,必须可回溯) +- `item_snapshot`(tenant_id, item_id, snapshot_time) + - 库存/可售、折扣、上新、发货国家限制、活动标签 +- 推荐/搜索曝光明细里最好**写入当时的关键快照字段**(至少 in_stock、price),避免事后回算失真。 + +### 3.5 商品天级统计特征(训练/排序最常用) +- 由 `dws_item_daily` 派生: + - 1d/7d/28d:search_ctr、search_cvr、rec_ctr、rec_cvr、atc_rate、purchase_rate + - 热度、趋势(环比/同比)、退货/取消(如可得) + - 分 placement 的表现(同一商品在“购物车推荐”与“首页推荐”差异巨大) + +### 3.6 标签(Label)与训练样本(建议一开始就定口径) +- **曝光→点击**(CTR)标签:以 `impression_item` 为样本 +- **点击→加购/购买**(CVR/GMV)标签:以 click 或 impression 为样本,设定归因窗口 +- 负样本:同一 trace_id 下未被点击的曝光 item(更稳定) + +--- + +## 4)你提到的两项“未完成工作”,数据层如何补齐 +- **商品曝光(搜索/推荐)**:必须新增 `ExposureEvent`(建议一屏/一次渲染批量上报 item 列表 + position + module/placement + trace_id) +- **链路跟踪**:以 `trace_id` 为主串联;若购买跨会话严重,可在 purchase 上补 `attribution_trace_id` 或单独落 `attribution_touch` 表做归因 + +--- + +如果你愿意,我可以基于你们现有 `proto`/事件骨架,把“搜索请求/曝光/点击/加购/购买/推荐请求”这几类事件的**最小必填字段清单**列成一张表(直接给前端埋点和后端 ETL 用),并给出每个指标(CTR/CVR/zero/no-click)的**精确定义与 SQL 计算口径**。 \ No newline at end of file diff --git a/frontend/static/js/tenant_facets_config.js b/frontend/static/js/tenant_facets_config.js index 1af6f6f..7c80dad 100644 --- a/frontend/static/js/tenant_facets_config.js +++ b/frontend/static/js/tenant_facets_config.js @@ -33,32 +33,53 @@ const TENANT_FACETS_CONFIG = { // tenant_id=170: 使用首字母大写的规格名称(Color, Size),没有material "170": { specificationFields: [ - { - field: "specifications.Color", + { + field: "specifications.Color", label: "Color", containerId: "colorTags", - size: 20, - type: "terms", - disjunctive: true + size: 20, + type: "terms", + disjunctive: true }, - { - field: "specifications.Size", + { + field: "specifications.Size", label: "Size", containerId: "sizeTags", - size: 15, - type: "terms", - disjunctive: true + size: 15, + type: "terms", + disjunctive: true } // 示例:如果170还有其他规格,可以这样添加: - // { - // field: "specifications.Weight", + // { + // field: "specifications.Weight", // label: "Weight", // containerId: "weightTags", - // size: 15, - // type: "terms", - // disjunctive: true + // size: 15, + // type: "terms", + // disjunctive: true // } ] + }, + // tenant_id=171: 与170配置相同 + "171": { + specificationFields: [ + { + field: "specifications.Color", + label: "Color", + containerId: "colorTags", + size: 20, + type: "terms", + disjunctive: true + }, + { + field: "specifications.Size", + label: "Size", + containerId: "sizeTags", + size: 15, + type: "terms", + disjunctive: true + } + ] } }; -- libgit2 0.21.2