如何在猫鼬pre updateOne钩子中获取文档_id?

时间:2018-10-15 09:00:10

标签: node.js mongodb mongoose pre

我为模型执行了updateOne,并在方案中预先添加了updateOne钩子,如下所示:

const schema = new mongoose.Schema({ name: { type: String } });
schema.pre('updateOne', async function() {
  fs.writeFileSync('./query.json', stringify(this, null, 2), 'utf-8');
});
const Model = mongoose.model('Model', schema);
let res = await Model.create({
  name: "I'll be updated soon",
});
console.log(res.name, res._id);
await Model.updateOne(
  ({ _id: res._id }, { $set: { name: 'I was updated!' } }),
);

但是我找不到任何方法来获取当前正在更新的文档ID 这是一个有效的测试脚本: https://gist.github.com/YuriGor/04192230fb63542c1af5ff5c19b3a724

注意:在现实生活中,这将在mongoose插件内发生,所以我不能像在此脚本中那样将doc _id保存到父范围内的某个变量中。

2 个答案:

答案 0 :(得分:1)

非常感谢vkarpov15 他在我的代码中发现了一个错字:在updateOne调用中加了双括号,这就是查询中没有条件的原因

因此正确的代码应如下所示:

const schema = new mongoose.Schema({ name: { type: String } });
schema.pre('updateOne', async function() {
  console.log('query criteria',this.getQuery());// { _id: 5bc8d61f28c8fc16a7ce9338 }
  console.log(this._update);// { '$set': { name: 'I was updated!' } }
  console.log(this._conditions);
});
const Model = mongoose.model('Model', schema);
let res = await Model.create({
  name: "I'll be updated soon",
});
console.log(res.name, res._id);
await Model.updateOne(
  { _id: res._id }, { $set: { name: 'I was updated!' } }
);

答案 1 :(得分:0)

当需要在MiddleWare中更新文档时,您需要使用findOneAndUpdate.post中间件。

  

使用猫鼬5.3.3测试的工作示例

定义挂钩

productSchema.post('findOneAndUpdate', function(doc) {
    console.log('post-updateOne! Writing this to JSON file..',doc._id); //here you got updated doc.
    console.log(JSON.stringify(doc));
  });

更新文档

Product.findOneAndUpdate({ _id: "5bc42563009dd527f3c058fe"}, { $set: { title: 'I was!' } }, {new: true}).then((res)=>{
  console.log('succes');
  console.log(res);
 })

您必须更改代码,例如:

schema.post('findOneAndUpdate', function(doc) {
   //here get doc
});

另外,用Model.updateOne({})更改您的Model.findOneAndUpdate({})