CosmosDB(Mongo)聚合查询报错:无法将对象转换为日期
问题分析与解决办法
为啥提交的毫秒数存成了带$date的对象?
你前端用FormData.append("date", Date.now())时,Date.now()返回的是数字,但FormData会自动把所有值转换为字符串。后端拿到的req.body.date是字符串形式的毫秒数(比如"1665398047000"),直接赋值给mongoose Schema中定义的Date类型字段时,mongoose没有正确将这个字符串毫秒数解析为Date对象,最终在Cosmos DB中存储为包含$date的嵌套对象结构,而非MongoDB原生的Date类型。
聚合报错的原因
聚合管道中的$year操作符仅能处理原生Date类型的数据,但你的date字段实际存储的是嵌套对象,因此MongoDB无法将对象转换为Date类型,抛出Can't convert from object to date错误。
修复方案
方法一:修改入库代码(从根源解决)
后端存储数据时,先将字符串形式的毫秒数转为数字,再生成Date对象:
var data = new Data({ user: req.body.User, // 先转数字再生成Date对象 date: new Date(Number(req.body.date)), // 其他字段... })
这样存入的就是原生Date类型,后续聚合使用$year就能正常执行。
方法二:调整聚合查询(适配已存储的旧数据)
如果已经有大量数据是嵌套对象格式,可以在聚合管道中先提取$date字段的值并转换为Date类型:
[ { $group: { _id: { $year: { $toDate: "$date.$date" } } } }, { $project: { _id: 1 } }, { $sort: { _id: 1 } } ]
通过$toDate将$date中的字符串日期转换为Date类型,再用$year提取年份。
内容的提问来源于stack exchange,提问作者Segfault
相关产品推荐
相关产品推荐

