Kan vi filtrera direkt på ett dokument med code>Referensfälts fält i en enda fråga?
Nej, det är inte möjligt att direkt filtrera ett dokument med fälten ReferenceField
eftersom detta skulle kräva joins och mongodb stöder inte joins.
Enligt MongoDB-dokument på databasreferenser:
Från en annan sida på den officiella webbplatsen:
Så i en fråga kan vi inte båda filtrera uppgifter
med ett visst flaggvärde och med angivet user_id
och task_id
på UserTasks
modell.
Hur utför man filtreringen då?
För att utföra filtreringen enligt de villkor som krävs måste vi utföra två frågor.
I den första frågan kommer vi att försöka filtrera Tasks
modell med det givna task_id
och flagga
. Sedan, i den andra frågan, kommer vi att filtrera UserTasks
modell med det givna user_id
och uppgiften
hämtas från den första frågan.
Exempel:
Låt oss säga att vi har ett user_id
, uppgifts-id
och vi måste kontrollera om den relaterade uppgiften har flagga
värde som 0
.
Första frågan
Vi kommer först att hämta min_uppgift
med det angivna task_id
och flagga
som 0
.
my_task = Tasks.objects.get(task_id=task_id, flag=0) # 1st query
andra frågan
Sedan i den andra frågan måste du filtrera på UserTask
modell med det givna user_id
och min_uppgift
objekt.
my_user_task = UserTasks.objects.get(user_id=user_id, tasks=my_task) # 2nd query
Du bör endast utföra den andra frågan om du får en my_task
objekt med det givna task_id
och flagga
värde. Du måste också lägga till felhantering om det inte finns några matchade objekt.
Tänk om vi har använt EmbeddedDocument
för Tasks
modell?
Låt oss säga att vi har definierat våra Tasks
dokument som ett EmbeddedDocument
och uppgifterna
fältet i UserTasks
modell som ett EmbeddedDocumentField
, sedan för att göra den önskade filtreringen kunde vi ha gjort något som nedan:
my_user_task = UserTasks.objects.get(user_id=user_id, tasks__task_id=task_id, tasks__flag=0)
Hämta den specifika my_task
från listan över uppgifter
Ovanstående fråga returnerar en UserTask
dokument som kommer att innehålla alla uppgifter
. Vi kommer då att behöva utföra någon form av iteration för att få önskad uppgift.
För att göra det kan vi utföra listförståelse med enumerate()
.Då kommer det önskade indexet att vara det första elementet i listan med 1 element som returneras.
my_task_index = [i for i,v in enumerate(my_user_task.tasks) if v.flag==0][0]