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

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

作者: uvscjh | 来源:发表于2016-07-29 13:54 被阅读30次

    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. 总结

    • 管道模型就像是一层层的管子, 从数据库中通过管道取出数据
    • 这些过滤管道, 每一个都是字典的结构

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/fqdrjttx.html