使用DuckDB查询DeepSeek历史对话
DeepSeek网页版在左下角个人信息/系统设置的账号管理页签中有个“导出所有历史对话”功能,点击“导出”,片刻就能生成一个deepseek_data-2025-06-14.zip
的文件,里面有2个json文件,直接用文本编辑器查看不太方便。
而用DuckDB查询却很方便。
一开始,我们不知道这个json包括哪些字段,输入:
D select * from 'conv.json' limit 1;
┌──────────────────────┬──────────────────────┬──────────────────────┬──────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ id │ title │ inserted_at │ updated_at │ mapping │
│ uuid │ varchar │ varchar │ varchar │ struct(root struct(id varchar, parent json, children varchar[], message json), "1" struct(id varchar, parent va… │
├──────────────────────┼──────────────────────┼──────────────────────┼──────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ e6535268-e25a-4620… │ 麻将胡牌判断函数实现 │ 2025-01-23T14:10:3… │ 2025-01-23T14:48:2… │ {'root': {'id': root, 'parent': NULL, 'children': [1], 'message': NULL}, '1': {'id': 1, 'parent': root, 'childr… │
└──────────────────────┴──────────────────────┴──────────────────────┴──────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
可见,这个文件有5个字段,对话信息保存在mapping中,其他都是它的属性信息,标题,建立和更新时间,还有uuid。
为了看起来方便,我们设置输出模式为list, 这样就能显示mapping的全部内容,而不会被截断,我们看到mapping中的各个字段,有我们的问话和deepseek的回答。
D .mode list
D select mapping from 'conv.json' limit 1;
mapping
{'root': {'id': root, 'parent': NULL, 'children': [1], 'message': NULL}, '1': {'id': 1, 'parent': root, 'children':
[2], 'message': {'files': [], 'search_results': NULL, 'model': deepseek-chat, 'reasoning_content': NULL,
'content': 请给出一个函数,输入是长度为14的unicode的麻将字符串,返回是否胡牌的布尔值, 'inserted_at': '2025-01-23T14:10:32.372143+00:00'}}, '2': {'id': 2, 'parent': 1, 'children': [4],
'message': {'files': [], 'search_results': NULL, 'model': deepseek-chat, 'reasoning_content': NULL,
'content': '要判断一个长度为14的Unicode字符串是否表示一副胡牌的麻将牌型,我们需要遵循麻将的基本规则。通常,胡牌的牌型由4个顺子或刻子(每组3张牌)加上一对将牌组成。以下是Python代码实现:`` `python
def is_winning_hand(hand):from collections import defaultdictif len(hand) != 14:return False
一般情况下,这样输出已经足够了,对话中的换行也从json文件中的转义符\n转换成了实际换行,很便于阅读。
而如果历史记录很多,也可以根据标题和时间进行筛选,这时,我把它切回box模式
D .mode box
D select title, inserted_at from 'conv.json' where inserted_at::date between date'2025-06-01' and date'2025-06-15' and title like'%DuckDB%';
┌──────────────────────────────────────────────────┬──────────────────────────────────┐
│ title │ inserted_at │
├──────────────────────────────────────────────────┼──────────────────────────────────┤
│ DuckDB PostgreSQL查询功能实现分析 │ 2025-06-01T06:12:58.998000+08:00 │
│ DuckDB实现XLS读取功能 │ 2025-06-08T12:23:09.081000+08:00 │
│ DuckDB查询结果导出XLS实现 │ 2025-06-08T22:36:21.605000+08:00 │
│ DuckDB CSV Copy Function Implementation Analysis │ 2025-06-09T13:14:15.707396+00:00 │
│ DuckDB技术文档翻译与总结 │ 2025-06-13T17:55:30.205000+08:00 │
└──────────────────────────────────────────────────┴──────────────────────────────────┘