• MongoDB学习笔记:Python 操作MongoDB


    MongoDB学习笔记:Python 操作MongoDB

     

    Pymongo 安装

    安装pymongo
    pip install pymongo
    PyMongo是驱动程序,使python程序能够使用Mongodb数据库,使用python编写而成;

    数据库相关操作

    连接及创建数据库

    import pymongo
    
    connect = pymongo.MongoClient("mongodb://localhost:27017/")
    
    mydb = connect ["test"]

    注意:在 MongoDB 中,初次创建数据库,数据库在获取内容之前不会真正创建的!

    在实际创建数据库(和集合)之前,MongoDB 会一直等待您创建至少有一个文档(记录)的集合(表)。

    连接及查看数据库

    from pymongo import MongoClient
    connect = MongoClient(host='localhost', port=27017, username="root", password="123456")
    #connect = MongoClient('mongodb://localhost:27017/', username="root", password="123456")
    print(connect.list_database_names())

     单例模式封装链接

    注意:

    mongodb的数据库连接池的问题,在创建MongoClient 的时候就已经创建了一个连接池,每一个操作(增删改查等)都会获取一个连接,执行操作后释放连接。

    而连接池是不需要我们及时关闭的,我们可以在程序的生命周期中维护一个这样的单例,至于从连接池中拿出的连接,我们也不需要自行关闭。

    所以这里self.db实例其实已经是一个现成的连接池了,而且线程安全。内置的连接池默认初始了100个连接,每一个操作(增删改查等)都会获取一个连接,执行操作后释放连接。

    最大连接限制最大连接数限制,默认值为 1000000。

    如果你需要为进程中支持大量并发MongoDB操作,请增加maxPoolSize

    client = MongoClient(host, port, maxPoolSize=200)

    或使其不受限制:

    client = MongoClient(host, port, maxPoolSize=None)

    一旦池达到最大大小,其他线程就必须等待套接字可用。PyMongo并不限制等待套接字可用的线程数,应用程序有责任在负载高峰期间将其线程池的大小限制为绑定队列。除非waitQueueTimeoutMS定义,否则允许线程等待任何时间长度 

    client = MongoClient(host, port, waitQueueTimeoutMS=100)

    等待套接字等待时间超过100ms(在此示例中)的线程引发 ConnectionFailure如果限制负载高峰期间的操作持续时间比完成每个操作更为重要,请使用此选项。

    另外不要为了每个操作都去创建一个新的MongoClient实例,这是非常低效的。

     
    from pymongo import MongoClient
    
    class MongoDBClient(object):
        # 饿汉式 单例模式
        def __new__(cls):
            if not hasattr(cls, 'instance'):
                cls.instance = super(MongoDBClient, cls).__new__(cls)
            return cls.instance
        # 代理ip Redis 连接池
        def __init__(self):
            uri = 'mongodb://账号:密码@128.777.244.19:27017/admin'
            self.mgdb = MongoClient(uri, connect=False, maxPoolSize=2000)
    
        def getMongoClient(self):
            return self.mgdb
     

    集合相关操作

    检查 "customers" 集合是否存在

     
    from pymongo import MongoClient
    connect = MongoClient(host='localhost', port=27017, username="root", password="123456")
    #connect = MongoClient('mongodb://localhost:27017/', username="root", password="123456")
    collist = mydb.list_collection_names()
    if "customers" in collist:
      print("The collection exists.")
     

    创建名为 "customers" 的集合

    import pymongo
    
    connect = pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["test"]
    mycol = test_db["customers"]

    获取数据库及集合实例

     
    from pymongo import MongoClient
    connect = MongoClient(host='localhost', port=27017, username="root", password="123456")
    获取数据库实例
    test_db = connect['test']
    获取collection实例
    collection = test_db['students']
     

    删除数据库下的集合

    使用drop() 方法删除在 MongoDB 中的集合。

     
    import pymongo
    
    connect= pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["mydatabase"]
    mycol = test_db["customers"]
    
    mycol.drop()
     

    注意:如果成功删除集合,则 drop() 方法返回 true,如果集合不存在则返回 false。

    文档相关操作

    插入文档

    在集合中插入单个文档

    insert_one() 方法的第一个参数是字典,其中包含希望插入文档中的每个字段名称和值。

     
    from pymongo import MongoClient
    from datetime import datetime
    
    connect = MongoClient(host='localhost', port=27017, username="root", password="123456",)
    # 获取db
    test_db = connect['test']
    # 获取collection
    collection = test_db['students']
    # 构建document
    document = {"author": "Mike",  "text": "My first blog post!", "tags": ["mongodb", "python", "pymongo"], "date": datetime.now()}
    # 插入document
    one_insert = collection.insert_one(document=document)
    print(one_insert.inserted_id)
     

    注意:insert_one() 方法返回 InsertOneResult 对象,该对象拥有属性 inserted_id,用于保存插入文档的 id。

    在集合中插入多个文档

    insert_many() 方法的第一个参数是包含字典的列表,其中包含要插入的数据:

     
    import pymongo
    
    connect= pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["mydatabase"]
    mycol = test_db["customers"]
    
    mylist = [
      { "name": "Amy", "address": "Apple st 652"},
      { "name": "Hannah", "address": "Mountain 21"},
      { "name": "Michael", "address": "Valley 345"},
      { "name": "Sandy", "address": "Ocean blvd 2"},
      { "name": "Betty", "address": "Green Grass 1"},
      { "name": "Richard", "address": "Sky st 331"},
      { "name": "Susan", "address": "One way 98"},
      { "name": "Vicky", "address": "Yellow Garden 2"},
      { "name": "Ben", "address": "Park Lane 38"},
      { "name": "William", "address": "Central st 954"},
      { "name": "Chuck", "address": "Main Road 989"},
      { "name": "Viola", "address": "Sideway 1633"}
    ]
    
    x = mycol.insert_many(mylist)
    
    # 打印被插入文档的  _id 值列表:
    print(x.inserted_ids)
     

    注意:insert_many() 方法返回 InsertManyResult 对象,该对象拥有属性 inserted_ids(id列表),用于保存被插入文档的 id。

    插入带有指定 ID 的多个文档

    如果您不希望 MongoDB 为您的文档分配唯一 id,则可以在插入文档时指定 _id 字段。

    请记住,值必须是唯一的。两个文件不能有相同的 _id。

     
    import pymongo
    
    connect= pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["mydatabase"]
    mycol = test_db["customers"]
    
    mylist = [
      { "_id": 1, "name": "John", "address": "Highway 37"},
      { "_id": 2, "name": "Peter", "address": "Lowstreet 27"},
      { "_id": 3, "name": "Amy", "address": "Apple st 652"},
      { "_id": 4, "name": "Hannah", "address": "Mountain 21"},
      { "_id": 5, "name": "Michael", "address": "Valley 345"},
      { "_id": 6, "name": "Sandy", "address": "Ocean blvd 2"},
      { "_id": 7, "name": "Betty", "address": "Green Grass 1"},
      { "_id": 8, "name": "Richard", "address": "Sky st 331"},
      { "_id": 9, "name": "Susan", "address": "One way 98"},
      { "_id": 10, "name": "Vicky", "address": "Yellow Garden 2"},
      { "_id": 11, "name": "Ben", "address": "Park Lane 38"},
      { "_id": 12, "name": "William", "address": "Central st 954"},
      { "_id": 13, "name": "Chuck", "address": "Main Road 989"},
      { "_id": 14, "name": "Viola", "address": "Sideway 1633"}
    ]
    
    x = mycol.insert_many(mylist)
    
    # 打印被插入文档的  _id 值列表:
    print(x.inserted_ids)
     

    更新集合

    更新集合中的单个文档

    update_one() 方法来更新 MongoDB 集合中的文档。

    第一个参数是 query 对象,用于定义要更新的文档。

    第二个参数是定义文档新值的对象。

    注意:如果查询找到多个记录,则仅更新第一个匹配项。

     
    import pymongo
    
    connect= pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["mydatabase"]
    mycol = test_db["customers"]
    
    myquery = { "address": "Valley 345" }
    newvalues = { "$set": { "address": "Canyon 123" } }
    
    mycol.update_one(myquery, newvalues)
    
    #print "customers" after the update:
    for x in mycol.find():
      print(x)
     

    更新集合中的多个文档

    更新符合查询条件的所有文档,需要使用 update_many() 方法。

     
    import pymongo
    
    connect= pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["mydatabase"]
    mycol = test_db["customers"]
    
    myquery = { "address": { "$regex": "^S" } }
    newvalues = { "$set": { "name": "Minnie" } }
    
    x = mycol.update_many(myquery, newvalues)
    
    print(x.modified_count, "documents updated.")
     

    删除文档

    删除单个文档

    要删除一个文档,我们使用 delete_one() 方法。

    delete_one() 方法的第一个参数是 query 对象,用于定义要删除的文档。

    注释:如果查询找到了多个文档,则仅删除第一个匹配项。

     
    import pymongo
    
    connect= pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["mydatabase"]
    mycol = test_db["customers"]
    
    myquery = { "address": "Mountain 21" }
    
    mycol.delete_one(myquery)
     

    删除多个文档

    要删除多个文档,请使用 delete_many() 方法。

    delete_many() 方法的第一个参数是一个查询对象,用于定义要删除的文档。

     
    import pymongo
    
    connect= pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["mydatabase"]
    mycol = test_db["customers"]
    
    myquery = { "address": {"$regex": "^S"} }
    
    x = mycol.delete_many(myquery)
    
    print(x.deleted_count, " documents deleted.")
     

    删除集合中的所有文档

    删除集合中的所有文档,请把空的查询对象传递给 delete_many() 方法

     
    import pymongo
    
    connect= pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["mydatabase"]
    mycol = test_db["customers"]
    
    x = mycol.delete_many({})
    
    print(x.deleted_count, " documents deleted.")

    查找文档

    查找单条文档

    我们可以使用 find_one() 方法,find_one() 方法返回选择中的第一个匹配项。

     
    import pymongo
    
    connect= pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["mydatabase"]
    mycol = test_db["customers"]
    
    x = mycol.find_one()
    
    print(x)
     

    查找全部

    如需从 MongoDB 中的表中选取数据,我们还可以使用 find() 方法。

    find() 方法返回选择中的所有匹配项。

    find() 方法的第一个参数是 query 对象。在这个例子中,我们用了一个空的 query 对象,它会选取集合中的所有文档。

    find() 方法的第二个参数是描述包含在结果中字段的对象。此参数是可选的,如果省略,则所有字段都将包含在结果中。

     
    import pymongo
    
    connect= pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["mydatabase"]
    mycol = test_db["customers"]
    
    for x in mycol.find():
      print(x)
     

    返回部分字段

    使用find时,第二个参数字典中,需要返回的字段设置为1,不需要返回的字段为0。

     
    import pymongo
    
    connect= pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["mydatabase"]
    mycol = test_db["customers"]
    
    for x in mycol.find({},{ "_id": 0, "name": 1, "address": 1 }):
      print(x)
     

    查找多条数据

     
    from pymongo import MongoClient
    from datetime import datetime
    connect = MongoClient(host='localhost', port=27017, username="root", password="123456",)
    # 获取db
    test_db = connect['test']
    # 获取collection
    collection = test_db['students']
    documents = [{"author": "Mike","text": "Another post!","tags": ["bulk", "insert"], "date": datetime(2009, 11, 12, 11, 14)},
    {"author": "Eliot", "title": "MongoDB is fun", "text": "and pretty easy too!", "date": datetime(2009, 11, 10, 10, 45)}]
    collection.insert_many(documents=documents)
    
    # 通过条件过滤出多条document
    documents = collection.find({"author": "Mike"})
     

    计数

    如果我们只想知道有多少文档与某个查询匹配,我们可以执行count_documents()操作而不是完整查询。

    我们以上一个程序为例,可以对集合中的所有文档进行计数:

    collection.count_documents({})  #返回结果:2

    或仅与特定查询匹配的那些文档:

    collection.count_documents({"author": "Mike"})  #返回结果:1

    Query查询

    待续

    结果排序

    sort() 方法按升序或降序对结果进行排序。

    sort() 方法为 "fieldname"(字段名称)提供一个参数,为 "direction"(方向)提供一个参数(升序是默认方向)

    按姓名的字母顺序对结果进行排序:

     
    import pymongo
    
    connect= pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["mydatabase"]
    mycol = test_db["customers"]
    
    mydoc = mycol.find().sort("name")
    
    for x in mydoc:
      print(x)
     

    那么如何做降序排序?

    使用值 -1 作为第二个参数进行降序排序。

    sort("name", 1) # 升序
    sort("name", -1) # 降序

    按名称的逆向字母顺序对结果进行排序:

     
    import pymongo
    
    connect= pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["mydatabase"]
    mycol = test_db["customers"]
    
    mydoc = mycol.find().sort("name", -1)
    
    for x in mydoc:
      print(x)
     

    返回结果限制

    限制 MongoDB 中的结果,我们使用 limit() 方法。

    limit() 方法接受一个参数,定义的数字表示返回的文档数。

    把结果限定为只返回 5 个文档:

     
    import pymongo
    
    connect= pymongo.MongoClient("mongodb://localhost:27017/")
    test_db= connect["mydatabase"]
    mycol = test_db["customers"]
    
    myresult = mycol.find().limit(5)
    
    # 打印结果:
    for x in myresult:
      print(x)
     

    在多进程中使用

    绝不能将MongoClient实例从父进程复制到子进程。相反,父进程和每个子进程必须创建自己的MongoClient实例。例如:

     
    # Each process creates its own instance of MongoClient.
    def func():
        db = pymongo.MongoClient().mydb
        # Do something with db.
    
    proc = multiprocessing.Process(target=func)
    proc.start()
     

    永远不要这样做:

     
    client = pymongo.MongoClient()
    
    # Each child process attempts to copy a global MongoClient
    # created in the parent process. Never do this.
    def func():
      db = client.mydb
      # Do something with db.
    
    proc = multiprocessing.Process(target=func)
    proc.start()
     

    由于fork(),线程和锁之间固有的不兼容性,从父进程复制的MongoClient实例在子进程中极有可能出现死锁 如果有可能发生这种死锁,PyMongo将尝试发出警告。

  • 相关阅读:
    POJ 2774 Long Long Message
    Jmeter学习——5
    Jmeter学习——4
    Jmeter学习——10
    Jmeter学习——9
    使用 JMeter 完成常用的压力测试 [转]
    Jmeter学习——3
    Jmeter学习——7
    Jmeter学习——11
    Jmeter学习——8
  • 原文地址:https://www.cnblogs.com/xiao-xue-di/p/14189727.html
Copyright © 2020-2023  润新知