批量查询数据库中符合条件的文档,并把每个文档转换为相应的类实例后返回一个列表
示例代码:
def bulk_find(cls: Type[T], **filter_options) -> list[T]:
collection = _database[cls.get_collection_name()]
try:
instances = collection.find(filter_options)
return [document for instance in instances if (document := cls.from_mongo(instance)) is not None]
except errors.OperationFailure:
logger.error("Failed to retrieve documents")
return []
批量查询数据库中符合条件的文档,并把每个文档转换为相应的类实例后返回一个列表。如果在查询或转换过程中出现错误,则会记录错误并返回一个空列表。下面解释代码:
1. 获取数据库集合
collection = _database[cls.get_collection_name()]
- 解释:
- 首先调用
cls.get_collection_name()
获取当前类对应的集合名称。例如,如果当前类是UserDocument
,那么可能返回"users"
。 - 然后通过
_database[集合名称]
得到该集合对象,这个对象用来执行查询操作。
- 首先调用
举例:
假设 cls.get_collection_name()
返回 "users"
,那么这行代码就相当于:
collection = _database["users"]
2. 查询符合条件的文档
instances = collection.find(filter_options)
- 解释:
- 使用
collection.find(filter_options)
根据传入的过滤条件(filter_options
)查找所有匹配的文档。 filter_options
是一个字典,里面可以包含任何查询条件。例如:{"age": 30}
表示查找年龄为 30 的文档。- 查询结果
instances
是一个迭代器,包含所有符合条件的数据库文档(通常以字典形式表示)。
- 使用
举例:
假设数据库中 "users"
集合有以下文档:
- 文档 1:
{"_id": "uuid-001", "name": "Alice", "age": 30}
- 文档 2:
{"_id": "uuid-002", "name": "Bob", "age": 25}
- 文档 3:
{"_id": "uuid-003", "name": "Charlie", "age": 30}
如果传入过滤条件为 {"age": 30}
,则 collection.find({"age": 30})
会返回文档 1 和文档 3。
3. 转换文档并生成返回列表
return [document for instance in instances if (document := cls.from_mongo(instance)) is not None]
- 解释:
- 这里使用列表推导式遍历每一个查询结果
instance
。 - 对于每个
instance
,调用cls.from_mongo(instance)
方法将数据库中的字典转换为类实例(例如,将字典转换为UserDocument
对象)。 - 使用“海象运算符”
:=
同时进行赋值和判断。如果转换后的结果document
不是None
,则将它加入到最终返回的列表中。 - 这样可以保证只有转换成功的文档才会出现在返回结果中。
- 这里使用列表推导式遍历每一个查询结果
举例:
假设转换方法 from_mongo
能正常转换文档 1 和文档 3:
- 对文档 1:
cls.from_mongo({"_id": "uuid-001", "name": "Alice", "age": 30})
返回实例User_Alice
- 对文档 3:
cls.from_mongo({"_id": "uuid-003", "name": "Charlie", "age": 30})
返回实例User_Charlie
那么列表推导式最终返回的列表就是:
[User_Alice, User_Charlie]
如果某个文档转换失败(即 from_mongo
返回 None
),则该文档不会被加入到结果列表中。
4. 异常处理
except errors.OperationFailure:
logger.error("Failed to retrieve documents")
return []
- 解释:
- 如果在查询数据库过程中(例如执行
collection.find(filter_options)
)遇到OperationFailure
异常(可能由于查询条件不正确或数据库问题),代码会进入except
块。 - 这里记录一条错误日志
"Failed to retrieve documents"
,并返回一个空列表[]
,避免程序崩溃。
- 如果在查询数据库过程中(例如执行
数值详细举例
假设数据库 "users"
集合中有以下三条记录:
{"_id": "uuid-001", "name": "Alice", "age": 30}
{"_id": "uuid-002", "name": "Bob", "age": 25}
{"_id": "uuid-003", "name": "Charlie", "age": 30}
当调用 bulk_find
时,如果传入过滤条件为 {"age": 30}
,则:
collection.find({"age": 30})
会返回文档 1 和文档 3。- 假设
cls.from_mongo
分别能将这两个文档转换为实例User_Alice
和User_Charlie
(转换成功),则最终返回列表为:[User_Alice, User_Charlie]
- 如果在转换过程中,比如文档 3 的数据格式有问题导致
cls.from_mongo
返回None
,那么最终返回列表只包含User_Alice
。
如果查询时发生数据库错误(比如连接超时),则会捕获异常,记录错误日志,并返回空列表 []
。
总结
-
bulk_find 方法的功能:
它根据传入的过滤条件批量查询数据库中的文档,并通过from_mongo
方法将每个文档转换为对应的类实例。只有转换成功的实例会被加入到返回的列表中。 -
通俗解释:
就好比你到图书馆(数据库)里找符合特定条件(比如出版年份为2020)的书(文档),查找到书以后你还需要把这些书装订成一本新书(转换为类实例)。如果转换过程中有书籍内容有问题(转换返回None
),就不把这本书放入新书中。如果整个查询过程出错,就返回一个空的书架(空列表)。