Как использовать сравнение в фильтре Mongodb

Контекст: я создаю веб-сайт, на котором пользователи могут создавать учетные записи. Затем они должны подтвердить свои учетные записи, открыв электронное письмо с подтверждением. Я использую Node.js и Mongodb.

Что я пытаюсь сделать: если пользователь не подтвердил свою учетную запись за последние 24 часа, удалите свою учетную запись.

Пример аккаунта для удаления:

{
    created: 3294038434,
    notValid: "dslafjksdfkj"
}

Пример аккаунта, который нельзя удалять:

{
    created: 203498324,
    notValid: false
}

Ключ created сохраняет дату как number. Если notValid равно false, то учетная запись подтверждена. Если notValid является string, то учетная запись еще не проверена, и строка представляет собой код подтверждения.

Есть ли способ для пользователя deleteMany() и иметь что-то вроде этого фильтра?

{
   Date.now() > created + 1000 * 60 * 60 * 24 && typeof(notValid) == "string"
}

Я знаю, что могу просто прочитать каждого пользователя, а затем выполнить логику, но есть ли способ просто заставить mongodb выполнять логику/фильтр за меня?


person programmerRaj    schedule 27.11.2019    source источник


Ответы (1)


Работая из оболочки mongo, возьмем эти три входных документа:

{ "_id" : 2, "created" : 1574831443519, "notValid" : "dslafjksdfkj-abc" }
{ "_id" : 3, "created" : 1574817043519, "notValid" : true }
{ "_id" : 1, "created" : 1574817043519, "notValid" : "abc-111" }

Создайте фильтр для запроса, чтобы выбрать документы с критериями:

Date.now() > created + 1000 * 60 * 60 * 24 && typeof(notValid) == "строка"

var queryFilter = { $cond: {
                       if: { $and: [
                                     { $eq: [ { $type: "$notValid"}, "string" ] },
                                     { $gt: [ new Date(), { $toDate: { $add: [ "$created", 86400000 ] } } ] }
                                    ]
                            },
                        then: true,
                        else: false
                     }
};

Запрос db.colln.find( { $expr: { $eq: [ queryFilter, true ] } } ) возвращает документ:

{ "_id" : 1, "created" : 1574817043519, "notValid" : "abc-111" }

Применение фильтра запроса для удаления совпадающих документов:

db.colln.deleteMany( { $expr: { $eq: [ queryFilter,  true ] } } );

Удаляет документ с _id : 1.

Обратите внимание, что в поле created дата/время указаны в миллисекундах. В то время, когда я тестировал, дата/время и соответствующие миллисекунды: ISODate("2019-11-28T03:20:03.835Z") и 1574911160308.

person prasad_    schedule 28.11.2019
comment
Спасибо, это сработало. Не могли бы вы вставить ссылку на документацию по таким запросам? (При наличии есть документации) - person programmerRaj; 01.12.2019
comment
Проблема заключалась в сравнении дат, а ввод даты был в виде числа в миллисекундах. Сравнение дат выполняется по двум значениям: новая дата() возвращает текущую дату как объект Date. $toDate — это оператор агрегации, и это преобразует значение (строку или число) в дату; он принимает входной параметр, в данном случае число created+86400000. - person prasad_; 02.12.2019