Kunnen we direct op een document filteren met de ReferenceField's
velden in een enkele zoekopdracht?
Nee, het is niet mogelijk om een document direct te filteren met de velden van ReferenceField
omdat hiervoor joins nodig zijn en mongodb ondersteunt geen joins.
Volgens MongoDB-documenten op databasereferenties:
Van een andere pagina op de officiële site:
Dus in 1 zoekopdracht kunnen we niet allebei tasks
filteren met een bepaalde vlagwaarde en met de gegeven user_id
en task_id
op de UserTasks
model.
Hoe moet ik dan filteren?
Om de filtering volgens de vereiste voorwaarden uit te voeren, moeten we 2 zoekopdrachten uitvoeren.
In de eerste zoekopdracht zullen we proberen de Tasks
. te filteren model met de opgegeven task_id
en flag
. Vervolgens filteren we in de 2e query UserTasks
model met de opgegeven user_id
en de task
opgehaald uit de eerste zoekopdracht.
Voorbeeld:
Laten we zeggen dat we een user_id
. hebben , task_id
en we moeten controleren of de gerelateerde taak een flag
. heeft waarde als 0
.
Eerste zoekopdracht
We zullen eerst de my_task
. ophalen met de opgegeven task_id
en flag
als 0
.
my_task = Tasks.objects.get(task_id=task_id, flag=0) # 1st query
2e zoekopdracht
Vervolgens moet u in de 2e query filteren op UserTask
model met de opgegeven user_id
en my_task
voorwerp.
my_user_task = UserTasks.objects.get(user_id=user_id, tasks=my_task) # 2nd query
U moet de tweede zoekopdracht alleen uitvoeren als u een my_task
. krijgt object met de opgegeven task_id
en flag
waarde. U moet ook foutafhandeling toevoegen voor het geval er geen overeenkomende objecten zijn.
Wat als we EmbeddedDocument
hebben gebruikt? voor de Tasks
model?
Laten we zeggen dat we onze Tasks
hebben gedefinieerd document als een EmbeddedDocument
en de tasks
veld in UserTasks
model als een EmbeddedDocumentField
, om vervolgens de gewenste filtering uit te voeren, hadden we zoiets als hieronder kunnen doen:
my_user_task = UserTasks.objects.get(user_id=user_id, tasks__task_id=task_id, tasks__flag=0)
De specifieke my_task
. ophalen uit de lijst met taken
De bovenstaande query retourneert een UserTask
document dat alle tasks
. zal bevatten . We zullen dan een soort iteratie moeten uitvoeren om de gewenste taak te krijgen.
Om dat te doen, kunnen we lijstbegrip uitvoeren met enumerate()
.Dan is de gewenste index het eerste element van de lijst met 1 element dat wordt geretourneerd.
my_task_index = [i for i,v in enumerate(my_user_task.tasks) if v.flag==0][0]