Merge #47 into develop from fix/othername-name

[fix]Fix the bug that affects user memory.

* fix/othername-name: (11 commits squashed)

  - [fix]Fix the issue with the display of the user's memory list

  - [fix]Ensure the six dimensions of emotional expression

  - [fix]Fix the issue with the display of the user's memory list

  - [fix]Ensure the six dimensions of emotional expression

  - Merge branch 'fix/othername-name' of codeup.aliyun.com:redbearai/python/redbear-mem-open into fix/othername-name

  - [fix]Restore the display of memory types

  - [fix]Fix the issue with the display of the user's memory list

  - [fix]Ensure the six dimensions of emotional expression

  - [fix]Restore the display of memory types

  - Merge branch 'fix/othername-name' of codeup.aliyun.com:redbearai/python/redbear-mem-open into fix/othername-name

  - [updated]Update the title of the "analytics/node_statistics" log

Signed-off-by: 乐力齐 <accounts_690c7b0af9007d7e338af636@mail.teambition.com>
Reviewed-by: aliyun6762716068 <accounts_68cb7c6b61f5dcc4200d6251@mail.teambition.com>
Merged-by: aliyun6762716068 <accounts_68cb7c6b61f5dcc4200d6251@mail.teambition.com>

CR-link: https://codeup.aliyun.com/redbearai/python/redbear-mem-open/change/47
This commit is contained in:
乐力齐
2025-12-24 10:11:31 +00:00
committed by 孙科
parent 6338edda11
commit 9cf8d5cb0a
6 changed files with 129 additions and 33 deletions

View File

@@ -65,19 +65,9 @@ class EmotionAnalyticsService:
"""获取情绪标签统计
查询指定用户的情绪类型分布,包括计数、百分比和平均强度。
Args:
end_user_id: 宿主ID用户组ID
emotion_type: 可选的情绪类型过滤
start_date: 可选的开始日期ISO格式
end_date: 可选的结束日期ISO格式
limit: 返回结果的最大数量
Returns:
Dict: 包含情绪标签统计的响应数据:
- tags: 情绪标签列表
- total_count: 总情绪数量
- time_range: 时间范围信息
确保返回所有6个情绪维度joy、sadness、anger、fear、surprise、neutral
即使某些维度没有数据也会返回count=0的记录。
"""
try:
logger.info(f"获取情绪标签统计: user={end_user_id}, type={emotion_type}, "
@@ -92,8 +82,34 @@ class EmotionAnalyticsService:
limit=limit
)
# 定义所有6个情绪维度
all_emotion_types = ['joy', 'sadness', 'anger', 'fear', 'surprise', 'neutral']
# 将查询结果转换为字典,方便查找
tags_dict = {tag["emotion_type"]: tag for tag in tags}
# 补全缺失的情绪维度
complete_tags = []
for emotion in all_emotion_types:
if emotion in tags_dict:
complete_tags.append(tags_dict[emotion])
else:
# 如果该情绪类型不存在,添加默认值
complete_tags.append({
"emotion_type": emotion,
"count": 0,
"percentage": 0.0,
"avg_intensity": 0.0
})
# 计算总数
total_count = sum(tag["count"] for tag in tags)
total_count = sum(tag["count"] for tag in complete_tags)
# 如果有数据重新计算百分比因为补全了0值项
if total_count > 0:
for tag in complete_tags:
if tag["count"] > 0:
tag["percentage"] = round((tag["count"] / total_count) * 100, 2)
# 构建时间范围信息
time_range = {}
@@ -104,12 +120,12 @@ class EmotionAnalyticsService:
# 格式化响应
response = {
"tags": tags,
"tags": complete_tags,
"total_count": total_count,
"time_range": time_range if time_range else None
}
logger.info(f"情绪标签统计完成: total_count={total_count}, tags_count={len(tags)}")
logger.info(f"情绪标签统计完成: total_count={total_count}, tags_count={len(complete_tags)}")
return response
except Exception as e:

View File

@@ -272,7 +272,7 @@ async def get_workspace_total_memory_count(
from app.repositories.end_user_repository import EndUserRepository
repo = EndUserRepository(db)
end_user = repo.get_by_id(uuid.UUID(end_user_id))
user_name = end_user.name if end_user else None
user_name = end_user.other_name if end_user else None
return {
"total_memory_count": search_result.get("total", 0),

View File

@@ -534,6 +534,91 @@ async def analytics_node_statistics(
return data
async def analytics_memory_types(
db: Session,
end_user_id: Optional[str] = None
) -> Dict[str, Any]:
"""
统计8种记忆类型的数量
计算规则:
1. 感知记忆 = statement + entity
2. 工作记忆 = chunk + entity
3. 短期记忆 = chunk
4. 长期记忆 = entity
5. 显性记忆 = 1/2 * entity
6. 隐形记忆 = 1/3 * entity
7. 情绪记忆 = statement
8. 情景记忆 = memory_summary
Args:
db: 数据库会话
end_user_id: 可选的终端用户ID (UUID),用于过滤特定用户的节点
Returns:
{
"感知记忆": int,
"工作记忆": int,
"短期记忆": int,
"长期记忆": int,
"显性记忆": int,
"隐形记忆": int,
"情绪记忆": int,
"情景记忆": int
}
"""
# 定义需要查询的节点类型
node_types = {
"Statement": "Statement",
"Entity": "ExtractedEntity",
"Chunk": "Chunk",
"MemorySummary": "MemorySummary"
}
# 存储每种节点类型的计数
node_counts = {}
# 查询每种节点类型的数量
for key, node_type in node_types.items():
if end_user_id:
query = f"""
MATCH (n:{node_type})
WHERE n.group_id = $group_id
RETURN count(n) as count
"""
result = await _neo4j_connector.execute_query(query, group_id=end_user_id)
else:
query = f"""
MATCH (n:{node_type})
RETURN count(n) as count
"""
result = await _neo4j_connector.execute_query(query)
# 提取计数结果
count = result[0]["count"] if result and len(result) > 0 else 0
node_counts[key] = count
# 获取各节点类型的数量
statement_count = node_counts.get("Statement", 0)
entity_count = node_counts.get("Entity", 0)
chunk_count = node_counts.get("Chunk", 0)
memory_summary_count = node_counts.get("MemorySummary", 0)
# 按规则计算8种记忆类型
memory_types = {
"感知记忆": statement_count + entity_count,
"工作记忆": chunk_count + entity_count,
"短期记忆": chunk_count,
"长期记忆": entity_count,
"显性记忆": entity_count // 2, # 1/2 entity使用整除
"隐形记忆": entity_count // 3, # 1/3 entity使用整除
"情绪记忆": statement_count,
"情景记忆": memory_summary_count
}
return memory_types
async def analytics_graph_data(
db: Session,
end_user_id: str,