Possiamo filtrare direttamente un documento con ReferenceField's
campi in una singola query?
No, non è possibile filtrare direttamente un documento con i campi di ReferenceField poiché ciò richiederebbe join e mongodb non supporta i join.
Secondo i documenti MongoDB su riferimenti al database:
Da un'altra pagina sul sito ufficiale:
Quindi in 1 query, non possiamo entrambi filtrare tasks con un particolare valore di flag e con il dato user_id e task_id su UserTasks modello.
Come eseguire il filtraggio, allora?
Per eseguire il filtraggio secondo le condizioni richieste, dovremo eseguire 2 query.
Nella prima query cercheremo di filtrare le Tasks modello con il dato task_id e flag . Quindi, nella seconda query, filtreremo UserTasks modello con il dato user_id e l'tasks recuperato dalla prima query.
Esempio:
Diciamo che abbiamo un user_id , task_id e dobbiamo verificare se l'attività correlata ha flag valore come 0 .
1a richiesta
Per prima cosa recupereremo my_task con il dato task_id e flag come 0 .
my_task = Tasks.objects.get(task_id=task_id, flag=0) # 1st query
2a richiesta
Quindi nella seconda query, devi filtrare su UserTask modello con il dato user_id e my_task oggetto.
my_user_task = UserTasks.objects.get(user_id=user_id, tasks=my_task) # 2nd query
Dovresti eseguire la seconda query solo se ottieni un my_task oggetto con il dato task_id e flag valore. Inoltre, dovrai aggiungere la gestione degli errori nel caso non ci siano oggetti corrispondenti.
E se avessimo utilizzato EmbeddedDocument per le Tasks modello?
Diciamo che abbiamo definito le nostre Tasks documento come EmbeddedDocument e le tasks campo in UserTasks modello come EmbeddedDocumentField , quindi per eseguire il filtraggio desiderato avremmo potuto fare qualcosa come di seguito:
my_user_task = UserTasks.objects.get(user_id=user_id, tasks__task_id=task_id, tasks__flag=0)
Ottenere il particolare my_task dall'elenco delle attività
La query precedente restituirà un UserTask documento che conterrà tutte le tasks . Dovremo quindi eseguire una sorta di iterazione per ottenere l'attività desiderata.
Per fare ciò, possiamo eseguire la comprensione dell'elenco usando enumerate() .Quindi l'indice desiderato sarà il primo elemento dell'elenco di 1 elemento restituito.
my_task_index = [i for i,v in enumerate(my_user_task.tasks) if v.flag==0][0]