2016-02-03 2 views
3

Существует определенная задача, которую я хочу выполнить, но я не нахожу никакого конкретного способа сделать это. Допустим, у меня есть приложение, которое используется для отправки писем. Я продолжаю записывать эти письма в коллекции в монго. И используя это приложение, я могу отправить почту прямо сейчас или планировать рассылки на будущее. Структура документов в коллекции, как:Создать условный TTL в mongo

{ 
'_id' : 123456789, 
'to_email' : '[email protected]' 
'from_email' : '[email protected]' 
'subject': 'some subject' 
'type' : '<1 if normal and 2 if scheduled>', 
'createdDate' '<date when mail was sent or the request was created>', 
'scheduledDate' : '<time for which mail is scheduled>' 
.. and many more key-value pairs 
} 

Поле scheduledDate может быть равен нулю или любой даты, в зависимости от того, если его планируется или нет. Я не хочу хранить данные старше 2 дней, поэтому я создал индекс TTL на 'createdDate' в течение 2 дней. Но я также не хочу удалять строки или запросы, запланированные на будущее. Я искал какой-то условный TTL, но не смог найти такого решения.

Есть ли что-либо в наличии, например условный TTL или любой другой способ сделать itin mongodb.

Я хочу, чтобы создать TTL, который работает как:

if(requestType!=2 and createdDate < -2days) 
delete row; 

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

EDIT: Я решил это, используя те же значения для scheduleDate и requestDate в случае запланированных писем.

ответ

5

Я бы добавил еще одно поле. Это не так много данных:

{ 
'_id' : 123456789, 
'createdDate' '<date when mail was sent or the request was created>', 
'scheduledDate' : '<time for which mail is scheduled>' 
'expires': '<Date or NULL>' 
} 

Добавить индекс TTL в 0 секунд до поля expires. Не добавляйте TTL к другим датам.

Следующие примеров в Мангусте (ОРМ для узла), но идеи должны перенести на любую основе вы используете:

Значение по умолчанию

Вы можете добавить значение по умолчанию в истекает поле со значением «дата создания + 2 дня».

{ 
    type: Date, 
    default: function() { 
    return new Date(Date.now() + 1000*60*60*24*2); 
    } 
} 

Другой истекает срок для ваших запланированных задач

Просто установите дату в явном виде:

myNewDocument.expires = new Date(scheduled + ...); 

Или изменить функцию, которая устанавливает значение по умолчанию:

function() { 
    if(this.get("type") === 2) { 
     return scheduled_date_plus_2_days; 
    } else { 
     return created_date_plus_2_days; 
    } 
} 

Нет срок действия недействителен

Установите поле в NULL:

myNewDocument.expires = null; 

Таким образом, у вас есть возможность выбрать другой истечение для обычных писем, важных писем, запланированных из них, и т.д. Если вы на время, вы может даже установить для поля expires значение NULL, чтобы отменить автоматическое удаление.
Единственное предостережение в том, что если вы измените запланированное время, вам нужно обновить поле expires.

+0

Итак, вы должны добавить индекс, необходимый для его истечения [(Документы)] (https://docs.mongodb.com/manual/tutorial/expire-data/#expire-documents-at-a-specific-clock-time)? 'db.emails.createIndex ({" expires ": 1}, {expireAfterSeconds: 0})' – luckydonald

+1

Это выглядит корректно для меня: в вашем случае документ будет удален, когда текущая дата будет значением 'expires' поле (дайте или займите минутку). – RikkusRukkus

0

Вы можете просто создать индекс TTL на scheduledDate, если значение равно нулю, оно не будет удалено. Согласно documentation, если индексированное поле в документе не является датой или массивом, в котором хранятся значения (даты) даты, документ не истекает.

Использование Монго 3,2 Я проверил это действительно так, используя эту коллекцию тест:

db.data.drop() 
db.data.save({scheduledDate: 0}) 
db.data.save({scheduledDate: new Date()}) 
db.data.save({scheduledDate: new Date()}) 
db.data.createIndex({ "scheduledDate": 1 }, { expireAfterSeconds:1}) 

При использовании этой коллекции все new Date() записи удаляются, в то время как первая запись с нулевым значением остается

+0

, но если есть еще один индекс TTL для 'createdDate', то также он не будет истек? – kadamb

+0

Вы только хотите добавить индекс TTL в 'schedDate' с идеей, что вам нужно удалить записи только после того, как они были успешно отправлены, иначе посмотрите на решение RikkusRikkus, – Jaco