python3 -m pip install motor
import motor.motor_asyncio client = motor.motor_asyncio.AsyncIOMotorClient('localhost', 27017)
motor.motor_asyncio.AsyncIOMotorClient('mongodb://root:123456@localhost:27017')
MongoDB的单个实例能够支持多个独立的数据库。在开放式客户端中,您可使用点表示法或括号表示法来获取对特定数据库的引用:python
db = client.test_database db = client['test_database']
建立对数据库的引用不会执行I / O,也不须要 await 表达式。mongodb
一个集合是一组存储在MongoDB中的文档,而且能够被认为是大体在关系数据库中的表的当量。获取Motor中的集合与获取数据库的工做方式相同:数据库
collection = db.test_collection collection = db['test_collection']
就像获取对数据库的引用同样,获取对集合的引用不会产生I / O而且不须要 await 表达式。服务器
与pymongo同样,Motor使用Python字典表示MongoDB文档。要存储在MongoDB中的文档,在 await 表达式中调用 insert_one() :异步
async def do_insert(): document = {'key': 'value'} result = await db.test_collection.insert_one(document) # insert_one只能插入一条数据 print('result %s' % repr(result.inserted_id)) loop = asyncio.get_event_loop() loop.run_until_complete(do_insert()) # result ObjectId('...')
async def do_insert(): result = await db.test_collection.insert_many( [{'i': i} for i in range(2000)]) # insert_many能够插入一条或多条数据,可是必须以列表(list)的形式组织数据 print('inserted %d docs' % (len(result.inserted_ids),)) loop = asyncio.get_event_loop() loop.run_until_complete(do_insert()) # inserted 2000 docs
使用 find_one() 获得匹配查询的第一个文档。例如,要获取密钥“i”的值小于1的文档:async
async def do_find_one(): document = await db.test_collection.find_one({'i': {'$lt': 1}}) # find_one只能查询一条数据 pprint.pprint(document) loop = asyncio.get_event_loop() loop.run_until_complete(do_find_one()) # {'_id': ObjectId('...'), 'i': 0}
注意:结果是一个字典匹配咱们以前插入的字典。oop
使用 find() 要查询的一组文档。 find() 没有I / O,也不须要 await 表达式。它只是建立一个 AsyncIOMotorCursor 实例。当您调用 to_list() 或为循环执行异步时 (async for) ,查询其实是在服务器上执行的。post
查询 “ i ” 小于5的全部文档:code
async def do_find(): cursor = db.test_collection.find({'i': {'$lt': 5}}).sort('i') for document in await cursor.to_list(length=100): pprint.pprint(document) loop = asyncio.get_event_loop() loop.run_until_complete(do_find()) # {'_id': ObjectId('...'), 'i': 0} # {'_id': ObjectId('...'), 'i': 1} # {'_id': ObjectId('...'), 'i': 2} # {'_id': ObjectId('...'), 'i': 3} # {'_id': ObjectId('...'), 'i': 4}
一length ,调用方法 to_list 的必传参数,防止 Motor 从缓冲中获取的文档数量不受限制,此处限制为100。orm
您能够在循环中一次处理一个文档:async for
async def do_find(): c = db.test_collection async for document in c.find({}): # 查询全部文档 pprint.pprint(document) loop = asyncio.get_event_loop() loop.run_until_complete(do_find()) # {'_id': ObjectId('...'), 'i': 0} # {'_id': ObjectId('...'), 'i': 1}
您能够在开始迭代以前对查询应用排序,跳过或限制:
async def do_find(): cursor = db.test_collection.find({'i': {'$lt': 4}}) # Modify the query before iterating cursor.sort('i', -1).skip(1).limit(2) # 对查询应用排序(sort),跳过(skip)或限制(limit) async for document in cursor: pprint.pprint(document) loop = asyncio.get_event_loop() loop.run_until_complete(do_find()) # {'_id': ObjectId('...'), 'i': 2} # {'_id': ObjectId('...'), 'i': 1}
游标 (cursor) 实际上并非单独从服务器检索每一个文档; 它能够大批量地获取文档。
async def do_count(): n = await db.test_collection.count_documents({}) # 查询集合内全部文档数量 print('%s documents in collection' % n) n = await db.test_collection.count_documents({'i': {'$gt': 1000}}) # 按条件查询集合内文档数量 print('%s documents where i > 1000' % n) loop = asyncio.get_event_loop() loop.run_until_complete(do_count()) # 2000 documents in collection # 999 documents where i > 1000
replace_one() 更改文档。它须要两个参数:一个指定要替换哪一个文档的查询和一个替换文档。该查询遵循与 find() 或 相同的语法 find_one() 。替换一个文档的示例:
async def do_replace(): coll = db.test_collection old_document = await coll.find_one({'i': 50}) print('found document: %s' % pprint.pformat(old_document)) _id = old_document['_id'] old_document['i'] = -1 # 修改文档(dict)的key, value old_document['new'] = 'new' # 增长文档(dict)的key, value del old_document['i'] # 删除文档(dict)的key, value result = await coll.replace_one( {'_id': _id}, old_document) # replace_one第一个参数为查询条件, 第二个参数为更新后的文档 print('replaced %s document' % result.modified_count) new_document = await coll.find_one({'_id': _id}) print('document is now %s' % pprint.pformat(new_document)) loop = asyncio.get_event_loop() loop.run_until_complete(do_replace()) # found document: {'_id': ObjectId('...'), 'i': 50} # replaced 1 document # document is now {'_id': ObjectId('...'), 'key': 'value'}
除了 _id 不变,replace_one() 会对修改后文档的全部字段作更新操做, 慎用 。
update_one() 与MongoDB的修饰符运算符一块儿使用来更新文档的一部分并保持其他部分不变。咱们将找到“i”为51的文档,并使用 $set 运算符将“key”设置为“value”:
async def do_update(): coll = db.test_collection result = await coll.update_one({'i': 51}, {'$set': {'key': 'value'}}) # 仅新增或更改该文档的某个key print('updated %s document' % result.modified_count) new_document = await coll.find_one({'i': 51}) print('document is now %s' % pprint.pformat(new_document)) loop = asyncio.get_event_loop() loop.run_until_complete(do_update()) # updated 1 document # document is now {'_id': ObjectId('...'), 'i': 51, 'key': 'value'}
“key”设置为“value”,“i”仍为51。
update_one() 只影响它找到的第一个文档,您可使用 update_many() 更新全部文档:
await coll.update_many({'i': {'$gt': 100}}, {'$set': {'key': 'value'}})
delete_many() 采用与语法相同的 find() 查询。delete_many() 当即删除全部匹配的文档。
async def do_delete_many(): coll = db.test_collection n = await coll.count_documents({}) print('%s documents before calling delete_many()' % n) result = await db.test_collection.delete_many({'i': {'$gte': 1000}}) print('%s documents after' % (await coll.count_documents({}))) loop = asyncio.get_event_loop() loop.run_until_complete(do_delete_many()) # 2000 documents before calling delete_many() # 1000 documents after