猫鼬聚合不按输入日期过滤 [英] Mongoose Aggregation does not Filter by Input Date

查看:78
本文介绍了猫鼬聚合不按输入日期过滤的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试建立一个聚合查询,但是当我将$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()有什么区别.感谢您的帮助!

解决方案

猫鼬具有模式",它可以为您执行称为自动广播"的魔术操作.设计人员想到的典型情况是,所有来自网络"交互(例如GETPOST)的输入基本上都包含在字符串"中.

无论是否有一些使参数变成具有键和值的对象的助手,所有这些值"仍然是字符串",或者在适当的情况下可能由相同的助手"直接制成数字.这是常见的Web框架设计.

因此,当您发布.find()时,此功能完全无能,除了遗漏字段/属性外,它无法更改返回的内容,因此将应用模式".

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

因此,像.find() 这样的方法中出现的自动广播"不会发生,并且您需要强制转换元素(例如,将日期"作为字符串"发送为),自己输入正确的类型:

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

即使您所做的只是一个$match,并且您没有以任何方式修改"该模式,猫鼬也不会假定"该对象,也不会尝试将其强制转换为该模式中的匹配字段. /p>

这里的逻辑是$match阶段或可能绑定到类型"的任何类似事件都可能发生在管道内的任何地方.因此,不能保证管道阶段要执行的文档与原始收集模式有任何相似之处.

可以说,可以" 可能考虑到以下事实:该的第一个流水线阶段,在此阶段可能没有任何变化并进行类似的检查.但这不是当前代码库的工作方式.

因此,简而言之,在使用聚合管道时,需要将所有需要专门转换为类型(Date,ObjectId等)的对象都手动"转换为代码,而不是假定猫鼬会这样做就像其他方法一样.

I'm trying to build a aggregation query but when I use $match with dates, it doesn't work as I expect. If I use other fields instead of any Date field, it works as expected. The code examples I'm using is below:

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

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

The first line doesn't work but the second one works perfectly. What is the difference between .find() and .aggregate(). Thanks for your help!

解决方案

Mongoose has "schemas" for which it does this magic thing called "autocasting" for you. The typical case the designer(s) have in mind here is that all input from "web" interations like GET and POST is basically contained in a "string".

Whether or not there is some helper that that makes paramters into objects with keys and values, all those "values" are still "strings", or possibly made directly numeric by the same "helpers" where appropriate. This is common web framework design.

So when you issue a .find(), this function is completely incapable of altering the returned content other than by omission for fields/properties, so hence the "schema" is applied.

The .aggregate() method is entirely different. It's entire existence is to modify content contained in documents and collections. The consequence of this is that it is "impossible" for a schema to apply.

Hence, the "autocasting" present in methods like .find() does not happen, and you are required to cast elements ( such as the "string" your "date" is being sent in as ) to the correct types yourself:

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

Even if all you are doing is a $match and that you have not "modified" the schema in any way, mongoose does not "presume" this and does not attempt to cast to the matching field in the schema.

The logic here is that a $match stage or anything similar that could be bound to a "type", could occur anywhere within the pipeline. As such there is no guarantee that the documents being acted on by a pipeline stage bear any resemblance to the original collection schema.

Arguably it "could" possibly consider the fact that this is the first pipeline stage where nothing could possibly have changed and do a similar inspection. But that is not how the current code base worked.

So in short, when using the aggregation pipeline, all objects that need to be specifically cast to a type ( Date, ObjectId, etc ) need to be "manually" cast in your code, rather than assuming mongoose is going to do it for you like in other methods.

这篇关于猫鼬聚合不按输入日期过滤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆