我们可以直接过滤文档吗ReferenceField's http://docs.mongoengine.org/en/latest/apireference.html#mongoengine.fields.ReferenceField单个查询中的字段?
No,不可能直接使用以下字段过滤文档ReferenceField
因为这样做需要联接,而 mongodb 不支持联接。
根据 MongoDB 文档数据库参考: http://docs.mongodb.org/manual/reference/database-references/
MongoDB 不支持联接。在 MongoDB 中,一些数据是非规范化的,
或者与文档中的相关数据一起存储,以消除连接的需要。
来自另一个page http://docs.mongodb.org/ecosystem/tutorial/model-data-for-ruby-on-rails/在官方网站上:
如果我们使用关系数据库,我们可以执行连接
用户和商店,并在单个查询中获取所有对象。但
MongoDB 不支持连接,因此有时需要一些
非规范化。
关系纯粹主义者可能已经感到不安了,就好像我们是
违反某些普遍法则。但我们要记住,MongoDB
集合不等同于关系表;每个服务一个
独特的设计目标。规范化表提供了原子、
孤立的数据块。然而,一份文件更能代表
一个物体作为一个整体。
所以在 1 个查询中,我们不能同时过滤tasks
具有特定的标志值和给定的user_id
and task_id
on the UserTasks
model.
那么如何进行过滤呢?
要根据所需条件执行过滤,我们需要执行 2 个查询。
在第一个查询中,我们将尝试过滤Tasks
模型与给定的task_id
and flag
。然后,在第二个查询中,我们将过滤UserTasks
模型与给定的user_id
和task
从第一个查询中检索。
Example:
假设我们有一个user_id
, task_id
我们需要检查相关任务是否有flag
价值为0
.
第一个查询
我们首先会检索my_task
与给定的task_id
and flag
as 0
.
my_task = Tasks.objects.get(task_id=task_id, flag=0) # 1st query
第二次查询
然后在第二个查询中,您需要过滤UserTask
模型与给定的user_id
and my_task
object.
my_user_task = UserTasks.objects.get(user_id=user_id, tasks=my_task) # 2nd query
仅当您得到一个时才应该执行第二个查询my_task
具有给定对象task_id
and flag
价值。此外,您还需要添加错误处理,以防没有匹配的对象。
如果我们使用过怎么办EmbeddedDocument
为了Tasks
model?
假设我们已经定义了我们的Tasks
文档作为EmbeddedDocument
和tasks
领域在UserTasks
模型作为EmbeddedDocumentField
,然后为了进行所需的过滤,我们可以执行如下操作:
my_user_task = UserTasks.objects.get(user_id=user_id, tasks__task_id=task_id, tasks__flag=0)
获取特定的my_task
从任务列表中
上面的查询将返回一个UserTask
文件将包含所有tasks
。然后我们需要执行某种迭代以获得所需的任务。
为此,我们可以使用以下命令执行列表理解enumerate()
。
那么所需的索引将是返回的 1 元素列表的第一个元素。
my_task_index = [i for i,v in enumerate(my_user_task.tasks) if v.flag==0][0]