Можем ли директно да филтрираме документ с ReferenceField's
полета в една заявка?
Не, не е възможно директно да филтрирате документ с полетата на ReferenceField тъй като това ще изисква присъединявания, а mongodb не поддържа присъединявания.
Според документите на MongoDB относно препратки към бази данни:
От друга страница на официалния сайт:
Така че в 1 заявка не можем и двете да филтрираме tasks с определена стойност на флаг и с дадения user_id и task_id на UserTasks модел.
Как тогава да извършите филтрирането?
За да извършим филтрирането според необходимите условия, ще трябва да извършим 2 заявки.
В първата заявка ще се опитаме да филтрираме Tasks модел с дадения task_id и flag . След това във втората заявка ще филтрираме UserTasks модел с дадения user_id и task извлечено от първата заявка.
Пример:
Да кажем, че имаме user_id , task_id и трябва да проверим дали свързаната задача има flag стойност като 0 .
Първа заявка
Първо ще извлечем my_task с дадения task_id и flag като 0 .
my_task = Tasks.objects.get(task_id=task_id, flag=0) # 1st query
Втора заявка
След това във втората заявка трябва да филтрирате UserTask модел с дадения user_id и my_task обект.
my_user_task = UserTasks.objects.get(user_id=user_id, tasks=my_task) # 2nd query
Трябва да извършите второ запитване само ако получите my_task обект с дадения task_id и flag стойност. Освен това ще трябва да добавите обработка на грешки в случай, че няма съответстващи обекти.
Ами ако сме използвали EmbeddedDocument за Tasks модел?
Да приемем, че сме дефинирали нашите Tasks документ като EmbeddedDocument и tasks поле в UserTasks модел като EmbeddedDocumentField , тогава, за да направим желаното филтриране, можехме да направим нещо като по-долу:
my_user_task = UserTasks.objects.get(user_id=user_id, tasks__task_id=task_id, tasks__flag=0)
Получаване на конкретната my_task от списъка със задачите
Горната заявка ще върне UserTask документ, който ще съдържа всички tasks . След това ще трябва да извършим някакъв вид итерация, за да получим желаната задача.
За да направим това, можем да извършим разбиране на списък с помощта на enumerate() .Тогава желаният индекс ще бъде първият елемент от върнатия списък с 1 елемент.
my_task_index = [i for i,v in enumerate(my_user_task.tasks) if v.flag==0][0]