#mongodb
Вопрос:
Я создал веб-скребок для хранения данных в течение недели, чтобы найти тенденцию. Я написал код для удаления данных более недели назад при каждом запуске скрипта. Однако данные все еще хранятся более недели назад, есть ли для этого причина?»
пример данных монеты, созданных в поле, выглядит следующим образом
"createdAt": {
"$date": "2021-08-11T10:55:19.843Z"
},
coinSchema.statics.deleteOldData = async function () {
// delete old data
const today = new Date(Date.now());
today.setHours(0, 0, 0, 0);
const oneWeekAgo = new Date(Date.now());
const pastDate = oneWeekAgo.getDate() - 7;
oneWeekAgo.setDate(pastDate);
await this.deleteMany({
createdAt: {
$gte: today,
}, // 16 < 17 wont delete it prevent duplicates for one day
});
await this.deleteMany({
createdAt: {
$lt: pastDate,
}, // from 1 week ago
});
};
в сценарии у меня есть этот запуск
async function main() {
await Coin.deleteOldData();
моя модель монеты выглядит так :
const coinSchema = mongoose.Schema(
{
specNo: {
type: String,
required: true,
},
coinName: {
type: String,
required: true,
},
fullName: {
type: String,
required: false,
},
category: {
type: String,
},
array: [
{
GradeName: String,
PopulationCount: String,
trend: { type: Number, default: 0 },
},
],
},
{
timestamps: true,
}
);
Комментарии:
1. Как выглядят ваши данные сбора? Возможно, вы храните значения дат в виде строки (что является недостатком дизайна) вместо правильных
Date
объектов.2. При работе с датами я рекомендую использовать moment.js библиотека . Было бы
createdAt: { $lt: moment().startOf('day').subtract(7, 'day').toDate() }
иcreatedAt: { $gte: moment().startOf('day').toDate() }
3. «Дата создания»: { «дата$»: «2021-08-11T10:55:19.843 Z» },
Ответ №1:
Вы смотрели на индекс на основе TTL? https://docs.mongodb.com/manual/core/index-ttl/
Это хороший способ очистки старых данных, когда об этом заботится сама БД. В вашем случае 7 дней-это 604800 секунд, поэтому, если вы создадите индекс на createdAt с ttl 604800, то у вас все должно быть хорошо!
db.collection.createIndex( { "createdAt ": 1 }, { expireAfterSeconds: 604800 } )
Комментарии:
1. Должен ли я включить это в модель? или в моем веб-скребке?
2. этот индекс создается на сервере БД. обычно администратор базы данных создавал индексы. Кроме того, это одноразовая настройка. как только вы настроите индекс на основе TTL, все готово!
Ответ №2:
Ты можешь сделать это вот так:
db.collection.deleteMany({
createdAt: { $lte: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString() },
})