【问题标题】:mongoose push into array not working猫鼬推入阵列不起作用
【发布时间】:2018-06-02 22:39:08
【问题描述】:

我正在使用 Nodejs 在后端和 MongoDB 作为数据库来制作图书馆管理应用程序。它是一个简单的 express 服务器,使用 mongoose 库。必须发行一本书的客户发送一个 POST 请求,并将其记录添加到数据库中。这是我的日志模型:

var Logs = mongoose.model('Logs', {


bookid: {
    type: Number,
    required: true,
    minlength: 1
  },
  status: {
    type: String,
    required: true,
    minlength: 1,
    trim: true
  },
  details: [{
    issuedby: {
      type: String,
      trim: true
    },
    issuedate: {
      type: Date,
    },
    returndate: {
      type: Date
    }
  }]
});  

现在当收到 POST 请求时,我尝试将 book 的“status”从“Available”更改为“Issued”,并在“details”字段中添加客户的记录。这是代码:

app.post('/issueBook', (req,res) => {
  console.log(req.body);
  Logs.findOne({bookid: req.body.bookid}).then((doc) => {
    if(doc.status == "Available"){
      var detail = {};
      detail.issuedby = req.body.issueTo;
      detail.issuedate = new Date();
      Logs.findOneAndUpdate({bookid: req.body.bookid}, {$set: {status:"Issued"}}, {$push: {details:detail}}, {upsert: true}, function(err,doc) {
        if(err) {
          console.log("Couldn't issue");
          res.status(400).send(err);
        } else{
          res.send("OK");
        }
      });
    } else{
      res.send({
        status: "Error",
        reason: "Book already issued !"
      });
    }
  }, (e) => {
    res.send({
      status: "Error",
      reason: "Invalid Book ID !"
    });
  });
});  

当我发送这个 POST 请求时服务器崩溃。检查数据库时,我发现“状态”字段成功地从“可用”更改为“已发布”,但“详细信息”中没有插入记录。我的查询有问题吗?请对我的代码提出更正建议。
这是崩溃时的错误 sn-p:

终端中的错误如下所示:

【问题讨论】:

  • 所有更新修饰符都放在单个文档中。类似Logs.findOneAndUpdate({bookid: req.body.bookid}, {$set: {status:"Issued"}, $push: {details:detail}}, {upsert: true}...

标签: arrays node.js mongodb mongoose


【解决方案1】:

更改此代码


Logs.findOneAndUpdate({bookid: req.body.bookid}, {$set: {status:"Issued"}}, {$push: {details:detail}}, {upsert: true}, function(err,doc)

到这里


Logs.findOneAndUpdate({bookid: req.body.bookid}, {$set: {status:"Issued"}}, {$push: {details:detail}}, {upsert: true}).then((result) => {
  console.log(result)
}.catch((error) => {
  console.log(error)
}

请告诉我console.log(error) 将返回什么,根据该错误消息,我可以给你一个最终答案。

更新


您可以尝试以下代码块。此代码将查找具有您将在 request.body 中提供的 Id 且状态为可用的日志。如果此查询找到日志,它将在响应中发回。如果没有,它会抛出一个找不到它的错误。

app.post('/api/issueBooking', (request, response) => {

Log.findOneAndUpdate({
         bookid: request.body.bookid,
         status: "Available"
       }, {
         $set: {
           status: "Issued"
         }
       }, {
         $push: {
           "details": {
             issueby: "issueByHere",
             issuedate: "issueDateHere",
             returndate: "returnDateHere"
           }
         },
         {
           upsert: true
         }).then((log) => {

         if (!log) {
           return Promise.reject({
             status_code: 404,
             message: "Log not found."
           })
         }

         response.status(200).send("OK");

       }).catch((error) => {
         response.status(error.status_code).send(error.message);
      })
  });

【讨论】:

  • 错误提示 - TypeError: cannot read property then of undefined
  • 没问题的朋友!
  • upsert 已弃用为新的。所以新语法将是 { new: true }
【解决方案2】:

该错误可能是因为您没有正确更新详细信息字段。正如我在您的架构中看到的那样,您已将details 定义为[],但您正在使用对象{} 对其进行更新。你必须解决这个问题。但我也认为你可以使脚本更好。 声明:

Logs.findOneAndUpdate({bookid: req.body.bookid}, {$set: {status:"Issued"}}, {$push: {details:detail}}, {upsert: true}, function(err,doc) {

似乎是多余的。您已经拥有需要更新的文档:

Logs.findOne({bookid: req.body.bookid}).then((doc) => {

在你得到这个doc 之后,只需修改你想要的类似于 javascript 对象的任何内容,然后执行doc.save

【讨论】:

  • 我在查询中使用 push 将对象推送到 details 数组中。您提出的更新我已经拥有的文档的建议对我有用。为此非常感谢。我的问题是我看到人们在对他们有用的查询中使用 setpush 。但是当我使用它们时,我得到了一个错误。我只是想在这种情况下使用 push 和 set 来查看正确的查询以用于学习目的。
  • @ShouryaSharma 我认为您对 set 和 push 的使用很好,但您正在尝试使用 {} 类型的对象更新 [] 类型的对象。假设您有任何模式检查到位,这应该会按预期使数据库崩溃。此外,如果您发现答案有用,我们将不胜感激,因为这是对 SO 的唯一激励。不客气:D
  • 我投了赞成票,但我的声誉低于 15,它没有显示在答案中。
猜你喜欢
  • 2017-09-16
  • 2015-10-22
  • 2023-03-03
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
  • 2018-12-30
  • 2017-06-02
  • 2018-05-14
相关资源
最近更新 更多