Синхронизированный Cron Expire на простой схеме

У меня возникли некоторые проблемы при настройке задания cron с пакетом percolate:synced-cron для истечения срока действия записей коллекции на основе простых полей даты и времени схемы. Есть ли другой способ сделать это, или я делаю что-то не так?

Я получаю следующую ошибку ниже:

Ошибка типа: Posts.find(...). ToArray не является функцией

Синхронизированный код Cron

SyncedCron.start();


SyncedCron.add({
  name: 'Expire Events',
  schedule: function(parser) {
    // parser is a later.parse object
    return parser.text('every 15 minutes');
  },
  job: function() {
    expireToday = Posts.find ({
      date: new Date().toISOString().substring(0,10)
    }).toArray();
    console.log(expireToday);
    for (i = 0; i < expireToday.length; i++) {
      expireId = expireToday.eq(i)._id;
      console.log(expireId);
      if (expireToday.eq(i).time < new Date().toTimeString().substring(0,5)) {
        Posts.deleteOne({_id : expireId});
      }
    }
  }
});

Простая схема кофейного кода

Schemas.Posts = new SimpleSchema
    title:
        type:String
        max: 60
        optional: true

    content:
        type: String
        optional: true
        autoform:
            rows: 5

    createdAt:
        type: Date
        autoValue: ->
            if this.isInsert
                new Date()

    updatedAt:
        type:Date
        optional:true
        autoValue: ->
            if this.isUpdate
                new Date()


    time:
        type: String
        optional: false
        autoform:
            afFieldInput:
                type: 'time'


    date:
        type: String
        optional: false
        autoform:
            afFieldInput:
                type: 'date'


    owner:
        type: String
        regEx: SimpleSchema.RegEx.Id
        autoValue: ->
            if this.isInsert
                Meteor.userId()
        autoform:
            options: ->
                _.map Meteor.users.find().fetch(), (user)->
                    label: user.emails[0].address
                    value: user._id

Пример даты и времени монго

"date" : "2017-09-10"
"time" : "01:01"

2 ответа

Смотрите этот пост

Переход от дат к строкам не очень хорош для поиска в mongodb. Если вам нужны документы, срок действия которых истекает сегодня, то вы хотите определить сегодня как переход с полуночи до полуночи. Вы также можете массово удалять при запуске кода на сервере (задания SyncedCron всегда выполняются на сервере).

SyncedCron.add({
  name: 'Expire Events',
  schedule: function(parser) {
    return parser.text('every 15 minutes');
  },
  job: function() {
    let todayStart = new Date();
    todayStart.setHours(0,0,0,0);
    let todayEnd = todayStart.setHours(23,59,59,999);
    Posts.remove ({ date: {$gte: todayStart, $lte: todayEnd });
  }
});

Но это предполагает, что вы храните datetime в полях datetime mongodb, а не в виде строк (что, кстати, вам абсолютно необходимо сделать, если не что иное, как получить поддержку часового пояса).

Если вы хотите использовать свою схему с датой и временем в виде строк, вы можете сделать:

SyncedCron.add({
  name: 'Expire Events',
  schedule: function(parser) {
    return parser.text('every 15 minutes');
  },
  job: function() {
    let today = new Date().toISOString().substring(0,10);
    let now = new Date().toTimeString().substring(0,5);
    Posts.remove ({ date: today, time: { $lte: now });
  }
});

Сообщение об ошибке говорит вам, что это не удалось:

expireToday = Posts.find ({
  date: new Date().toISOString().substring(0,10)
}).toArray();

Это означает, что ваш Posts.find() не возвращает ничего, что может быть преобразовано в массив.

Он возвращает курсор, может быть, вы хотели добавить .fetch() получить массив объектов?

В любом случае вы должны проверить возврат вызова, подобного этому, чтобы убедиться, что он возвращает то, что вы ожидаете - только базовая практика защитного кодирования

Другие вопросы по тегам