148 lines
4.2 KiB
Markdown
148 lines
4.2 KiB
Markdown
|
|
# ID映射机制优化说明
|
|||
|
|
|
|||
|
|
## 🎯 解决的问题
|
|||
|
|
|
|||
|
|
### 原有问题
|
|||
|
|
1. **数据库查询失败**:ID查询时经常找不到对应数据
|
|||
|
|
2. **名称匹配不准确**:AI生成的选题名称与数据库中的名称不完全匹配
|
|||
|
|
3. **缺少兜底机制**:查询失败时没有备用方案
|
|||
|
|
4. **ID追踪缺失**:选题生成后无法保持ID的连续性
|
|||
|
|
|
|||
|
|
## 🔧 优化方案
|
|||
|
|
|
|||
|
|
### 1. 增强ID映射逻辑 (`api/routers/tweet.py`)
|
|||
|
|
|
|||
|
|
#### 模糊匹配机制
|
|||
|
|
```python
|
|||
|
|
def find_best_match(target_name: str, mapping: Dict[str, int]) -> Optional[int]:
|
|||
|
|
# 1. 精确匹配
|
|||
|
|
if target_name in mapping:
|
|||
|
|
return mapping[target_name]
|
|||
|
|
|
|||
|
|
# 2. 模糊匹配 - 去除空格后匹配
|
|||
|
|
target_clean = target_name.replace(" ", "").strip()
|
|||
|
|
for name, id_val in mapping.items():
|
|||
|
|
if name.replace(" ", "").strip() == target_clean:
|
|||
|
|
return id_val
|
|||
|
|
|
|||
|
|
# 3. 包含匹配 - 检查是否互相包含
|
|||
|
|
for name, id_val in mapping.items():
|
|||
|
|
if target_clean in name.replace(" ", "") or name.replace(" ", "") in target_clean:
|
|||
|
|
return id_val
|
|||
|
|
|
|||
|
|
# 4. 未找到匹配
|
|||
|
|
logger.warning(f"未找到匹配的ID: '{target_name}'")
|
|||
|
|
return None
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 匹配率监控
|
|||
|
|
- 记录每个选题的ID匹配情况
|
|||
|
|
- 计算匹配率并在匹配率低于50%时发出警告
|
|||
|
|
- 添加匹配元数据用于调试
|
|||
|
|
|
|||
|
|
### 2. 数据库服务兜底机制 (`api/services/database_service.py`)
|
|||
|
|
|
|||
|
|
#### 批量查询增强
|
|||
|
|
```python
|
|||
|
|
def get_styles_by_ids(self, styleIds: List[int]) -> List[Dict[str, Any]]:
|
|||
|
|
# 检查哪些ID没有找到对应记录
|
|||
|
|
found_ids = {result['id'] for result in results}
|
|||
|
|
missing_ids = set(styleIds) - found_ids
|
|||
|
|
|
|||
|
|
if missing_ids:
|
|||
|
|
# 添加兜底数据
|
|||
|
|
fallback_styles = self._get_fallback_styles(list(missing_ids))
|
|||
|
|
results.extend(fallback_styles)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 兜底数据提供
|
|||
|
|
- 当数据库查询失败时,提供默认的结构化数据
|
|||
|
|
- 标记兜底数据 (`_is_fallback: True`)
|
|||
|
|
- 确保系统可以继续运行
|
|||
|
|
|
|||
|
|
### 3. 内容生成阶段优化 (`api/services/tweet.py`)
|
|||
|
|
|
|||
|
|
#### 智能数据增强
|
|||
|
|
```python
|
|||
|
|
async def _enhance_topic_with_database_data(self, topic: Dict[str, Any]) -> Dict[str, Any]:
|
|||
|
|
# 优先使用ID从数据库获取最新数据
|
|||
|
|
if 'styleIds' in topic and topic['styleIds']:
|
|||
|
|
style_data = db_service.get_style_by_id(style_id)
|
|||
|
|
if style_data:
|
|||
|
|
enhanced_topic['style_object'] = style_data
|
|||
|
|
enhanced_topic['style'] = style_data.get('styleName')
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 多级兜底策略
|
|||
|
|
1. **第一级**:通过ID从数据库获取最新数据
|
|||
|
|
2. **第二级**:使用传入的对象参数作为兜底
|
|||
|
|
3. **第三级**:使用数据库服务的兜底数据
|
|||
|
|
|
|||
|
|
## 🔄 完整流程
|
|||
|
|
|
|||
|
|
### 选题生成阶段
|
|||
|
|
1. 接收ID列表 → 查询数据库获取完整对象
|
|||
|
|
2. 构建ID到名称的映射关系
|
|||
|
|
3. AI生成选题(包含名称)
|
|||
|
|
4. 将生成的选题名称映射回ID
|
|||
|
|
5. 返回包含ID的选题数据
|
|||
|
|
|
|||
|
|
### 内容生成阶段
|
|||
|
|
1. 接收带ID的选题数据
|
|||
|
|
2. 通过ID从数据库获取最新的详细信息
|
|||
|
|
3. 增强选题数据
|
|||
|
|
4. 生成内容
|
|||
|
|
|
|||
|
|
## 🎉 预期效果
|
|||
|
|
|
|||
|
|
### 1. 数据一致性
|
|||
|
|
- 确保整个流程中ID的连续性
|
|||
|
|
- 避免名称不匹配导致的数据丢失
|
|||
|
|
|
|||
|
|
### 2. 系统稳定性
|
|||
|
|
- 多级兜底机制确保系统不会因为数据库问题而崩溃
|
|||
|
|
- 详细的日志记录便于问题排查
|
|||
|
|
|
|||
|
|
### 3. 数据准确性
|
|||
|
|
- 内容生成时使用最新的数据库数据
|
|||
|
|
- 避免使用过期或不准确的缓存数据
|
|||
|
|
|
|||
|
|
### 4. 可观测性
|
|||
|
|
- 匹配率监控
|
|||
|
|
- 详细的日志记录
|
|||
|
|
- 兜底数据标记
|
|||
|
|
|
|||
|
|
## 🚀 使用建议
|
|||
|
|
|
|||
|
|
### 1. 监控日志
|
|||
|
|
关注以下日志信息:
|
|||
|
|
- ID匹配率低于50%的警告
|
|||
|
|
- 兜底数据使用情况
|
|||
|
|
- 数据库查询失败的频率
|
|||
|
|
|
|||
|
|
### 2. 数据维护
|
|||
|
|
- 定期清理重复数据
|
|||
|
|
- 更新"请修改产品名字"等占位数据
|
|||
|
|
- 确保软删除字段的正确使用
|
|||
|
|
|
|||
|
|
### 3. 性能优化
|
|||
|
|
- 考虑为常用数据添加缓存
|
|||
|
|
- 优化数据库查询性能
|
|||
|
|
- 定期清理无效数据
|
|||
|
|
|
|||
|
|
## 📋 测试验证
|
|||
|
|
|
|||
|
|
### 1. 功能测试
|
|||
|
|
- 测试各种ID组合的选题生成
|
|||
|
|
- 验证名称匹配的准确性
|
|||
|
|
- 确认兜底机制的有效性
|
|||
|
|
|
|||
|
|
### 2. 性能测试
|
|||
|
|
- 大批量选题生成的性能
|
|||
|
|
- 数据库查询的响应时间
|
|||
|
|
- 内存使用情况
|
|||
|
|
|
|||
|
|
### 3. 错误处理测试
|
|||
|
|
- 数据库连接失败时的行为
|
|||
|
|
- 无效ID的处理
|
|||
|
|
- 数据缺失时的兜底效果
|