【发布时间】:2016-11-07 04:24:30
【问题描述】:
我正在尝试基于这种方法 Saving Mongoose object into two collections 将文档移动到 MongoDB 中的另一个集合。
在示例中,他展示了如何创建两个新对象。我的目标是将它从一个集合移到另一个集合。
更具体一点:在一个文档中,我有一个任务列表,这些任务最终会完成,然后应该在这个文档中移动到另一个数组。但是我需要能够查询所有未完成的内容,这应该可以通过两个集合来实现。
【问题讨论】:
我正在尝试基于这种方法 Saving Mongoose object into two collections 将文档移动到 MongoDB 中的另一个集合。
在示例中,他展示了如何创建两个新对象。我的目标是将它从一个集合移到另一个集合。
更具体一点:在一个文档中,我有一个任务列表,这些任务最终会完成,然后应该在这个文档中移动到另一个数组。但是我需要能够查询所有未完成的内容,这应该可以通过两个集合来实现。
【问题讨论】:
所以你必须注册 Schema 两次
let ChangeSchema = new Schema({
title: String,
version: Number
})
mongoose.model('First', ChangeSchema)
mongoose.model('Second', ChangeSchema)
然后你可以像这样交换它们
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
})
【讨论】:
VersionError: No matching document found for id "58b1512b8f361b717254fa59" 几乎毫无意义我发现如果我先手动将文档注入到集合中,那么我就不会收到这样的错误,这让我相信我错过了关于 id 部分的步骤。谁能为这个解决方案添加更多细节?
No matching document found for id "58b1512b8f361b717254fa59" 告诉你没有文件有他的id。
_id 设置为String 类型,否则猫鼬会期望ObjectId。如果您的 id 是一个字符串并且 mongoose 需要一个对象 id,请使用 mongoose.Types.ObjectId(id),如有必要,请事先使用 mongoose.Types.ObjectId.isValid(id) 进行验证
objectId 类型的参数。有一种方法可以通过ID mongoose.model.findById(_id)查找文档,这将返回所需的文档
上述解决方案是正确的,但如果“等待”remove 和 save,则对于大量文档来说会太慢,否则可能会淹没实例。
这是半批量并行动作的简单改动
// 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 = []
}
}
【讨论】: