You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sails.js 1.0与Mongo适配器聚合查询报错:无法将字符串转Date

问题:Mongo聚合$dateToString报错“can't convert from BSON type string to Date”

我尝试执行一个使用$dateToString聚合函数的查询,但每次执行都会报错:

can't convert from BSON type string to Date

注:通过客户端执行该查询可正常返回每日统计结果。

我的代码如下:

getResultsDashboard: async function (req, res) {
    var db = myTestCollection.getDatastore().manager;
    var rawmyTestCollection = db.collection(myTestCollection.tableName);

    let aggregateQuery = [
      {
        $match: { field1: "myValue" },
      },
      {
        $group: {
          _id: { $dateToString: { format: "%Y-%m-%d", date: "$createdAt" } },
          count: { $sum: 1 },
        },
      },
      {
        $sort: { _id: -1 },
      },
    ];

    let resultsByDate = await rawmyTestCollection.aggregate(aggregateQuery).toArray();

    return res.json(resultsByDate);
  }

我也尝试过使用native方法:

myTestCollection.native((err, coll) => {
  coll.aggregate(aggregateQuery).toArray((err2, result) => console.log(result));
});

但没有得到结果,仅收到native方法已弃用的提示。

我猜测是Mongo驱动的问题,请问Sails有没有其他可用驱动?或者除了从数据库取出所有日期再在JavaScript中做聚合外,还有什么其他实现方式?


解决方案

1. 排查模型字段类型配置

客户端能成功执行但代码报错,核心原因大概率是代码层面查询时,createdAt字段被序列化为字符串而非BSON Date类型。Sails/Waterline如果模型里createdAt未正确配置为日期类型,会导致数据取出时被转成字符串。

检查模型定义,确保createdAt的类型是'datetime':

// api/models/myTestCollection.js
module.exports = {
  attributes: {
    field1: { type: 'string' },
    createdAt: { type: 'datetime', autoCreatedAt: true } // 必须配置正确
  }
};

2. 强制转换字段类型修正聚合查询

如果模型配置没问题,但历史数据存在字符串格式的日期,可在聚合里先用$toDate把字符串转成Date类型再使用$dateToString:

let aggregateQuery = [
  { $match: { field1: "myValue" } },
  {
    $group: {
      _id: { 
        $dateToString: { 
          format: "%Y-%m-%d", 
          date: { $toDate: "$createdAt" } // 先转换为Date类型
        } 
      },
      count: { $sum: 1 },
    },
  },
  { $sort: { _id: -1 } },
];

3. Sails中替代native方法的正确方式

Sails v1+推荐用.getDatastore().manager获取原生Mongo客户端(即你最开始的写法),但要确保使用官方维护的适配器@sailshq/mongo,而非旧版sails-mongo。若适配器版本过低,建议升级:

npm install @sailshq/mongo --save

4. 非全量聚合的替代方案

如果以上方法不生效,可先用$project阶段处理日期再分组:

let aggregateQuery = [
  { $match: { field1: "myValue" } },
  {
    $project: {
      dateOnly: { $dateToString: { format: "%Y-%m-%d", date: { $toDate: "$createdAt" } } }
    }
  },
  {
    $group: {
      _id: "$dateOnly",
      count: { $sum: 1 }
    }
  },
  { $sort: { _id: -1 } }
];

内容的提问来源于stack exchange,提问作者Xfox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 18:13:19