MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Eingebettete Mongo-Dokumentabfrage

Können wir mit dem ReferenceFields Felder in einer einzigen Abfrage?

Nein Es ist nicht möglich, ein Dokument direkt mit den Feldern von ReferenceField zu filtern da dies Joins erfordern würde und Mongodb Joins nicht unterstützt.

Gemäß MongoDB-Dokumentation auf Datenbankreferenzen:

Von einer anderen Seite auf der offiziellen Seite:

In einer Abfrage können wir also nicht beide tasks filtern mit einem bestimmten Flag-Wert und mit der angegebenen user_id und task_id auf den UserTasks Modell.

Wie führe ich dann die Filterung durch?

Um die Filterung gemäß den erforderlichen Bedingungen durchzuführen, müssen wir 2 Abfragen durchführen.

In der ersten Abfrage werden wir versuchen, die Tasks zu filtern Modell mit der angegebenen task_id und flag . Dann filtern wir in der zweiten Abfrage UserTasks Modell mit der angegebenen user_id und die Aufgabe von der ersten Abfrage abgerufen.

Beispiel:

Nehmen wir an, wir haben eine user_id , task_id und wir müssen prüfen, ob die zugehörige Aufgabe flag hat Wert als 0 .

Erste Abfrage

Wir werden zuerst my_task abrufen mit der angegebenen task_id und flag als 0 .

my_task = Tasks.objects.get(task_id=task_id, flag=0) # 1st query

Zweite Abfrage

Dann müssen Sie in der zweiten Abfrage nach UserTask filtern Modell mit der angegebenen user_id und meine_aufgabe Objekt.

my_user_task = UserTasks.objects.get(user_id=user_id, tasks=my_task) # 2nd query

Sie sollten die zweite Abfrage nur durchführen, wenn Sie eine my_task erhalten Objekt mit der angegebenen task_id und flag Wert. Außerdem müssen Sie eine Fehlerbehandlung hinzufügen, falls keine übereinstimmenden Objekte vorhanden sind.

Was ist, wenn wir EmbeddedDocument verwendet haben? für die Aufgaben Modell?

Nehmen wir an, wir haben unsere Aufgaben definiert Dokument als EmbeddedDocument und die Aufgaben Feld in UserTasks model als EmbeddedDocumentField , dann hätten wir, um die gewünschte Filterung durchzuführen, so etwas wie unten tun können:

my_user_task = UserTasks.objects.get(user_id=user_id, tasks__task_id=task_id, tasks__flag=0)

Abrufen des jeweiligen my_task aus der Aufgabenliste

Die obige Abfrage gibt eine UserTask zurück Dokument, das alle Aufgaben enthält . Wir müssen dann eine Art Iteration durchführen, um die gewünschte Aufgabe zu erhalten.

Dazu können wir das Listenverständnis mit enumerate() durchführen .Dann wird der gewünschte Index als erstes Element der 1-Element-Liste zurückgegeben.

my_task_index = [i for i,v in enumerate(my_user_task.tasks) if v.flag==0][0]