美文网首页
136MongoDB 数据库入门实战--PyMongo 操作文档

136MongoDB 数据库入门实战--PyMongo 操作文档

作者: Jachin111 | 来源:发表于2021-09-07 06:51 被阅读0次

    PyMongo 操作文档

    实验准备
    打开实验环境,在终端输入如下命令启动 MongoDB 服务,进入命令行交互客户端:

    $ cd
    $ sudo service mongodb start
    $ mongo
    

    创建数据

    进入 ipython 命令行交互解释器,创建 client 客户端对象:

    In [3]: from pymongo import MongoClient
    
    In [4]: client = MongoClient(host='localhost', port=27017)
    

    再次使用 learn 数据库,向数据库的 course 集合中添加数据:

    In [6]: db = client.learn
    
    In [7]: course = db.course
    
    In [8]: course.insert_many([
       ...:     {'name': 'Linux 基础入门', 'author': 'James', 'students_count': 1234},
       ...:     {'name': 'Python 简明教程', 'author': 'Wade', 'students_count': 2234},
       ...:     {'name': 'Git 与 GitHub 入门实践', 'author': 'Wade', 'students_count': 8777}
       ...: ])
    Out[8]: <pymongo.results.InsertManyResult at 0x7fac960bf1c8>
    

    在 MongoDB 客户端中验证操作:

    > show dbs
    admin      0.000GB
    config     0.000GB
    learn      0.000GB
    local      0.000GB
    shiyanlou  0.000GB
    > use learn
    switched to db learn
    > show collections
    course
    > db.course.find().pretty()
    {
            "_id" : ObjectId("5e4cc6bdf9df85a354b867d3"),
            "author" : "James",
            "students_count" : 1234,
            "name" : "Linux 基础入门"
    }
    {
            "_id" : ObjectId("5e4cc6bdf9df85a354b867d4"),
            "author" : "Wade",
            "students_count" : 2234,
            "name" : "Python 简明教程"
    }
    {
            "_id" : ObjectId("5e4cc6bdf9df85a354b867d5"),
            "author" : "Wade",
            "students_count" : 8777,
            "name" : "Git 与 GitHub 入门实践"
    }
    >
    

    上一节实验中我们学到了集合的 find 方法可以获取集合中的全部文档,此外我们还可以使用集合的 count_documents 方法获取文档数量,参数为过滤条件。
    查询全部文档数量,参数为空字典:

    In [9]: course.count_documents({})
    Out[9]: 3
    

    查询条件写到字典里,例如查询 author 为 Wade 的课程数量:

    In [10]: course.count_documents({'author': 'Wade'})
    Out[10]: 2
    

    等同于 MongoDB 客户端中的如下操作:

    > db.course.count()
    3
    > db.course.count({author: 'Wade'})
    2
    >
    

    查询数据

    除了上一节实验中提到的 find 方法,集合对象还提供了 find_one 方法用于查找某一条数据,过滤条件作为参数,例如查询学生数量为 8777 的课程:

    In [17]: course.find_one({'students_count': 8777})
    Out[17]:
    {'_id': ObjectId('5e4cc6bdf9df85a354b867d5'),
     'author': 'Wade',
     'name': 'Git 与 GitHub 入门实践',
     'students_count': 8777}
    

    此外,find 方法也可以提供参数,例如查找 author 为 Wade 的全部课程:

    In [18]: results = list(course.find({'author': 'Wade'}))
    
    In [19]: results
    Out[19]:
    [{'_id': ObjectId('5e4cc6bdf9df85a354b867d4'),
      'author': 'Wade',
      'name': 'Python 简明教程',
      'students_count': 2234},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d5'),
      'author': 'Wade',
      'name': 'Git 与 GitHub 入门实践',
      'students_count': 8777}]
    

    查找 author 为 Wade 且学生数量为 2234 的课程:

    In [20]: results = list(course.find(
        ...:     {'author': 'Wade', 'students_count': 2234}
        ...: ))
    
    In [21]: results
    Out[21]:
    [{'_id': ObjectId('5e4cc6bdf9df85a354b867d4'),
      'author': 'Wade',
      'name': 'Python 简明教程',
      'students_count': 2234}]
    

    需要注意的是 find_one 返回一条数据,数据类型自然就是字典;而 find 方法返回的数据为迭代器,不论查询结果是一条还是多条,我们都可以使用 list 方法将其转换成列表,列表中的元素是字典。
    在 MongoDB 客户端中可以使用 $or 操作符来表示 “或” 条件关系,在 PyMongo 中同样可以,但是需要加引号。
    查询 author 为 James 或 students_count 为 2234 的课程:

    In [25]: results = course.find(
        ...:     {'$or': [
        ...:         {'author': 'James'},
        ...:         {'students_count': 2234}
        ...:     ]}
        ...: )
    
    In [26]: list(results)
    Out[26]:
    [{'_id': ObjectId('5e4cc6bdf9df85a354b867d3'),
      'author': 'James',
      'name': 'Linux 基础入门',
      'students_count': 1234},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d4'),
      'author': 'Wade',
      'name': 'Python 简明教程',
      'students_count': 2234}]
    

    查询 author 为 James 或 students_count 为 2234 的课程的名字:

    In [27]: results = course.find(
        ...:     {'$or': [
        ...:         {'author': 'James'},
        ...:         {'students_count': 2234}
        ...:     ]},
        ...:     {'_id': 0, 'name': 1}
        ...: )
    
    In [28]: list(results)
    Out[28]: [{'name': 'Linux 基础入门'}, {'name': 'Python 简明教程'}]
    

    如上所示,第 2 个参数限制查询字段。首先设置去掉 _id 字段,将其设为 0 ;然后将 name 字段设为 1 。

    修改数据

    同 MongoDB 客户端中的操作一样,使用 update_one 和 update_many 修改文档。这些方法需要提供两个参数:第一个用来确定更新哪一条或哪几条文档,第二个用来提供更新的字段及其值。
    举例说明,将 name 为 'Linux 基础入门' 的课程的 students_count 修改为 1000 :

    In [34]: course.find_one(
        ...:     {'name': 'Linux 基础入门'}
        ...: )
    Out[34]:
    {'_id': ObjectId('5e4cc6bdf9df85a354b867d3'),
     'author': 'James',
     'name': 'Linux 基础入门',
     'students_count': 1234}
    
    In [35]: course.update_one(
        ...:     {'name': 'Linux 基础入门'},
        ...:     {'$set':
        ...:         {'students_count': 1000}
        ...:     }
        ...: )
    Out[35]: <pymongo.results.UpdateResult at 0x7fac86783848>
    
    In [36]: course.find_one(
        ...:     {'name': 'Linux 基础入门'}
        ...: )
    Out[36]:
    {'_id': ObjectId('5e4cc6bdf9df85a354b867d3'),
     'author': 'James',
     'name': 'Linux 基础入门',
     'students_count': 1000}
    

    如上所示,update_one 函数的第一个参数很好理解,它与 find 函数所用参数的一样。第二个参数为 {'set': {'students_count': 1000} ,其中set 叫做操作符,它作为 key 用来设置字段值,value 是一个嵌套键值对。这与 MongoDB 客户端中的操作几乎一样,唯一的不同之处在于 Python 键值对中所有的 key 都要用引号引起来。

    replace_one 方法

    在 MongoDB 客户端中我们学到了 save 函数,它不仅可以创建文档,而且能够修改文档。注意 save 函数修改文档其实是整体替换,而非对某个字段进行修改。在 PyMongo 中集合对象同样有 save 方法,且功能相同。
    不过此方法不再推荐使用。如果要插入一条数据,就使用 insert_one 方法;如果要替换一条数据,就使用 replace_one 方法。替换文档的操作是针对 ObjectId 对象而言,也就是文档的 _id 字段的值。
    举例说明,我们要替换 name 为 'Linux 基础入门' 的文档,也就是修改 _id 字段值为 ObjectId('5e4cc6bdf9df85a354b867d3') 的文档。
    首先,需要引入 ObjectId 类:

    In [44]: from bson.objectid import ObjectId
    

    然后使用 replace_one 执行替换操作:

    In [49]: list(course.find())
    Out[49]:
    [{'_id': ObjectId('5e4cc6bdf9df85a354b867d3'),
      'author': 'James',
      'name': 'Linux 基础入门',
      'students_count': 1000},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d4'),
      'author': 'Wade',
      'name': 'Python 简明教程',
      'students_count': 2234},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d5'),
      'author': 'Wade',
      'name': 'Git 与 GitHub 入门实践',
      'students_count': 8777}]
    
    In [50]: course.replace_one(
        ...:     {'_id': ObjectId('5e4cc6bdf9df85a354b867d3')},
        ...:     {'作者': 'James',
        ...:      '课程名': 'Python 网络编程',
        ...:      '学生数量': 123
        ...:     }
        ...: )
    Out[50]: <pymongo.results.UpdateResult at 0x7fac86574548>
    
    In [51]: list(course.find())
    Out[51]:
    [{'_id': ObjectId('5e4cc6bdf9df85a354b867d3'),
      '作者': 'James',
      '学生数量': 123,
      '课程名': 'Python 网络编程'},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d4'),
      'author': 'Wade',
      'name': 'Python 简明教程',
      'students_count': 2234},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d5'),
      'author': 'Wade',
      'name': 'Git 与 GitHub 入门实践',
      'students_count': 8777}]
    

    如上所示,它与 update_one 方法的调用方式几乎一致。

    删除数据

    在 MongoDB 客户端中,可以使用 deleteOne 和 deleteMany 函数删除文档。在 Python 中也有对应的方法 delete_one 和 delete_many 删除一条或多条文档。参数也是一样的,用于提供过滤条件。
    首先创建测试数据,创建多条具有相同键值对的文档:

    In [52]: list(course.find())
    Out[52]:
    [{'_id': ObjectId('5e4cc6bdf9df85a354b867d3'),
      '作者': 'James',
      '学生数量': 123,
      '课程名': 'Python 网络编程'},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d4'),
      'author': 'Wade',
      'name': 'Python 简明教程',
      'students_count': 2234},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d5'),
      'author': 'Wade',
      'name': 'Git 与 GitHub 入门实践',
      'students_count': 8777}]
    
    In [53]: for i in range(4):
        ...:     course.insert_one({'name': 'Test'})
        ...:
    
    In [54]: list(course.find())
    Out[54]:
    [{'_id': ObjectId('5e4cc6bdf9df85a354b867d3'),
      '作者': 'James',
      '学生数量': 123,
      '课程名': 'Python 网络编程'},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d4'),
      'author': 'Wade',
      'name': 'Python 简明教程',
      'students_count': 2234},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d5'),
      'author': 'Wade',
      'name': 'Git 与 GitHub 入门实践',
      'students_count': 8777},
     {'_id': ObjectId('5e4cd7c9f9df85a354b867d7'), 'name': 'Test'},
     {'_id': ObjectId('5e4cd7c9f9df85a354b867d8'), 'name': 'Test'},
     {'_id': ObjectId('5e4cd7c9f9df85a354b867d9'), 'name': 'Test'},
     {'_id': ObjectId('5e4cd7c9f9df85a354b867da'), 'name': 'Test'}]
    

    使用 delete_one 方法删除一条数据:

    In [55]: course.delete_one({'name': 'Test'})
    Out[55]: <pymongo.results.DeleteResult at 0x7fac86439a48>
    
    In [56]: list(course.find())
    Out[56]:
    [{'_id': ObjectId('5e4cc6bdf9df85a354b867d3'),
      '作者': 'James',
      '学生数量': 123,
      '课程名': 'Python 网络编程'},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d4'),
      'author': 'Wade',
      'name': 'Python 简明教程',
      'students_count': 2234},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d5'),
      'author': 'Wade',
      'name': 'Git 与 GitHub 入门实践',
      'students_count': 8777},
     {'_id': ObjectId('5e4cd7c9f9df85a354b867d8'), 'name': 'Test'},
     {'_id': ObjectId('5e4cd7c9f9df85a354b867d9'), 'name': 'Test'},
     {'_id': ObjectId('5e4cd7c9f9df85a354b867da'), 'name': 'Test'}]
    

    使用 delete_many 删除全部符合条件的文档:

    In [57]: course.delete_many({'name': 'Test'})
    Out[57]: <pymongo.results.DeleteResult at 0x7fac864c1448>
    
    In [58]: list(course.find())
    Out[58]:
    [{'_id': ObjectId('5e4cc6bdf9df85a354b867d3'),
      '作者': 'James',
      '学生数量': 123,
      '课程名': 'Python 网络编程'},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d4'),
      'author': 'Wade',
      'name': 'Python 简明教程',
      'students_count': 2234},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d5'),
      'author': 'Wade',
      'name': 'Git 与 GitHub 入门实践',
      'students_count': 8777}]
    

    修改集合名

    在 PyMongo 中我们可以使用集合的 name 属性查看集合的名字,course 对象实际上就是 db.course 集合,是 learn 数据库中的 course 集合:

    In [59]: db.course == course
    Out[59]: True
    
    # 集合的 full_name 属性值为用点号连接的数据库名和集合名的字符串
    In [60]: db.course.full_name
    Out[60]: 'learn.course'
    
    In [61]: db.course.name
    Out[61]: 'course'
    
    In [62]: course.name
    Out[62]: 'course'
    

    集合对象的 rename 方法可以修改集合名,将 course 更名为 courses :

    In [63]: db.list_collection_names()
    Out[63]: ['course']
    
    In [64]: db.course.rename('courses')
    Out[64]: {'ok': 1.0}
    
    In [65]: db.list_collection_names()
    Out[65]: ['courses']
    
    In [66]: list(db.courses.find())
    Out[66]:
    [{'_id': ObjectId('5e4cc6bdf9df85a354b867d3'),
      '作者': 'James',
      '学生数量': 123,
      '课程名': 'Python 网络编程'},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d4'),
      'author': 'Wade',
      'name': 'Python 简明教程',
      'students_count': 2234},
     {'_id': ObjectId('5e4cc6bdf9df85a354b867d5'),
      'author': 'Wade',
      'name': 'Git 与 GitHub 入门实践',
      'students_count': 8777}]
    

    挑战:向数据库中添加数据

    打开挑战环境,执行如下命令下载文件:

    $ cd ~/Code
    $ wget https://labfile.oss.aliyuncs.com/courses/1364/helloshiyanlou.json
    $ wget https://labfile.oss.aliyuncs.com/courses/1364/helloworld.json
    

    启动 MongoDB 服务:

    $ sudo service mongodb start
    

    在当前目录 /home/shiyanlou/Code 下创建 Python 文件 insert_data.py :

    $ touch insert_data.py
    

    将代码写入其中,实现向 MongoDB 数据库 challenge 的 file 集合中写入文件中的数据,也就是刚刚下载的两个 JSON 文件。
    最后执行程序:

    $ python3 insert_data.py
    
    # File Name: insert_data.py
    import json
    import os
    
    from pymongo import MongoClient
    
    
    json_data_list = []
    file_name_list = os.listdir('/home/shiyanlou/Code')
    
    for file_name in file_name_list:
        if file_name.endswith('.json'):
            with open(file_name) as f:
                json_data_list.append(json.load(f))
    
    client = MongoClient(host='localhost', port=27017)
    db = client.challenge
    db.file.insert_many(json_data_list)
    

    相关文章

      网友评论

          本文标题:136MongoDB 数据库入门实战--PyMongo 操作文档

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