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

Mongoose Aggregation filtert nicht nach Eingabedatum

Mongoose hat "Schemata", für die es diese magische Sache namens "Autocasting" für Sie erledigt. Der typische Fall, an den die Designer hier denken, ist, dass alle Eingaben von "Web"-Interaktionen wie GET und POST ist grundsätzlich in einem "String" enthalten.

Unabhängig davon, ob es einen Helfer gibt, der Parameter in Objekte mit Schlüsseln und Werten umwandelt, sind alle diese "Werte" immer noch "Zeichenfolgen" oder möglicherweise direkt numerisch von denselben "Helfern", wo dies angemessen ist. Dies ist ein gängiges Web-Framework-Design.

Wenn Sie also ein .find() ausgeben , ist diese Funktion völlig unfähig den zurückgegebenen Inhalt anders als durch Weglassen von Feldern/Eigenschaften zu ändern, daher wird das "Schema" angewendet.

Die .aggregate() Methode ist vollständig anders. Seine gesamte Existenz besteht darin, modifiziert zu werden Inhalte, die in Dokumenten und Sammlungen enthalten sind. Die Folge davon ist, dass es "unmöglich" ist, dass ein Schema angewendet wird.

Daher das "Autocasting", das in Methoden wie .find() vorhanden ist passiert nicht , und Sie müssen Elemente (wie die "Zeichenfolge", als die Ihr "Datum" gesendet wird) selbst in die richtigen Typen umwandeln:

Reservation.aggregate([
   { "$match": { "createdAt": { "$lte": new Date(req.endDate) } } }
])

Auch wenn Sie nur ein $match tun und dass Sie das Schema in keiner Weise "modifiziert" haben, "vermutet" Mongoose dies nicht und versucht nicht, in das passende Feld im Schema umzuwandeln.

Die Logik hier ist, dass ein $match stage oder etwas Ähnliches, das an einen "Typ" gebunden werden könnte, überall in der Pipeline auftreten könnte. Daher gibt es keine Garantie dafür, dass die Dokumente, auf die in einer Pipeline-Phase reagiert wird, Ähnlichkeit mit dem ursprünglichen Sammlungsschema aufweisen.

Es ist wohl "könnte" Bedenken Sie möglicherweise, dass dies ist die erste Pipelinestufe, an der sich möglicherweise nichts geändert haben könnte, und eine ähnliche Inspektion durchführen. Aber so funktionierte die aktuelle Codebasis nicht.

Kurz gesagt, wenn Sie die Aggregationspipeline verwenden, müssen alle Objekte, die speziell in einen Typ ( Date, ObjectId usw.) umgewandelt werden müssen, „manuell“ in Ihren Code umgewandelt werden, anstatt davon auszugehen, dass Mongoose dies für Sie tun wird wie bei anderen Methoden.