第三周/第三节学习课程: 使用find()函数精确查找数据

1. 引言

查找某个时间的数据, 只显示特定字段
绘制七日内上海城区二手物品走势图

2. 分析

  • mongodb查找数据的方法
  • mongodb显示特定字段的方法
  • charts显示走势图的方法
  • 显示charts折线图所需要的数据格式

3. 实现

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

Server running in the folder /home/wjh at 127.0.0.1:40064


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

In [3] :
# 包含所有二级区域的列表
area_list = [i['area'][1] for i in item_info_collection.find()]
# 区域名字是唯一的集合
area_set = set(area_list)
# 输出看下是什么结果
print(len(area_set), area_set)

21 {'闵行', '奉贤', '杨浦', '旮旯', '南汇', '虹口', '静安', '金山', '浦东', '青浦', '卢湾', '长宁', '上海周边', '崇明', '嘉定', '黄浦', '宝山', '闸北', '普陀', '徐汇', '松江'}


In [4] :
# 查找特定时间的数据, 并指定显示的字段, 1为显示 0为不显示, 如下为0的字段不显示, 其它都显示
[i for i in item_info_collection.find({'update': {'$in': ['07-01', '07-02']}}, {'_id': 0, 'cate': 0, 'degree': 0, 'title': 0, 'type': 0, 'price': 0}).limit(5)]
Out [4] :
[{'area': ['上海', '浦东', '东明路'], 'update': '07-02'},
 {'area': ['上海', '浦东', '川沙'], 'update': '07-02'},
 {'area': ['上海', '徐汇'], 'update': '07-02'},
 {'area': ['上海', '闵行', '梅陇'], 'update': '07-01'},
 {'area': ['上海', '浦东', '北蔡'], 'update': '07-01'}]
In [5] :
# _id不指定的话默认是显示的, 所以将其设置为0不显示, 如下为1的字段则显示, 其它都不显示
[i for i in item_info_collection.find({}, {'_id': 0, 'area': 1}).limit(5)]
Out [5] :
[{'area': ['上海', '长宁', '中山公园']},
 {'area': ['上海', '松江']},
 {'area': ['上海', '金山', '金山卫']},
 {'area': ['上海', '虹口', '四平路']},
 {'area': ['上海', '浦东', '八佰伴']}]

In [6] :
# 以下是timedelta, date的用法说明:
# 单位是小时, 然后时间就可以按小时增长
print(timedelta(hours=2))
# 单位是天, 然后时间就按天增长
print(timedelta(days=1))
# 传入3个int, 获取时间
print(date(2016,2,3))

2:00:00
1 day, 0:00:00
2016-02-03


In [7] :
# 定义生成日期列表函数, 传递两个参数(起始日期, 结束日期)
def date_gen(date1, date2):
    # 起始日期
    just_date = date(2016, int(date1.split('-')[0]), int(date1.split('-')[1]))
    # 结束日期
    end_date = date(2016, int(date2.split('-')[0]), int(date2.split('-')[1]))
    # 日期增长步长
    step = timedelta(days=1)
    # 循环生成日期列表
    while just_date <= end_date:
        yield just_date.strftime('%m-%d')
        just_date += step
# 输出看下结果
[i for i in date_gen('07-5', '07-10')]
Out [7] :
['07-05', '07-06', '07-07', '07-08', '07-09', '07-10']

In [8] :
# 定义生成图表字典列表
def area_data_gen(types, date1, date2):
    # 在区域名称集合内循环
    for area in area_set:
        # 区域出现次数列表
        area_posts = []
        # 指定时间段内循环
        for date in date_gen(date1, date2):
            # 查找特定时间特定区域的数据并生成列表
            find = list(item_info_collection.find({'update': date, 'area': area}))
            # 某一天区域出现的次数
            count = len(find)
            # 将这天区域出现的次数添加至列表
            area_posts.append(count)
        # 一个区域的图表数据, data为这几天出现的次数
        data = {
            'name': area,
            'data': area_posts,
            'type': types
        }
        # 生成列表
        yield data
# 输出看下
[i for i in area_data_gen('line', '06-30', '07-06')]
Out [8] :
[{'data': [151, 239, 258, 351, 403, 499, 805], 'name': '闵行', 'type': 'line'},
 {'data': [42, 39, 38, 59, 58, 93, 116], 'name': '奉贤', 'type': 'line'},
 {'data': [87, 88, 104, 123, 145, 164, 283], 'name': '杨浦', 'type': 'line'},
 {'data': [54, 50, 66, 89, 104, 136, 224], 'name': '旮旯', 'type': 'line'},
 {'data': [25, 23, 23, 60, 57, 83, 100], 'name': '南汇', 'type': 'line'},
 {'data': [30, 48, 58, 66, 96, 139, 266], 'name': '虹口', 'type': 'line'},
 {'data': [38, 34, 40, 41, 68, 99, 117], 'name': '静安', 'type': 'line'},
 {'data': [8, 7, 14, 18, 13, 37, 33], 'name': '金山', 'type': 'line'},
 {'data': [259, 393, 436, 591, 663, 842, 1375], 'name': '浦东', 'type': 'line'},
 {'data': [27, 53, 54, 64, 73, 83, 112], 'name': '青浦', 'type': 'line'},
 {'data': [14, 18, 18, 24, 24, 43, 31], 'name': '卢湾', 'type': 'line'},
 {'data': [37, 47, 82, 64, 107, 130, 171], 'name': '长宁', 'type': 'line'},
 {'data': [26, 21, 24, 20, 39, 47, 53], 'name': '上海周边', 'type': 'line'},
 {'data': [2, 5, 1, 0, 5, 2, 2], 'name': '崇明', 'type': 'line'},
 {'data': [69, 86, 141, 134, 175, 211, 352], 'name': '嘉定', 'type': 'line'},
 {'data': [19, 35, 41, 44, 70, 110, 127], 'name': '黄浦', 'type': 'line'},
 {'data': [100, 98, 149, 135, 247, 228, 378], 'name': '宝山', 'type': 'line'},
 {'data': [44, 48, 65, 73, 90, 105, 198], 'name': '闸北', 'type': 'line'},
 {'data': [85, 96, 119, 155, 177, 195, 352], 'name': '普陀', 'type': 'line'},
 {'data': [70, 110, 134, 105, 202, 238, 350], 'name': '徐汇', 'type': 'line'},
 {'data': [98, 101, 152, 165, 200, 274, 366], 'name': '松江', 'type': 'line'}]

In [9] :
# 图表参数
options = {
    'char': {'zoomType': 'xy'},
    'title': {'text': '七日内上海城区二手物品交易量'},
    'subtitle': {'text': '图表展示数据走势'},
    'xAxis': {'categories': [i for i in date_gen('06-30', '07-06')]},
    'yAxis': {'text': {'text': '数量'}},
}

In [10] :
# 生成折线图表数据
serises = [i for i in area_data_gen('line', '06-30', '07-06')]
# 展示图表柱状图
charts.plot(serises, show='inline', options=options)
Out [10] :
Paste_Image.png

In [11] :
# 生成柱状图表数据
serises = [i for i in area_data_gen('column', '06-30', '07-06')]
# 展示图表柱状图
charts.plot(serises, show='inline', options=options)
Out [11] :
Paste_Image.png

4. 总结

  • mongodb的find()方法的使用
    MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,及常规 SQL 的 AND 条件
  • highcharts的图表展示方法有各种各样的: 折线图 柱状图

推荐阅读更多精彩内容

  • 视频重点 练习代码 扩展 1. 视频重点 from datetime imort timedelta,date处理...
    唐宗宋祖阅读 982评论 0 0
  • 前天在网上看到了李笑来推荐的键盘,下单买了一个,今天货到家了,试用了一下,非常的爽,可以连接手机电脑平板,这些省了...
    一匹随机漫步的马阅读 300评论 0 0
  • 主持人:请各位查看自己的身份牌。这局游戏中,有三个狼人、四个村民、四个神职。接下来,天黑请闭眼。 主持人:预言家请...
    被窝大作战阅读 363评论 0 1
  • 我曾以为我是这个世界上最幸福的人 三年如一日,每月写下一首诗 我曾以为我是这个世界上最幸福的人 在无数个夜里仰望星...
    高壁缺阅读 69评论 0 0
  • 今天真的很气愤,一个高中女生加我,本着相逢即是有缘的理念,我同意了。 然后她居然来了句你是男的吧,我说嗯,没有女朋...
    纳怒西嘉阅读 134评论 0 0