4.3 KiB
4.3 KiB
转化率清零问题 - 修复总结
🔴 问题描述
用户选择多个标签(特别是同一分类中的多个标签)后,转化率变成0%
🔍 根本原因
标签分类特性
系统中的标签按分类组织,同一分类中的标签通常是互斥的:
监护人身份分类:
- 母亲 (tag_id=1)
- 父亲
- 祖母
- 外祖母 (tag_id=14) ← 与母亲互斥
文化程度分类:
- 小学
- 初中
- 高中
- 本科 (tag_id=2)
职业分类:
- 专业人士 (tag_id=3)
- 工人 (tag_id=16) ← 与专业人士互斥
- 农民
旧逻辑的问题
所有标签都用AND逻辑(INTERSECT):
// 错误的逻辑
SELECT user_id FROM user_tags WHERE tag_id = 1 // 母亲
INTERSECT
SELECT user_id FROM user_tags WHERE tag_id = 14 // 外祖母
结果为0:因为没有用户既是"母亲"又是"外祖母"!
数据验证
-- 测试同分类标签交集
SELECT COUNT(*) FROM (
SELECT user_id FROM user_tags WHERE tag_id = 1 -- 母亲:99人
INTERSECT
SELECT user_id FROM user_tags WHERE tag_id = 14 -- 外祖母:26人
);
-- 结果:0 ❌ (预期应该是在这两个标签中任选其一的人数)
✅ 解决方案
新逻辑:分类感知的OR/AND组合
同一分类内的多个标签 → 用OR逻辑(任选其一)
不同分类的标签 → 用AND逻辑(需同时满足)
// 新逻辑示例
// 选择:(母亲 OR 外祖母) AND 本科
SELECT user_id FROM user_tags WHERE tag_id IN (1, 14) // 同分类:OR
INTERSECT
SELECT user_id FROM user_tags WHERE tag_id = 2 // 不同分类:AND
结果:125 ✓ (99个母亲 + 26个外祖母 = 125人,其中与本科的交集)
实现细节
文件修改:server.js 的 /api/compute 端点
// 第1步:按分类对选中标签分组
const categoryMap = {};
for (const inc of includes) {
const tagInfo = db.prepare(`
SELECT t.id, t.category_id FROM tags t WHERE t.id = ?
`).get(inc.tagId);
if (tagInfo) {
if (!categoryMap[tagInfo.category_id]) {
categoryMap[tagInfo.category_id] = [];
}
categoryMap[tagInfo.category_id].push(inc.tagId);
}
}
// 第2步:为每个分类生成SQL子句
const categoryParts = [];
for (const catId in categoryMap) {
const tagIds = categoryMap[catId];
if (tagIds.length === 1) {
// 单标签:直接用WHERE tag_id = ?
baseParams.push(tagIds[0]);
categoryParts.push(`SELECT user_id FROM user_tags WHERE tag_id = ?`);
} else {
// 多标签:用IN (OR逻辑)
baseParams.push(...tagIds);
const placeholders = tagIds.map(() => '?').join(',');
categoryParts.push(`SELECT user_id FROM user_tags WHERE tag_id IN (${placeholders})`);
}
}
// 第3步:分类间用INTERSECT (AND逻辑)
baseSql = categoryParts.join(' INTERSECT ');
📊 测试结果
测试1:同分类多选
curl -X POST http://localhost:3456/api/compute \
-H "Content-Type: application/json" \
-d '{"selected":[{"tagId":1,"mode":"include"},{"tagId":14,"mode":"include"}]}'
旧结果:count: 0, rate: 0% ❌
新结果:count: 125, rate: 65.45% ✓
测试2:跨分类组合
# 选择:(母亲 OR 外祖母) AND 本科
curl -X POST http://localhost:3456/api/compute \
-H "Content-Type: application/json" \
-d '{"selected":[{"tagId":1,"mode":"include"},{"tagId":14,"mode":"include"},{"tagId":2,"mode":"include"}]}'
结果:count: 33, rate: 17.28% ✓
(其中29个母亲+本科,4个外祖母+本科)
🎨 UI优化
在"已选条件"栏添加逻辑说明:
已选条件:[母亲] [本科] (同分类: OR | 不同分类: AND)[✕清空]
📌 总结
| 方面 | 旧行为 | 新行为 |
|---|---|---|
| 同分类多标签 | AND(导致为0) | OR(返回合理结果) |
| 跨分类标签 | AND | AND(保持不变) |
| 转化率 | 0% | ✓ 正确计算 |
| 用户体验 | 困惑 | ✓ 显示逻辑说明 |
🚀 验证步骤
- ✅ 刷新浏览器(Ctrl+F5/Cmd+Shift+R)清除缓存
- ✅ 多选同分类标签(如"母亲"+"父亲")
- ✅ 观察转化率 - 应显示正常数值(不为0%)
- ✅ 结合其他分类 - 结合不同分类验证AND逻辑
修复时间:2026-04-07
涉及文件:server.js, public/index.html