在Mongoose聚合时无法使用moment.js

4
我正在使用聚合管道,像这样:

Model.aggregate([
  $project:{
    expiry: moment("$date_expired").format('h')}]
,function(err,res){...});

"$date_expired" 是一个Schema中的日期。

但是,当我尝试从上述聚合中获取结果时,出现了错误FieldPath \'Invalid date\' doesn\'t start with $

可能的错误是什么?我要如何解决?


在Mongo中不能使用$hour聚合吗?请参考https://docs.mongodb.com/manual/reference/operator/aggregation/hour/。 - MrWillihog
是的,但我需要获取差异,所以我也必须使用$substract。我希望能有一个更简单的解决方案,因为我已经在我的应用程序中使用了moment。 - Faizuddin Mohammed
3个回答

1

您可以在聚合管道中使用$function,但是您需要将MongoDB升级到v4.4。

     Model.aggregate([
     { $addFields:{
        expiry: {
          $function:{
            body:function(date_expire){return moment(date_expired).format('h')},
           args:['$date_expire'],
           lang:"js"
        }}
     }])

2
如果你只需要 'h',你可以使用其他函数,比如 $dateToString,并使用格式和时区选项来获取任何你想要的格式的数据。 - Badri Derakhshan
1
哦,谢谢。这对我很有帮助。应该将其标记为答案。 - hamid reza jafari

-2

这永远不会起作用。 moment 是你的 node.js 代码中的一个函数,但聚合运行在 MongoDB 中。

如果你想让它在迭代时运行 moment('$fieldInYourSchema'),那是不可能的,因为 moment 实际上会在调用聚合之前运行(例如,在构造要提交到数据库的数组时)。


-3

你应该尝试一下:

Model.aggregate([
  $project:{
    expiry: moment($date_expired).format('h')}]
,function(err,res){...});

因为

$date_expired

是一个变量,所以你不应该用 "" 来表示它。


不是变量,而是MongoDB结果中的一个属性。而且,在属性名称前面加上了 $ 符号来表示。 - Faizuddin Mohammed
是的,我做了。很明显它抛出了未知变量错误。 - Faizuddin Mohammed
由于您正在使用Angular来定义函数,因此无法将其作为参数传递。尝试在调用模型时传递更新后的内容。 - Deepak Sharma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接