Python数据持久化-MongoDB篇

2018年7月6日笔记
下文中的操作都是使用python操作mongoDB,所以前提是必须安装python和mongoDB。

1. 安装pymongo

在cmd或者PowerShell中运行命令:pip install pymongo

2. 插入数据

2.1 插入一条数据

引入pymongo库中的MongoClient类,使用该类的初始化方法实例化一个对象赋值给conn
conn.myschool为数据库school,将其赋值给变量db
db.students为数据库school中的students集合,将其赋值给变量students
定义一个数据类型为字典dict的变量zhangsan
往数据库中的students集合中插入zhangsan的信息文档,students.insert_one(zhangsan)

from pymongo import MongoClient

if __name__ == '__main__':
    conn = MongoClient('localhost')
    db = conn.myschool
    students = db.students
    zhangsan = dict(
        name="zhangsan",
        age=20,
        sex="boy",
        contact=dict(
            email1="abc@qq.com",
            email2="123@qq.com"
        )
    )
    students.insert_one(zhangsan)

2.2 插入多条数据

from pymongo import MongoClient

if __name__ == '__main__':
    conn = MongoClient('localhost')
    db = conn.myschool
    students = db.students
    lisi = dict(
        name = 'lisi',
        habit = dict(
            habit1 = 'eat',
            habit2 = 'sleep'
        )
    )
    wangwu = dict(
        name = 'wangwu',
        age = 20,
        sex = 'boy'
    )
    students.insert_many([lisi,wangwu])

2.3 使用循环创建3个班,并随机添加10个学生

from pymongo import MongoClient
from random import randint
if __name__ == '__main__':
    conn = MongoClient('localhost')
    db = conn.school
    hobby_list = ['sing','drawing','run','football','basketball']
    grade_list = ['grade_1_1','grade_1_2','grade_1_3']
    for grade in grade_list:
        collection = db.get_collection(grade)
        collection.drop()
        for i in range(10):
            student = dict(
                name = "zhangsan" + str(i),
                age = randint(1,9),
                sex = "男" if randint(0,1) else "女",
                hobby = hobby_list[:randint(0,5)]
            )
            collection.insert_one(student)

3.查询数据

在进行查询的时候,必须要先执行2-3节中的代码,确保school数据库中插入3个班集合

3.1 查询集合中全部数据

示例代码如下:

from pymongo import MongoClient

if __name__ == '__main__':
    conn = MongoClient('localhost')
    db = conn.school
    students = db.grade_1_3
    cursor = students.find()
    for i in cursor:
        print(i)
图片.png-57.9kB
图片.png-57.9kB

3.2 过滤查询

查询之前先定义一个数据类型为字典dict的变量filter
filter示例,查询年龄等于4的文档:filter = {"age":4}
代码示例如下,代码能够成功运行,具体的数据库名和集合名要根据自己电脑中的MongoDB情况进行更改:

from pymongo import MongoClient

if __name__ == '__main__':
    conn = MongoClient('localhost')
    db = conn.school
    students = db.grade_1_3
    filter = {"age": 4}
    cursor = students.find(filter)
    for i in cursor:
        print(i)

filter中操作符及其含义


图片.png-131.5kB
图片.png-131.5kB

3.2.1 $in操作符示例:

from pymongo import MongoClient

if __name__ == '__main__':
    conn = MongoClient('localhost')
    db = conn.school
    students = db.grade_1_3
    filter = {"name": {'$in':['zhangsan2','zhangsan3']}}
    cursor = students.find(filter)
    for i in cursor:
        print(i)

上面一段代码的运行结果如下:

{'_id': ObjectId('5b3f0ea2ba50f64850ef1cda'), 'name': 'zhangsan2', 'age': 3, 'sex': '女', 'hobby': ['sing', 'drawing']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1cdb'), 'name': 'zhangsan3', 'age': 3, 'sex': '男', 'hobby': ['sing', 'drawing', 'run', 'football']}

3.2.2 $gt操作符示例:

from pymongo import MongoClient

if __name__ == '__main__':
    conn = MongoClient('localhost')
    db = conn.school
    students = db.grade_1_3
    filter = {"age": {'$gt':4}}
    cursor = students.find(filter)
    for i in cursor:
        print(i)

上面一段代码的运行结果如下:

{'_id': ObjectId('5b3f0ea2ba50f64850ef1cd8'), 'name': 'zhangsan0', 'age': 7, 'sex': '女', 'hobby': ['sing', 'drawing', 'run']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1cd9'), 'name': 'zhangsan1', 'age': 5, 'sex': '女', 'hobby': ['sing', 'drawing', 'run', 'football']}

3.2.3 $gte操作符示例:

from pymongo import MongoClient

if __name__ == '__main__':
    conn = MongoClient('localhost')
    db = conn.school
    students = db.grade_1_3
    filter = {"age": {'$gte':4}}
    cursor = students.find(filter)
    for i in cursor:
        print(i)

上面一段代码运行结果如下:

{'_id': ObjectId('5b3f0ea2ba50f64850ef1cd8'), 'name': 'zhangsan0', 'age': 7, 'sex': '女', 'hobby': ['sing', 'drawing', 'run']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1cd9'), 'name': 'zhangsan1', 'age': 5, 'sex': '女', 'hobby': ['sing', 'drawing', 'run', 'football']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1cdc'), 'name': 'zhangsan4', 'age': 4, 'sex': '女', 'hobby': ['sing', 'drawing', 'run']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1cdf'), 'name': 'zhangsan7', 'age': 4, 'sex': '女', 'hobby': ['sing', 'drawing']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1ce1'), 'name': 'zhangsan9', 'age': 4, 'sex': '女', 'hobby': ['sing', 'drawing', 'run']}

4.更新数据

4.1使用update_many函数

让所有文档中的sex字段都被修改为“男”。

from pymongo import MongoClient

if __name__ == '__main__':
    conn = MongoClient('localhost')
    db = conn.school
    students = db.grade_1_3
    filter = {"sex":"女"}
    updater = {"$set":{"sex":"男"}}
    students.update_many(filter,updater)
    cursor = students.find()
    for i in cursor:
        print(i)

上面一段代码的运行结果如下:

{'_id': ObjectId('5b3f0ea2ba50f64850ef1cd8'), 'name': 'zhangsan0', 'age': 7, 'sex': '男', 'hobby': ['sing', 'drawing', 'run']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1cd9'), 'name': 'zhangsan1', 'age': 5, 'sex': '男', 'hobby': ['sing', 'drawing', 'run', 'football']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1cda'), 'name': 'zhangsan2', 'age': 3, 'sex': '男', 'hobby': ['sing', 'drawing']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1cdb'), 'name': 'zhangsan3', 'age': 3, 'sex': '男', 'hobby': ['sing', 'drawing', 'run', 'football']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1cdc'), 'name': 'zhangsan4', 'age': 4, 'sex': '男', 'hobby': ['sing', 'drawing', 'run']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1cdd'), 'name': 'zhangsan5', 'age': 1, 'sex': '男', 'hobby': ['sing', 'drawing', 'run', 'football']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1cde'), 'name': 'zhangsan6', 'age': 2, 'sex': '男', 'hobby': ['sing']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1cdf'), 'name': 'zhangsan7', 'age': 4, 'sex': '男', 'hobby': ['sing', 'drawing']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1ce0'), 'name': 'zhangsan8', 'age': 1, 'sex': '男', 'hobby': ['sing', 'drawing']}
{'_id': ObjectId('5b3f0ea2ba50f64850ef1ce1'), 'name': 'zhangsan9', 'age': 4, 'sex': '男', 'hobby': ['sing', 'drawing', 'run']}

4.2 $inc操作符示例

让所有文档的age字段加2,即让集合grade_1_1中的所有人年龄加2

from pymongo import MongoClient

def printMongo(collection,filter={},num=3):
    cursor = collection.find(filter)
    for i in cursor[:num]:
        print(i)

if __name__ == "__main__":
    conn = MongoClient("localhost")
    db = conn.school
    students = db.grade_1_1
    printMongo(students)
    updater = {"$inc":{"age":2}}
    students.update_many({},updater)
    print("MongoDB更新数据后:")
    printMongo(students)

上面一段代码的运行结果如下:

{'_id': ObjectId('5b403bdc33514c04b891a363'), 'name': 'zhangsan0', 'age': 7, 'sex': '男', 'hobby': ['sing', 'drawing', 'run', 'football', 'basketball']}
{'_id': ObjectId('5b403bdc33514c04b891a364'), 'name': 'zhangsan1', 'age': 4, 'sex': '男', 'hobby': ['sing', 'drawing', 'run']}
{'_id': ObjectId('5b403bdc33514c04b891a365'), 'name': 'zhangsan2', 'age': 7, 'sex': '女', 'hobby': []}
MongoDB更新数据后:
{'_id': ObjectId('5b403bdc33514c04b891a363'), 'name': 'zhangsan0', 'age': 9, 'sex': '男', 'hobby': ['sing', 'drawing', 'run', 'football', 'basketball']}
{'_id': ObjectId('5b403bdc33514c04b891a364'), 'name': 'zhangsan1', 'age': 6, 'sex': '男', 'hobby': ['sing', 'drawing', 'run']}
{'_id': ObjectId('5b403bdc33514c04b891a365'), 'name': 'zhangsan2', 'age': 9, 'sex': '女', 'hobby': []}

4.3 $min操作符示例

与当前值进行比较,更新值为两者中的较小值
下面一段代码将所有age字段大于6的文档中的age字段修改为6

from pymongo import MongoClient

def printMongo(collection,filter={},num=5):
    cursor = collection.find(filter)
    for i in cursor[:num]:
        print(i)

if __name__ == "__main__":
    conn = MongoClient("localhost")
    db = conn.school
    students = db.grade_1_1
    printMongo(students)
    updater = {"$min":{"age":6}}
    students.update_many({},updater)
    print("MongoDB更新数据后:")
    printMongo(students)

上面一段代码的运行结果如下:

{'_id': ObjectId('5b403efd33514c189890748f'), 'name': 'zhangsan0', 'age': 4, 'sex': '男', 'hobby': ['sing', 'drawing', 'run']}
{'_id': ObjectId('5b403efe33514c1898907490'), 'name': 'zhangsan1', 'age': 9, 'sex': '男', 'hobby': []}
{'_id': ObjectId('5b403efe33514c1898907491'), 'name': 'zhangsan2', 'age': 1, 'sex': '男', 'hobby': ['sing']}
{'_id': ObjectId('5b403efe33514c1898907492'), 'name': 'zhangsan3', 'age': 7, 'sex': '女', 'hobby': ['sing', 'drawing', 'run', 'football']}
{'_id': ObjectId('5b403efe33514c1898907493'), 'name': 'zhangsan4', 'age': 2, 'sex': '男', 'hobby': ['sing', 'drawing', 'run']}
MongoDB更新数据后:
{'_id': ObjectId('5b403efd33514c189890748f'), 'name': 'zhangsan0', 'age': 4, 'sex': '男', 'hobby': ['sing', 'drawing', 'run']}
{'_id': ObjectId('5b403efe33514c1898907490'), 'name': 'zhangsan1', 'age': 6, 'sex': '男', 'hobby': []}
{'_id': ObjectId('5b403efe33514c1898907491'), 'name': 'zhangsan2', 'age': 1, 'sex': '男', 'hobby': ['sing']}
{'_id': ObjectId('5b403efe33514c1898907492'), 'name': 'zhangsan3', 'age': 6, 'sex': '女', 'hobby': ['sing', 'drawing', 'run', 'football']}
{'_id': ObjectId('5b403efe33514c1898907493'), 'name': 'zhangsan4', 'age': 2, 'sex': '男', 'hobby': ['sing', 'drawing', 'run']}

$currentDate操作符示例

添加的时间是按照0时区时间计时:比如本文作者实验时间为2018年7月7日12时28分(北京时间东8区),下面一段代码执行时记录的时间是2018年7月7日4时28分。

from pymongo import MongoClient

def printMongo(collection,filter={},num=2):
    cursor = collection.find(filter)
    for i in cursor[:num]:
        print(i)

if __name__ == "__main__":
    conn = MongoClient("localhost")
    db = conn.school
    students = db.grade_1_1
    printMongo(students)
    updater = {"$currentDate":{"create_time":True}}
    students.update_many({},updater)
    print("MongoDB更新数据后:")
    printMongo(students)

上面一段代码的运行结果如下:

{'_id': ObjectId('5b40413a33514c36d8a854ee'), 'name': 'zhangsan0', 'age': 8, 'sex': '女', 'hobby': ['sing', 'drawing']}
{'_id': ObjectId('5b40413a33514c36d8a854ef'), 'name': 'zhangsan1', 'age': 5, 'sex': '男', 'hobby': ['sing', 'drawing', 'run', 'football']}
MongoDB更新数据后:
{'_id': ObjectId('5b40413a33514c36d8a854ee'), 'name': 'zhangsan0', 'age': 8, 'sex': '女', 'hobby': ['sing', 'drawing'], 'create_time': datetime.datetime(2018, 7, 7, 4, 28, 0, 527000)}
{'_id': ObjectId('5b40413a33514c36d8a854ef'), 'name': 'zhangsan1', 'age': 5, 'sex': '男', 'hobby': ['sing', 'drawing', 'run', 'football'], 'create_time': datetime.datetime(2018, 7, 7, 4, 28, 0, 527000)}

5.删除数据

delete_many()函数用于删除多条数据
delete_one()函数用于删除一条数据

6.查询同时更新

三个可以利用来操作满足filter筛选条件的第一条文档的函数:
find_one_and_replace()
find_one_and_delete()
find_one_and_update()

作业

新建mongoDB数据库employee,里面有两个集合employee_info、employee_salary
(1)分别添加2个集合的数据
(2)查询employee_salary工资大于2000的;查询employee_info员工名称=xxx)
(3)修改employee_salary集合(将员工工资增加3000)
(4)删除员工aa的信息

4道小题合在一起的代码如下:

from pymongo import MongoClient

def printMongo(collection,filter={},num=2):
    cursor = collection.find(filter)
    for i in cursor[:num]:
        print(i)

if __name__ == "__main__":
    conn = MongoClient("localhost")
    db = conn.employee
    info = db.employee_info
    salary = db.employee_salary
    #第1小题
    info.drop()
    salary.drop()
    info.insert_one({"name":"aa","sex":"男","age":23})
    info.insert_one({"name":"bb","sex":"女","age":20})
    salary.insert_one({"name":"aa","salary":3000})
    salary.insert_one({"name": "bb", "salary": 1800})
    printMongo(info)
    printMongo(salary)
    # 第2小题
    filter = {"salary":{"$gt":2000}}
    print("找出工资大于2000的员工:")
    printMongo(salary,filter)
    filter2 = {'name':"bb"}
    print("找出姓名为bb的员工")
    printMongo(info,filter2)
    ##第3小题
    print("没有增加工资时:")
    printMongo(salary)
    updater = {"$inc":{"salary":3000}}
    salary.update_many({},updater)
    print("增加工资后:")
    printMongo(salary)
    ##第4小题
    print("没有删除员工aa时打印所有员工信息:")
    printMongo(info)
    printMongo(salary)
    print("删除员工aa后打印所有员工信息")
    info.delete_one({"name":"aa"})
    salary.delete_one({"name":"aa"})
    printMongo(info)
    printMongo(salary)

上面一段代码的运行结果如下:

{'_id': ObjectId('5b404b3333514c1dd0f6c096'), 'name': 'aa', 'sex': '男', 'age': 23}
{'_id': ObjectId('5b404b3333514c1dd0f6c097'), 'name': 'bb', 'sex': '女', 'age': 20}
{'_id': ObjectId('5b404b3333514c1dd0f6c098'), 'name': 'aa', 'salary': 3000}
{'_id': ObjectId('5b404b3333514c1dd0f6c099'), 'name': 'bb', 'salary': 1800}
找出工资大于2000的员工:
{'_id': ObjectId('5b404b3333514c1dd0f6c098'), 'name': 'aa', 'salary': 3000}
找出姓名为bb的员工
{'_id': ObjectId('5b404b3333514c1dd0f6c097'), 'name': 'bb', 'sex': '女', 'age': 20}
没有增加工资时:
{'_id': ObjectId('5b404b3333514c1dd0f6c098'), 'name': 'aa', 'salary': 3000}
{'_id': ObjectId('5b404b3333514c1dd0f6c099'), 'name': 'bb', 'salary': 1800}
增加工资后:
{'_id': ObjectId('5b404b3333514c1dd0f6c098'), 'name': 'aa', 'salary': 6000}
{'_id': ObjectId('5b404b3333514c1dd0f6c099'), 'name': 'bb', 'salary': 4800}
没有删除员工aa时打印所有员工信息:
{'_id': ObjectId('5b404b3333514c1dd0f6c096'), 'name': 'aa', 'sex': '男', 'age': 23}
{'_id': ObjectId('5b404b3333514c1dd0f6c097'), 'name': 'bb', 'sex': '女', 'age': 20}
{'_id': ObjectId('5b404b3333514c1dd0f6c098'), 'name': 'aa', 'salary': 6000}
{'_id': ObjectId('5b404b3333514c1dd0f6c099'), 'name': 'bb', 'salary': 4800}
删除员工aa后打印所有员工信息
{'_id': ObjectId('5b404b3333514c1dd0f6c097'), 'name': 'bb', 'sex': '女', 'age': 20}
{'_id': ObjectId('5b404b3333514c1dd0f6c099'), 'name': 'bb', 'salary': 4800}

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

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,287评论 0 10
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,577评论 18 399
  • 2018年7月5日笔记 1.MongoDB简介 1.1 NoSQL数据库是什么 NoSQL,指的是非关系型的数据库...
    潇洒坤阅读 615评论 0 0
  • pyspark.sql模块 模块上下文 Spark SQL和DataFrames的重要类: pyspark.sql...
    mpro阅读 9,446评论 0 13
  • 第一次看到“桥头”这个名字,大概是近十年前的时候。那时候,刚刚毕业,正在到处找工作。一次到另外一座县城去应聘,...
    燕语诗心阅读 288评论 0 3