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]