第三周/第四节课程: 使用聚合管道高效查找数据

1. 引言

统计某日发布的二手物品在随后七天内, 交易完成时间是一天的类目分布占比.
也就是有哪些类目当天发布当天就有人买了.

2. 分析

  • 利用管道模型聚合数据
    collection.aggregate(pipeline)
    有这么多过虑管道, 每个管道都是一个字典的结构, 常用的为$match``$group``$sort``$limit
    Paste_Image.png

database -> pipeline -> data
不同管道有不同的作用, 有的负责筛选匹配, 有的负责聚合整合统计, 还有的负责重新分组重新命名, 之后各管道叠加起来


Paste_Image.png

3. 实现

In [1] :
from pymongo import MongoClient
from string import punctuation
from datetime import timedelta, date
import charts

In [2] :
client = MongoClient('10.66.17.17', 27017)
database = client['ganji']
item_info = database['item_info']

In [3] :
# 查看下源数据
[i for i in item_info.find().limit(3)]
Out [3] :
[{'_id': ObjectId('5698f524a98063dbe9e91ca8'),
  'area': ['朝阳', '高碑店'],
  'cates': ['北京58同城', '北京二手市场', '北京二手家电', '北京二手冰柜'],
  'look': '-',
  'price': 450,
  'pub_date': '2016.01.12',
  'time': 0,
  'title': '【图】95成新小冰柜转让 - 朝阳高碑店二手家电 - 北京58同城',
  'url': 'http://bj.58.com/jiadian/24541664530488x.shtml'},
 {'_id': ObjectId('5698f525a98063dbe4e91ca8'),
  'area': ['朝阳', '定福庄'],
  'cates': ['北京58同城', '北京二手市场', '北京二手家电', '北京二手洗衣机'],
  'look': '-',
  'price': 1500,
  'pub_date': '2016.01.14',
  'time': 2,
  'title': '【图】洗衣机,小冰箱,小冰柜,冷饮机 - 朝阳定福庄二手家电 - 北京58同城',
  'url': 'http://bj.58.com/jiadian/24349380911041x.shtml'},
 {'_id': ObjectId('5698f525a98063dbe7e91ca8'),
  'area': ['朝阳', '望京'],
  'cates': ['北京58同城', '北京二手市场', '北京二手台式机/配件'],
  'look': '-',
  'price': 1500,
  'pub_date': '2015.12.27',
  'time': 3,
  'title': '【图】三星 A5 白色 没有打开过 - 朝阳望京台式机/配件 - 北京58同城',
  'url': 'http://bj.58.com/diannao/24475337853109x.shtml'}]

In [4] :
# 定义pipeline模型
pipeline = [
    # 大于某个日期小于某个日期且3天内完成成交的
    # {'$match': {'$and': [{'pub_date': {'$gt': '2015.12.24', '$lt': '2015.12.26'}}, {'time': 3}]}},
    # 发布日期为'2015.12.24'且3天内完成成交的
    {'$match': {'$and': [{'pub_date': '2015.12.24'}, {'time': 3}]}},
    # 以源数据的'price'字段分组, 且统计其出现次数, 出现一次则加1, '$sum'后的数字是多少就加多少
    {'$group': {'_id': '$price', 'counts': {'$sum': 1}}},
    # 排序, 指定以什么字段排序, 1为从低到高, -1为从高到低
    {'$sort': {'counts': -1}},
    # 限制显示多少条数据
    {'$limit': 10},
]

In [5] :
[i for i in item_info.aggregate(pipeline)]
Out [5] :
[{'_id': 0, 'counts': 14},
 {'_id': 1000, 'counts': 11},
 {'_id': 300, 'counts': 7},
 {'_id': 100, 'counts': 6},
 {'_id': 50, 'counts': 5},
 {'_id': 1800, 'counts': 5},
 {'_id': 700, 'counts': 4},
 {'_id': 200, 'counts': 4},
 {'_id': 350, 'counts': 4},
 {'_id': 3000, 'counts': 3}]

In [6] :
# 定义pipeline模型
pipeline2 = [
    {'$match': {'$and': [{'pub_date': '2015.12.28'}, {'time': 1}]}},
    {'$group': {'_id': {'$slice': ['$cates', 2, 1]}, 'counts': {'$sum': 1}}},
    {'$sort': {'counts': -1}},
]

In [7] :
# 打印看下管道模型的输出结果
[i for i in item_info.aggregate(pipeline2)]
Out [7] :
[{'_id': ['北京二手家电'], 'counts': 40},
 {'_id': ['北京二手服装/鞋帽/箱包'], 'counts': 21},
 {'_id': ['北京二手母婴/儿童用品'], 'counts': 18},
 {'_id': ['北京二手图书/音像/软件'], 'counts': 17},
 {'_id': ['北京二手台式机/配件'], 'counts': 15},
 {'_id': ['北京二手办公用品/设备'], 'counts': 14},
 {'_id': ['北京二手文体/户外/乐器'], 'counts': 12},
 {'_id': ['北京二手数码产品'], 'counts': 10},
 {'_id': ['北京二手手机'], 'counts': 8},
 {'_id': ['北京二手笔记本'], 'counts': 6},
 {'_id': ['北京其他二手物品'], 'counts': 6},
 {'_id': ['北京二手平板电脑'], 'counts': 5}]

In [8] :
# 定义函数方便快速生成图表数据
def time_data_gen(date, time):
    # 定义管道模型
    pipeline = [
        {'$match': {'$and': [{'pub_date': date}, {'time': time}]}},
        {'$group': {'_id': {'$slice': ['$cates', 2, 1]}, 'counts': {'$sum': 1}}},
        {'$sort': {'counts': -1}},
    ]
    # 生成所有数据
    for i in item_info.aggregate(pipeline):
        yield [i['_id'][0], i['counts']]
# 输出看下结果        
[i for i in time_data_gen('2015.12.28', 1)]
Out [8] :
[['北京二手家电', 40],
 ['北京二手服装/鞋帽/箱包', 21],
 ['北京二手母婴/儿童用品', 18],
 ['北京二手图书/音像/软件', 17],
 ['北京二手台式机/配件', 15],
 ['北京二手办公用品/设备', 14],
 ['北京二手文体/户外/乐器', 12],
 ['北京二手数码产品', 10],
 ['北京二手手机', 8],
 ['北京二手笔记本', 6],
 ['北京其他二手物品', 6],
 ['北京二手平板电脑', 5]]

In [9] :
# 图表参数
options = {
    'char': {'zoomType': 'xy'},
    'title': {'text': '发帖量统计, 好看又好玩'},
    'subtitle': {'text': '某日发布的二手物品在随后七天内, 交易完成时间是一天的类目分布占比'},
}

In [10] :
# 图表数据
serises = {
    'type': 'pie',
    'data': [i for i in time_data_gen('2015.12.28', 1)],
    'name': 'One day',
}
# 输出饼状图表
charts.plot(serises, show='inline', options=options)
Out [10] :
Paste_Image.png

4. 总结

  • 管道模型就像是一层层的管子, 从数据库中通过管道取出数据
  • 这些过滤管道, 每一个都是字典的结构
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容