【问题标题】:Mongoose findOneAndUpdate not returning raw Mongo responseMongoose findOneAndUpdate 不返回原始 Mongo 响应
【发布时间】:2017-10-14 19:00:30
【问题描述】:

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

但是,无论是否找到文档,我的原始值都是未定义的。通过在更新前运行一个简单的“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);
    }

  });
} 

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

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

    更新:

    所以我自己做了一些测试,我发现如果我们通过选项 strict:false 那么你的代码应该能按预期工作。所以您的选项部分将如下所示

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

    说明:

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

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

    附言

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

    【讨论】:

    • 哦,如果是这样的话,应该采取什么方法呢?我的 Item 对象具有可以在更新中设置的可选属性,所以这是我的一个用例。
    • 所以架构中没有定义可选属性?
    • 嘿检查了 - 感谢您的回复!基本上我只是想知道服务器是否找到了与要更新的查询匹配的对象。如果没有,我想返回 404 not found 给客户——因此我首先检查原始文件是否找到(并更新)了任何文档
    • @DavidTamrazov 添加“strict:false”选项对你有用吗?
    • 不幸的是,我设置的属性都在模式中定义,实际上我非常依赖模型的完整性。现在我已经决定简单地找到文档 --> 手动更新 --> 保存
    【解决方案2】:

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

    我可以通过检查回调函数上的 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'
        });
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-02-07
      • 2014-09-26
      • 2016-01-26
      • 2019-05-01
      • 2021-01-02
      • 1970-01-01
      • 2011-12-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多