Mongoose Aggregation不按输入日期过滤

时间:2016-02-26 15:22:38

标签: mongodb mongoose mongodb-query aggregation-framework

我正在尝试构建聚合查询,但是当我使用$match日期时,它不会像我预期的那样工作。如果我使用其他字段而不是任何Date字段,则按预期工作。我正在使用的代码示例如下:

const res = await Reservation.aggregate([{ $match: { createdAt: { $lte: req.endDate } } }]).exec();

const res = await Reservation.find({ createdAt: { $lte: req.endDate } }).exec();

第一行不起作用,但第二行完美无缺。 .find().aggregate()之间有什么区别?谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

Mongoose有"架构"为此它做了这个神奇的事情叫做" autocasting"为了你。设计师在这里想到的典型案例是来自" web" GETPOST之间的互动基本上包含在"字符串"。

是否有一些助手可以将参数变成带有键和值的对象,所有这些"值"仍然是"字符串",或者可能由同一"帮助"直接数字化?在适当情况下。这是常见的Web框架设计。

因此,当您发出.find()时,此函数完全无法更改返回的内容,而不是省略字段/属性,因此"架构&#34 ;适用。

.aggregate()方法完全不同。它的全部存在是修改文档和集合中包含的内容。这样做的结果是它是不可能的"要应用的架构。

因此," autocasting"存在于.find() 之类的方法中,并且您需要投射元素(例如"字符串"您的"日期"正在自己发送as)到正确的类型:

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

即使你正在做的只是一个$match并且你没有"修改过"任何方式的模式,mongoose都没有"假设"这并且不会尝试转换为模式中的匹配字段。

这里的逻辑是$match阶段或类似的任何可以绑定到"类型"的阶段,可能发生在管道内的任何地方。因此,无法保证管道阶段所执行的文档与原始集合架构有任何相似之处。

可以说"可能" 可能会认为这个 是第一个没有任何改变并且进行类似检查的管道阶段。但这不是当前代码库的工作方式。

因此,简而言之,在使用聚合管道时,需要专门转换为类型(Date,ObjectId等)的所有对象需要手动"在你的代码中强制转换,而不是假设mongoose会像其他方法一样为你做这件事。