Czy możemy bezpośrednio filtrować dokument za pomocą ReferenceField's
pola w jednym zapytaniu?
Nie, nie jest możliwe bezpośrednie filtrowanie dokumentu z polami ReferenceField's ponieważ wymagałoby to złączeń, a mongodb nie obsługuje złączeń.
Zgodnie z dokumentacją MongoDB na odniesienia do baz danych:
Z innej strony na oficjalnej stronie:
Tak więc w jednym zapytaniu nie możemy jednocześnie filtrować tasks z określoną wartością flagi i podanym user_id i task_id w UserTasks model.
Jak w takim razie przeprowadzić filtrowanie?
Aby przeprowadzić filtrowanie zgodnie z wymaganymi warunkami, musimy wykonać 2 zapytania.
W pierwszym zapytaniu spróbujemy przefiltrować Tasks model z podanym task_id i flag . Następnie w drugim zapytaniu przefiltrujemy UserTasks model z podanym user_id i task pobrane z pierwszego zapytania.
Przykład:
Powiedzmy, że mamy user_id , task_id i musimy sprawdzić, czy powiązane zadanie ma flag wartość jako 0 .
Pierwsze zapytanie
Najpierw pobierzemy my_task z podanym task_id i flag jako 0 .
my_task = Tasks.objects.get(task_id=task_id, flag=0) # 1st query
Drugie zapytanie
Następnie w drugim zapytaniu musisz filtrować według UserTask model z podanym user_id i my_task obiekt.
my_user_task = UserTasks.objects.get(user_id=user_id, tasks=my_task) # 2nd query
Powinieneś wykonać drugie zapytanie tylko wtedy, gdy otrzymasz my_task obiekt o podanym task_id i flag wartość. Ponadto będziesz musiał dodać obsługę błędów w przypadku braku dopasowanych obiektów.
Co jeśli użyliśmy EmbeddedDocument dla Tasks model?
Powiedzmy, że zdefiniowaliśmy nasze Tasks dokument jako EmbeddedDocument i tasks pole w UserTasks model jako EmbeddedDocumentField , a następnie, aby wykonać żądane filtrowanie, moglibyśmy zrobić coś takiego jak poniżej:
my_user_task = UserTasks.objects.get(user_id=user_id, tasks__task_id=task_id, tasks__flag=0)
Pobieranie konkretnego my_task z listy zadań
Powyższe zapytanie zwróci UserTask dokument, który będzie zawierał wszystkie tasks . Następnie będziemy musieli wykonać pewną iterację, aby uzyskać pożądane zadanie.
W tym celu możemy wykonać zrozumienie listy za pomocą enumerate() .Wtedy żądany indeks będzie pierwszym elementem zwróconej listy 1-elementowej.
my_task_index = [i for i,v in enumerate(my_user_task.tasks) if v.flag==0][0]