Pyt*_*ast 5 python mongodb mongoengine mongodb-query
我有2个DynamicDocuments:
class Tasks(db.DynamicDocument):
task_id = db.UUIDField(primary_key=True,default=uuid.uuid4)
name = db.StringField()
flag = db.IntField()
class UserTasks(db.DynamicDocument):
user_id = db.ReferenceField('User')
tasks = db.ListField(db.ReferenceField('Tasks'),default=list)
Run Code Online (Sandbox Code Playgroud)
我想UserTasks通过检查flag给定task_id 的值(来自Tasks Document)是否为0或者1给定task_id和user_id 来过滤文档.所以我用以下方式查询: -
obj = UserTasks.objects.get(user_id=user_id,tasks=task_id)
Run Code Online (Sandbox Code Playgroud)
这会抓住我一个UserTask对象.
现在我循环遍历任务列表,首先我获得等效任务,然后按以下方式检查其标志值.
task_list = obj.tasks
for t in task_list:
if t['task_id'] == task_id:
print t['flag']
Run Code Online (Sandbox Code Playgroud)
是否有更好/直接的方式查询UserTasksDocument以获取Tasks Document的标志值.
PS:我可以从TasksDocument 直接获取标志值,但我还需要检查任务是否与用户相关联.因此我直接查询了该USerTasks文件.
ReferenceField\'s我们可以直接使用单个查询中的字段来过滤文档吗?
不,不可能直接使用 字段过滤文档,ReferenceField因为这样做需要联接,而 mongodb 不支持联接。
\n\n\nMongoDB 不支持联接。在 MongoDB 中,一些数据被非规范化,或者与相关数据一起存储在文档中,以消除连接的需要。
\n
从官方网站的另一个页面:
\n\n\n\n\n如果我们使用关系数据库,我们可以对用户和商店执行联接,并在单个查询中获取所有对象。但是 MongoDB 不支持连接,因此有时需要一些非规范化。
\n\n关系纯粹主义者可能已经感到不安了,就好像我们违反了某些普遍法则。但让\xe2\x80\x99s记住,MongoDB\n集合并不等同于关系表;每一个都服务于独特的设计目标。规范化表提供原子、独立的数据块。然而,文档更接近地表示一个对象作为一个整体。
\n
因此,在 1 个查询中,我们不能同时tasks使用特定标志值和模型上给定的user_id和进行过滤。task_idUserTasks
那么如何进行过滤呢?
\n\n为了根据所需条件执行过滤,我们需要执行 2 个查询。
\n\n在第一个查询中,我们将尝试使用Tasks给定的task_id和来过滤模型flag。然后,在第二个查询中,我们将UserTasks使用给定的user_id和task从第一个查询中检索到的模型来过滤模型。
例子:
\n\n假设我们有一个user_id,task_id我们需要检查相关任务的flag值是否为0。
第一个查询
\n\n我们将首先使用my_task给定的task_id和flagas 检索0。
my_task = Tasks.objects.get(task_id=task_id, flag=0) # 1st query\nRun Code Online (Sandbox Code Playgroud)\n\n第二次查询
\n\nUserTask然后在第二个查询中,您需要使用给定的模型user_id和对象来过滤模型my_task。
my_user_task = UserTasks.objects.get(user_id=user_id, tasks=my_task) # 2nd query\nRun Code Online (Sandbox Code Playgroud)\n\n仅当您获得my_task具有给定task_id和的对象时才应执行第二个查询flag,才应执行第二个查询。此外,您还需要添加错误处理,以防没有匹配的对象。
如果我们已经使用了怎么EmbeddedDocument办Tasks呢?
假设我们已将Tasks文档定义为 anEmbeddedDocument并将模型tasks中的字段定义UserTasks为 anEmbeddedDocumentField,那么为了进行所需的过滤,我们可以执行如下操作:
my_user_task = UserTasks.objects.get(user_id=user_id, tasks__task_id=task_id, tasks__flag=0)\nRun Code Online (Sandbox Code Playgroud)\n\n获取特定的my_task从任务列表中
上面的查询将返回一个UserTask文档,其中包含所有tasks. 然后我们需要执行某种迭代以获得所需的任务。
为此,我们可以使用以下命令执行列表理解enumerate()。\n那么所需的索引将是返回的 1 元素列表的第一个元素。
my_task_index = [i for i,v in enumerate(my_user_task.tasks) if v.flag==0][0]\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1033 次 |
| 最近记录: |