云函数使用数据库aggregate筛选时间返回结果为空,如何解决?
发布于 7 年前 作者 kpan 4130 次浏览 来自 官方Issues

最近要在云函数上做一个统计功能,因此需要用到aggregate。参照着API文档写,我的集合是这样的,文档包含一个date类型的字段:

{
    ……
    rec_date: "2019-07-31T03:40:12.345Z",

   duration: 700,

   ……

}

我需要在每个指定的时间区间对duration进行求和,但发现我无论怎样比较时间,筛选以后都是没有任何数据进行求和了,最后返回结果的列表是空的。我尝试把时间筛选的条件去掉,返回结果的列表就有数值了。最初我是这样写的:

res = await db.collection('ndata').aggregate()
      .match(
        $.and([
                {rec_date: $.gte(new Date(startDate))},
                {rec_date: $.lt(new Date(endDate))},
             ])
      )
      .group({
        _id: null,
        total: $.sum('$duration'),
      })
      .end()

后来我把$.and去掉只保留$.gte一个条件试验也不行。同样的区间输入数值我使用db.collection().where().get()是可以正确获得数据的,证明该区间是存在数据的,但是使用到aggregate就一直返回一个空列表。我试过使用其他类型的条件到match内可以返回聚合sum的数值,唯独date类型的会有问题。已经调试了很久,试过各种办法都没用,不知道哪里出问题,希望大神们指点,谢谢。

2 回复

Aggregate的时候不能直接使用日期进行比较,而应该使用以下代码:

let date = new Date();
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
const d = new Date(),
a = $.dateFromString({
  dateString: date.toJSON()
}),
b = $.dateFromString({
  dateString: d.toJSON()
})
console.log({ a, b });
const match = await db.collection('match').aggregate().addFields({
  matched: $.and([ $.lte(['$vote_date', a]), $.gte(['$vote_date', b]) ]),
}).match({
  matched: !0,
}).unwind('$vote_id').end();
console.log('match', match);

或者在数据库设计时(添加)使用时间戳(数字)

同样遇到

回到顶部