Mongodb Mongoose查询钩子,修改所有传入日期

Mongodb Mongoose查询钩子,修改所有传入日期,mongodb,mongoose,hook,Mongodb,Mongoose,Hook,我有一个MEAN应用程序,我在mongodb中存储了很多日期,10月27日英国的时钟在变化,所以数据库中存储的所有日期都需要添加一个小时。 我不想循环查看数据库中的所有文档并在其日期上添加一个小时,我更希望是动态的,因此我尝试实现一个查询钩子来检查传入文档上的每个日期以及文档中附加的时区偏移,以添加/减去时区偏移。 问题是,我希望传入文档上的循环能够动态地识别日期所在的位置,有时会在文档的根上,隐藏在对象或数组中,我很难对循环建模以检查所有这些。 我使用函数来检查传入的对象是日期、对象还是数组,

我有一个MEAN应用程序,我在mongodb中存储了很多日期,10月27日英国的时钟在变化,所以数据库中存储的所有日期都需要添加一个小时。 我不想循环查看数据库中的所有文档并在其日期上添加一个小时,我更希望是动态的,因此我尝试实现一个查询钩子来检查传入文档上的每个日期以及文档中附加的时区偏移,以添加/减去时区偏移。 问题是,我希望传入文档上的循环能够动态地识别日期所在的位置,有时会在文档的根上,隐藏在对象或数组中,我很难对循环建模以检查所有这些。 我使用函数来检查传入的对象是日期、对象还是数组,但是mongoose添加了一堆妨碍操作的对象/函数,因此我得到了
RangeError:超过了最大调用堆栈大小

const config = require('../config/environment');
var UK_TIMEZONE_GMT_OFFSET = config.UK_TIMEZONE_GMT_OFFSET || 0; // should check if the offset is the same as in each document in the db, if it doesn't match then I'll subtract the offset.

const mongoose = require('mongoose');
const exec = mongoose.Query.prototype.exec;

const Q = require('Q');

mongoose.Query.prototype.exec = function () {
  var d = Q.defer();
  var p = exec.apply(this, arguments);
  if (p) p.then(function (rs) {
    var mod;
    try {
      mod = fixDates(rs);
    } catch (err) {
      console.log(err, rs)
    };
    d.resolve(mod);
  }, d.reject);
  return d.promise;
}

function fixDates(rs) {
  if (isArray(rs)) {
    rs.forEach(function (r, i) {
      rs[i] = fixDates(r);
    })
  } else if (isObject(rs)) {
    for (var key in rs) {
      var val = rs[key];
      if (isObject(val)) console.log('isobject', isObject(val), val);
      // the '_id' of the document is considered an object
      // also some stuff like Schema, NativeCollection ... are objects as well
      // rs[key] = fixDates(val); // this line causes problems 
    }
  } else if (isDate(rs)) {
    // modify the date if necessary ..
    // Check the timezone offset of the document vs the global timezone offset 
        of the system then add/subtract the difference
  }
  return rs;
}

function isDate(obj) {
  return obj instanceof Date;
}

function isObject(obj) {
  return Object.prototype.toString.call(obj) === '[object Object]';
}

function isArray(obj) {
  return Array.isArray(obj);
}

我需要更好的方法来处理mongoose返回的对象,以便在所有文档中循环并深入查找日期并修改它们。

我更新了循环函数以调用model.toObject(如果存在)并应用更新日期字段,同时仍然保留model类

function recur(rs, docTimezone) {
  if (isArray(rs)) {
    rs.forEach(function (r, i) {
      rs[i] = recur(r, docTimezone);
    })
  } else if (isObject(rs)) {
    if (rs.toObject) {
      return updateModel(rs, recur(rs.toObject(), docTimezone))
    }
    Object.keys(rs).forEach(function (key) {
      var val = rs[key];
      rs[key] = recur(val, docTimezone !== undefined ? docTimezone : rs.usedTimezoneGMTOffset); // usedTimezoneGMTOffset if exists on the doc
    })
  } else if (isDate(rs)) {
    // modify the date if necessary ..
    rs = alignTimezone(rs, docTimezone);
  }
  return rs;
}

function updateModel(model, updates) {
  var key, val;
  for (key in updates) {
    val = updates[key];
    if (val !== void 0 && key !== '_id') {
      model[key] = val;
    }
  }
  return model;
}