Mongoose findOneAndUpdate没有返回原始Mongo响应

时间:2017-05-15 21:10:16

标签: node.js mongodb mongoose

我试图确定是否在我的findOneAndUpdate操作中找到了该文档。如果它不是,我返回404未找到错误。我想我会使用" passRawValue"选项Mongoose提供并检查原始值 - 如果raw未定义,我知道找不到doc。

但无论是否找到doc,我的原始值都是未定义的。我通过运行一个简单的" findOne"来验证我在查询时尝试更新的文档是在数据库中。在更新之前查询。我哪里错了?

let updateItemById = (userId, itemId, params, cb) => {

//this finds and prints the document I'm testing with -- I know its in the DB

  // Item.findOne({ "_id" : itemId, ownerId: userId }, (err, doc) => {
  //   if (doc) {
  //     console.log("This is the doc: ", doc);
  //   }
  // });

  Item.findOneAndUpdate({ "_id" : itemId, ownerId: userId },
    {
      $set: {
        params
      }
    }, { runValidators: 1, passRawResult: true}, (err, doc, raw) => {

    if (err) {
      //winston.log
      return cb(ErrorTypes.serverError(), false);
    }
    else if (raw) {
      return cb(null, true);
    }
    else {
      return cb(ErrorTypes.notFound(), false);
    }

  });
} 

2 个答案:

答案 0 :(得分:1)

您好我有预感,您传递的params具有数据库中文档中不存在的属性。在这种情况下,没有任何内容被修改,因此db不会将raw作为第三个参数返回。

<强>更新

所以我做了一些自己的测试,我看到如果我们传递option strict:false,那么你的代码应该按预期工作。因此,您的选项部分将如下所示

    { runValidators: 1, passRawResult: true, strict: false, new:true}

<强>解释

Mongoose的strict option默认为true。它确保在架构中定义要更新的值。因此,当我们提供严格为false的选项时,如[mongoose documentation](http://mongoosejs.com/docs/api.html#query_Query-findOneAndUpdate)中所述,我们可以用新字段实现更新文档。

我还添加了new:true选项,它会返回更新的文档。

<强> P.S。

我想补充一下,因为我们的 upsert 为false,这意味着当找不到匹配项时它不会插入新文档,它会为doc返回null,而你可以简单地检查一下。你为什么要检查原始?这有什么特别的原因吗?

答案 1 :(得分:0)

我知道已经有一段时间了,但是我在这里遇到了同样的问题,所以我决定留下一个可能对其他人有帮助的答案。

通过检查回调函数中的 doc 参数是否为空,我能够检查 findOneAndUpdate()方法是否找到了文档:

async Update(request: Request, response: Response) {
  const productId = request.params.id;

  const query = { _id: productId };
  const options = { new: true };

  try {
    await Product.findOneAndUpdate(query, request.body, options, (err, doc, res) => {
      if (doc === null)
        return response.status(404).send({
          error: 'Product not found'
        })
      return response.status(204).send();
    });
  }
  catch (err) {
    return response.status(400).send({
      error: 'Product update failed'
    });
  }
}