MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Query sui documenti incorporati Mongo

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]