Podemos filtrar diretamente um documento com o
ReferenceField's
campos em uma única consulta? Não, não é possível filtrar diretamente um documento com os campos de
ReferenceField
pois isso exigiria junções e o mongodb não suporta junções. De acordo com os documentos do MongoDB em referências de banco de dados:
De outra página no site oficial:
Portanto, em 1 consulta, não podemos filtrar
tasks
com um valor de sinalizador específico e com o user_id
fornecido e task_id
nas UserTasks
modelo. Como fazer a filtragem então?
Para realizar a filtragem de acordo com as condições exigidas, precisamos realizar 2 consultas.
Na primeira consulta tentaremos filtrar as
Tasks
model com o task_id
fornecido e flag
. Então, na 2ª consulta, filtraremos UserTasks
model com o user_id
fornecido e a task
recuperado da primeira consulta. Exemplo:
Digamos que temos um
user_id
, task_id
e precisamos verificar se a tarefa relacionada tem flag
valor como 0
. 1ª consulta
Primeiro vamos recuperar o
my_task
com o task_id
fornecido e flag
como 0
. my_task = Tasks.objects.get(task_id=task_id, flag=0) # 1st query
2ª consulta
Então, na segunda consulta, você precisa filtrar em
UserTask
model com o user_id
fornecido e my_task
objeto. my_user_task = UserTasks.objects.get(user_id=user_id, tasks=my_task) # 2nd query
Você deve realizar a segunda consulta somente se receber um
my_task
objeto com o task_id
fornecido e flag
valor. Além disso, você precisará adicionar tratamento de erros caso não haja objetos correspondentes. E se tivermos usado
EmbeddedDocument
para as Tasks
modelo? Digamos que definimos nossas
Tasks
documento como um EmbeddedDocument
e as tasks
campo em UserTasks
model como um EmbeddedDocumentField
, então para fazer a filtragem desejada poderíamos ter feito algo como abaixo:my_user_task = UserTasks.objects.get(user_id=user_id, tasks__task_id=task_id, tasks__flag=0)
Obter a
my_task
específica da lista de tarefas A consulta acima retornará um
UserTask
documento que conterá todas as tasks
. Em seguida, precisaremos realizar algum tipo de iteração para obter a tarefa desejada. Para fazer isso, podemos realizar a compreensão da lista usando
enumerate()
.Então o índice desejado será o 1º elemento da lista de 1 elemento retornada. my_task_index = [i for i,v in enumerate(my_user_task.tasks) if v.flag==0][0]