mongodb学习经验
0、ObjectId 不能直接return前端,需要2次包裹
一、repl包裹 二、dict包裹 return {'msg': repr(docs)} return {'code': 1, 'msg': '查询成功', 'data': {'auth_list': repr(result)}}
聚合($group $match)
cursor = await db.running.aggregate([
{"$match": {"company_id": {'$in': [3, 1]}}},
{"$group": {"_id": "$company_id", 'locks': {'$addToSet': '$lock_id'}}},
]).to_list(length=None)
users = await db.user.find({'role_id': {'$in': [1, 2]}}).sort('mobile', -1).skip(1).limit(8).to_list(length=None)
计数
total = coll.count_documents({'name': 'zhangsan'})
total = await db.test.count_documents({'$and': [{'i': {'$gt': 6000000}}, {'i': {'$lt': 6508000}}]})
查询条件
match = {"company_id": {'$in': [3, 1]}} # 查符合条件的
match = {} # 查全部
1、ObjectId与String相互转换
ObjectId类型 —→ String类型 这个非常简单,直接强制类型转换就可以了 _id = str(ObjectId('类型')) String类型 —→ ObjectId类型 from bson.objectid import ObjectId _id = ObjectId("字符串")
2、连接数据库
# 一、AsyncIOMotorClient 异步 DB_CLIENT = AsyncIOMotorClient('127.0.0.1', 27017) db = DB_CLIENT['xy'] # 库名称 # 二、pymongo 同步 server = "mongodb://127.0.0.1:27017" conn = pymongo.MongoClient(server) db1 = conn["xy"] xyuser = db1.get_collection('xyuser')
3、常用
一、ObjectId返回前端后,可以传参过来直接在_id字段使用 async def mongodb(oid: str, request: Request): oid = ObjectId('632bd220c66f6b200868ed6c') cursor = db.user.find({'_id': {'$eq': oid}}) # 返回cursor docs = await cursor.to_list(None) # 注意cursor的处理 print(str(docs[0].get('_id'))) 二、插入多个值,返回_id列表 docs = await Userorg.all().values() print(docs) insert_many = await db.userorg.insert_many(docs) print(insert_many.inserted_ids) return {'msg': repr(len(insert_many.inserted_ids))} 三、插入和返回多个值 result = await db.test.insert_many( [{'i': i} for i in range(200000)]) async for document in db.xyuser.find(): print(document) print('inserted %d docs' % (len(result.inserted_ids),))
四、find() cursor
cursor = db.test_collection.find({'i': {'$lt': 4}})
cursor.sort('i', -1).skip(1).limit(2) # Modify the query before iterating
docs = await cursor.to_list(None) # 注意cursor的处理
async for document in cursor:
print(document)
4、增删查改
增 document = {'key': 'value'} result = await db.test_collection.insert_one(document) print('result %s' % repr(result.inserted_id)) result = await db.test_collection.insert_many( [{'i': i} for i in range(2000)]) print('inserted %d docs' % (len(result.inserted_ids),)) 删 n = await coll.count_documents({}) print('%s documents before calling delete_one()' % n) result = await db.test_collection.delete_one({'i': {'$gte': 1000}}) print('%s documents after' % (await coll.count_documents({}))) 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({}))) 查 document = await coll.find_one({'i': 51}) cursor = db.test_collection.find({'i': {'$lt': 4}}) # Modify the query before iterating cursor.sort('i', -1).skip(1).limit(2) docs=await cursor.to_list(length=100) async for document in cursor: pprint.pprint(document) 改 result = await coll.update_one({'i': 51}, {'$set': {'key': 'value'}}) print(result.modified_count) await coll.update_many({'i': {'$gt': 100}}, {'$set': {'key': 'value'}}) print(result.modified_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)
5、querying
cursor = db.test_collection.find({'i': {'$lt': 5}}).sort('i') for document in await cursor.to_list(length=100): pprint.pprint(document) c = db.test_collection async for document in c.find({'i': {'$lt': 2}}): pprint.pprint(document) cursor = db.test_collection.find({'i': {'$lt': 4}}) # Modify the query before iterating cursor.sort('i', -1).skip(1).limit(2) async for document in cursor: pprint.pprint(document)
6、事务
操作 # Use "await" for start_session, but not for start_transaction. async with await client.start_session() as s: async with s.start_transaction(): await collection.delete_one({'x': 1}, session=s) await collection.insert_one({'x': 2}, session=s) 示例 async def coro(session): orders = session.client.db.orders inventory = session.client.db.inventory inserted_id = await orders.insert_one( {"sku": "abc123", "qty": 100}, session=session) await inventory.update_one( {"sku": "abc123", "qty": {"$gte": 100}}, {"$inc": {"qty": -100}}, session=session) return inserted_id async with await client.start_session() as session: inserted_id = await session.with_transaction(coro)
7、增删查改 返回result:(https://pymongo.readthedocs.io/en/stable/api/pymongo/results.html)
class pymongo.results.InsertManyResult(inserted_ids: List[Any], acknowledged: bool) property acknowledged: bool property inserted_ids: List class pymongo.results.InsertOneResult(inserted_id: Any, acknowledged: bool) property acknowledged: bool property inserted_id: Any #The inserted document’s _id. class pymongo.results.UpdateResult(raw_result: Dict[str, Any], acknowledged: bool) #The return type for update_one(), update_many(), and replace_one(). property acknowledged: bool property matched_count: int # The number of documents matched for this update. property modified_count: int #The number of documents modified. property raw_result: Dict[str, Any] #The raw result document returned by the server. property upserted_id: Any #The _id of the inserted document if an upsert took place. Otherwise None.
8、log写入数据库(https://blog.csdn.net/wangteng13/article/details/122110701)
9、内嵌数组分页
内嵌数组数据 { "_id" : ObjectId("5aa877e4aa25752ab4d4cae3"), "Records" : [ { "Data" : 1962163552.0, "RecorDateTime" : ISODate("2018-03-16T10:01:14.931Z") }, { "Data" : 1111405346.0, "RecorDateTime" : ISODate("2018-03-16T08:53:14.931Z") }, ...... ] } 分页代码 aggregate( [ {"$match" : { "_id" : ObjectId("5aa877e4aa25752ab4d4cae3") } }, { "$unwind" : "$Records" }, { "$project" : { "Records" : "$Records", "_id" : 0 } }, { "$sort" : { "Records.RecorDateTime" : 1 } }, { "$skip" : 30 }, { "$limit" : 10 } ]);
{ _id: 4, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 5 }, { grade: 90, mean: 85, std: 3 } ] } db.students.update( { _id: 4, "grades.grade": 85 }, { $set: { "grades.$.std" : 6 } } ) db.students.update( { _id: 4, grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } } }, { $set: { "grades.$.std" : 6 } } )
{
name:"scy",
mArray:[{age:13,weight:50},{age:13,weight:30}]
}
User.update({name:"scy"},{$pull:{"mArray":{"weight":30}}});//删除所有weight属性值为30的对象
db.user.update({'_id': user_id},{$pull:{"company":{"oid": company_id}}}) # 从用户资料中删除内嵌公司id
本方式可用**************************************************
查询内嵌数组
match = {'_id': ObjectId('6331746228d5a457ed763f78')}
users = await db.coltd.find_one(match, {'employee': {'$elemMatch': {"id": "997454981"}}})
修改内嵌数组
match = {'_id': ObjectId('63310eb84fccc40e5f2058f9'), 'company.id': "21807313636737386"}
user = {"company.$.name": '中华人民共和国', "company.$.dept": '中华人民共和国中华人民共和d 国中华人民共和国'}
update = await db.test.update_one(match, {'$set': user})
本方式可用**************************************************
user = {"company.nickname": i.nickname, "company.dept": i.dept}
update = await db.user.aggregate(
{"$match": {'_id': i.user_id}},
{"$unwind": "$company"},
{"$match": {'company.oid': ObjectId(company_id)}},
{'$set': user} # 从用户资料中修改内嵌公司相关资料
)
10、中间件、执行时间计算、随机数生成二维数组
中间件
@app.middleware("http") async def add_process_time_header(request: Request, call_next): start_time = time.time() response = await call_next(request) process_time = time.time() - start_time response.headers["X-Process-Time"] = str(process_time) print(repr(response.__repr__())) return response
执行时间计算、随机数生成二维数组 start_time = time.time() array = [] for i in range(200000): row = [] for j in range(100): company = {'id': str(random.randint(10000, 3000000000)), 'name': str(random.randint(10000, 3000000000)), 'dept': str(random.randint(10000, 3000000000))} row.append(company) item = {'i': i, 'company': row} array.append(item) crate_time = time.time() - start_time print(str(crate_time)) result = await db.test.insert_many(array, ordered=False) print('inserted %d docs' % (len(result.inserted_ids),)) insert_time = time.time() - start_time print(str(insert_time))
11、聚合代码(可用)
本方式可用**************************************************
1、查询内嵌数组并展开后输出多条数据
start_time = time.time() companys = await db.test.aggregate([ {'$match': {'_id': ObjectId('6331038c29964c0e72facb1d')}}, {"$unwind": "$company"}, {'$skip': 8}, {'$limit': 8}, {'$project': {'_id': 0, 'company.id': 1}} ]).to_list(length=None) crate_time = time.time() - start_time print(str(crate_time)) print(companys)
2、查询内嵌数组中单条数据
match = {'_id': ObjectId('6331746228d5a457ed763f78')}
users = await db.coltd.find_one(match, {'employee': {'$elemMatch': {"id": "997454981"}}})
3、修改内嵌数组
match = {'_id': ObjectId('63310eb84fccc40e5f2058f9'), 'company.id': "21807313636737386"}
user = {"company.$.name": '中华人民共和国', "company.$.dept": '中华人民共和国中华人民共和d 国中华人民共和国'}
update = await db.test.update_one(match, {'$set': user})
本方式可用**************************************************
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix