猫鼬自定义SchemaType转换为JSON / Transform

时间:2019-12-04 16:40:54

标签: node.js mongodb express mongoose

对于我当前正在处理的应用程序,我需要没有时间来存储日期。通过创建看起来像这样的自定义架构类型来完成此操作:

var mongoose = require('mongoose');

/**
 * Registers a new DateOnly type field. Extends the `Date` Schema Type
 */
function DateOnly(key, options) {
  mongoose.SchemaTypes.Date.call(this, key, options, 'DateOnly');
}

DateOnly.prototype = Object.create(mongoose.SchemaTypes.Date.prototype);

DateOnly.prototype.cast = (originalValue) => {
  try {
    var value = originalValue;
    if (typeof value === 'string' && !value.match(/^([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))(T00:00:00.000Z)?$/)) {
      throw new Error('Date is invalid');
    } else if (typeof value === 'number') {
      value = new Date(value);
    }

    if (value instanceof Date) {
      value = new Date(value.getFullYear(), value.getMonth(), value.getDate());
    }

    return mongoose.Schema.Types.Date._cast(value);
  } catch (err) {
    throw new mongoose.SchemaType.CastError('date', originalValue, this.path);
  }
};

mongoose.Schema.Types.DateOnly = DateOnly;

module.exports = DateOnly;

这允许模型接受日期字符串(例如:2020-01-01)和日期对象。现在,它将所有时间存储在UTC午夜时间,这样我仍然可以获得将它们作为日期存储在mongodb中的所有优点。

我遇到的问题是,当我将其中一个日期返回给API时,它将以完全ISO格式(例如:2020-01-01T00:00:00.000Z)返回,该格式将转换为本地用户的时区。在我的时区中,此日期将比预期的早1天显示。

所以我的问题是,如何使之成为document.toJSON时要转换日期?我知道我要返回的是date.toISOString().substring(0,10)

我尝试从Date类继承,但是我发现它与mongoose和mongodb驱动程序的工作方式不兼容。

我知道我可以编写一种方法来放入toJSON.transform选项,但是然后我必须对使用该类型的每个字段和模型执行此操作。

1 个答案:

答案 0 :(得分:0)

在 mongoose 5.9.0 中添加了一个解决方案,可以这样做:

DateOnly.set('transform', (val) => {
  return /* transformed value */;
});

来源:https://github.com/Automattic/mongoose/issues/8403

相关问题