Как стать автором
Обновить

Комментарии 13

Может я чего-то не понял, но чем принципиально будет отличаться перебор всей базы по времени от перебору по такой регулярки? Все равно все данные будут просматриваться, только тут еще и велосепед в коде? Поправьте, если я не прав.
так вот кто это делает оказывается.
В чём решние? Что там, где нужно было применить Date() отсекая секунды, было принято решение парсить строки?
Нет, скорее автор имел ввиду не это. Предположим крон вызывает скрипт и обращается к базе в 12 часов 12 минут. И у нас есть задача, которая должна отработать в это время. Мы разбиваем текущее время на составляющие части и смотрим все записи, в которых есть подходящие записи. Среди таки например будет: 12 12, * *, * 12, 12 * и т.д. Т.е. фактически задача стоит в том, чтобы появилась возможность указать время выполнения постинга не в конкретное время или интервал, а как в кроне (например каждую 12ую минуту 13ого часа по средам). С использованием Date() тривиальным путем этого не добиться (по крайней мере мне быстрого решения не приходит на ум, но с удовольствием выслушаю предложения). В своем первом комментарии не до конца понял автора и поэтому спешу извиниться.
Почему нельзя просто хранить в документах время отправки в обычной posix форме и отправлять, если оно стало меньше time()? Или я неправильно понял задачу?
Да, судя по количеству вопросов автор действительно невнятно объяснил. Выше изложил то, что, как мне показалось, пытался реализовать автор.
Спасибо, что объяснили. Когда я вижу регулярки в фильтрах, становится как-то не по себе. Для этой задачи можно, например, хранить дни, часы, минуты отдельно в форме субдокумента и использовать multikeys.
Да, тоже в голову это пришло, но согласитесь, что по сути выйдет тоже самое. Вам также прийдется проводить сравнение на *, числа и т.п. Тут скорее вопрос в том, как эффективней будет работать Mongo: с регуляркой по строке или фильтрами по нескольким спискам. Что-то мне подсказывает, что регулярка будет быстрее да и в реализации проще, но утверждать не буду, так как с Mongo не очень плотно работал.
Если построить обычный многополевой индекс, то он будет работать весьма эффективно, примерно так же, как индекс по нескольким полям в MySQL, при условии, что они в нужном порядке есть в фильтре. Однако, в отличие от MySQL, если свойство не число, а массив чисел, добавится в индекс каждый элемент массива. Таким образом, можно задавать интервалы. Это может привести к некоторой избыточности хранения данных (если запускать надо каждые 2 минуты, придётся хранить в массиве все чётные минуты). Но работать будет быстрее регулярок. Если количество документов в базе невелико, и устроит фулскан по регулярке, тогда можно наверное и ей обойтись. А ещё можно просто добавлять правила в кронтаб.
А разумно ли будет хранить в такой структуре что-то типа этого: */2 */2 */2 */2 */2? Это получается что мне нужно будет хранить 30 значений для минут, 12 для часов, 15 для дней, 6 для месяцев и 3 для дней недели… В сумме получим… 66 значений вместо 19 символов. Конечно это самый маразматичный случай и вряд ли кто-то такое будет использовать… В любом случае добавлю в избранное.
А вот про правила кронтаба не совсем понял. Что вы имеете ввиду? Каждой задаче создавать свое правило? Так они динамически добавляются через веб-форму, как я понял, и их может быть миллион.
Это маловероятный случай, хотя и возможный. Да, в таком случае придется сохранить 66 значений, но зато потом легче выбирать будет. Другое решение мне пока в голову не пришло (кроме как писать в кронтаб)
По поводу крона. Правила можно сохранять в базу и писать в кронтаб только уникальные (новые) правила. Если это операторская форма для рассылки рекламы или ведения информационной войны, то хватит крона. Если для посторонних пользователей — я не могу сказать точно, поскольку не приходилось использовать крон на милионном числе задач. Коллекция с индексами в этом случае должна работать эффективнее регулярок.
По ходу реализации пришла в голову еще одна идея. Создать поле в базе nextTimeSend. Заносим в базу крон правило, потом подключаем вот эту библиотеку по работе с кроном github.com/mtdowling/cron-expression и вычисляем ближайшую дату, совпадающую с правилом крона:

$cron = Cron\CronExpression::factory($cronRule);
$nextTimeSend = strtotime($cron->getNextRunDate()->format('Y-m-d H:i'));

$cronRule — наше правило крона.

Записываем эту дату в базу.
Теперь выборку легче делать без регулярки.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации