我正在尝试构建聚合查询,但是当我使用$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()
之间有什么区别?谢谢你的帮助!
答案 0 :(得分:1)
Mongoose有"架构"为此它做了这个神奇的事情叫做" autocasting"为了你。设计师在这里想到的典型案例是来自" web" GET
和POST
之间的互动基本上包含在"字符串"。
是否有一些助手可以将参数变成带有键和值的对象,所有这些"值"仍然是"字符串",或者可能由同一"帮助"直接数字化?在适当情况下。这是常见的Web框架设计。
因此,当您发出.find()
时,此函数完全无法更改返回的内容,而不是省略字段/属性,因此"架构&#34 ;适用。
.aggregate()
方法完全不同。它的全部存在是修改文档和集合中包含的内容。这样做的结果是它是不可能的"要应用的架构。
因此," autocasting"存在于.find()
之类的方法中,并且您需要投射元素(例如"字符串"您的"日期"正在自己发送as)到正确的类型:
Reservation.aggregate([
{ "$match": { "createdAt": { "$lte": new Date(req.endDate) } } }
])
即使你正在做的只是一个$match
并且你没有"修改过"任何方式的模式,mongoose都没有"假设"这并且不会尝试转换为模式中的匹配字段。
这里的逻辑是$match
阶段或类似的任何可以绑定到"类型"的阶段,可能发生在管道内的任何地方。因此,无法保证管道阶段所执行的文档与原始集合架构有任何相似之处。
可以说"可能" 可能会认为这个 是第一个没有任何改变并且进行类似检查的管道阶段。但这不是当前代码库的工作方式。
因此,简而言之,在使用聚合管道时,需要专门转换为类型(Date,ObjectId等)的所有对象需要手动"在你的代码中强制转换,而不是假设mongoose会像其他方法一样为你做这件事。