Based on Mat Wills answer here comes the Typescript version thats fully working. It's based on NestJS. Following is the implementation from a service class:
...
async moveDocuments(
sourceCollection: Model<any>,
targetCollection: Model<any>,
filter: any
) {
const sourceDocs = await sourceCollection.find(filter)
console.log(sourceDocs.length)
console.log(
`Moving ${await sourceDocs.length} documents from ${
sourceCollection.modelName
} to ${targetCollection.modelName}`
)
const idsOfCopiedDocs = await this.insertDocuments(
targetCollection,
sourceDocs
).catch((err) => {
return Promise.reject(err)
})
const targetDocs = await sourceCollection.find({
_id: { $in: idsOfCopiedDocs },
})
await this.deleteDocuments(sourceCollection, targetDocs).catch(
(err) => {
return Promise.reject(err)
}
)
return Promise.resolve('Cleanups done!')
}
private async insertDocuments(
collection: Model<any>,
documents: Document[]
) {
const insertedIds = []
const bulkWrites = []
await documents.forEach((doc) => {
const { _id } = doc
insertedIds.push(_id)
bulkWrites.push({
replaceOne: {
filter: { _id },
replacement: doc,
upsert: true,
},
})
})
if (bulkWrites.length)
await collection.bulkWrite(bulkWrites, { ordered: false })
return insertedIds
}
private async deleteDocuments(
collection: Model<any>,
documents: Document[]
) {
const bulkWrites = []
await documents.forEach(({ _id }) => {
bulkWrites.push({
deleteOne: {
filter: { _id },
},
})
})
if (bulkWrites.length)
await collection.bulkWrite(bulkWrites, { ordered: false })
}
And thats how you might call the service with the help of dayjs:
...
const now = dayjs()
const xMonthBeforeNow = now.subtract(5, 'months')
const filter = {
createdAt: {
$lte: date,
}
},
const cleanupResult = await this.cleaningService.moveDocuments(
this.anyModel,
this.anyModelOld,
filter
)
...