Reputation: 4691
I'm trying to move a document to another collection in MongoDB based on this approach Saving Mongoose object into two collections.
In the example he shows how to create two new objects. My goal is to move it from one collection to another.
To be a bit more specific: In a document I have a list of tasks which eventually get completed and should then be moved inside this document to another array. However I need to be able to query all the unfinished and this should be possible with two collections.
Upvotes: 7
Views: 11517
Reputation: 716
The solution above is correct but will be too slow for a massive amount of documents if "awaited" for remove
and save
, or may flood an instance if it doesn't.
Here's a simple alteration for semi-bulk parallel action
// use "strict: false" so we won't have to declare schema in the script
const First = mongoose.model('ActionsNewCollection', new mongoose.Schema({}, {collection: `first`, strict: false}))
const Second = mongoose.model('ActionsNewCollection', new mongoose.Schema({}, {collection: `second`, strict: false}))
const cursor = First.find({}).cursor();
let moved_actions = []
let moved_actions_ids = []
for (let action = await cursor.next(); action != null; action = await cursor.next()) {
let actions_json = action.toJSON()
moved_actions.push(actions_json)
moved_actions_ids.push(actions_json._id)
// Every 100, stop and wait for them to be done
if (moved_actions.length > 300) {
let inserts = [Second.insertMany(moved_actions.slice(0,100)), Second.insertMany(moved_actions.slice(100,200)), Second.insertMany(moved_actions.slice(200))]
let deletes = [First.deleteMany({_id: { $in: moved_actions_ids.slice(0,100)}}), First.deleteMany({_id: { $in: moved_actions_ids.slice(100,200)}}), First.deleteMany({_id: { $in: moved_actions_ids.slice(200)}})]
await Promise.all(inserts)
await Promise.all(deletes)
moved_actions = []
moved_actions_ids = []
}
}
Upvotes: 0
Reputation: 4691
So you have to register the Schema twice
let ChangeSchema = new Schema({
title: String,
version: Number
})
mongoose.model('First', ChangeSchema)
mongoose.model('Second', ChangeSchema)
Then you can swap 'em like this
mongoose.model('First').findOne({ _id: id }, function(err, result) {
let swap = new (mongoose.model('Second'))(result.toJSON()) //or result.toObject
/* you could set a new id
swap._id = mongoose.Types.ObjectId()
swap.isNew = true
*/
result.remove()
swap.save()
// swap is now in a better place
})
Upvotes: 15