【问题标题】:Updating a record with mongoose使用 mongoose 更新记录
【发布时间】:2017-03-12 20:54:39
【问题描述】:

我正在学习 MEAN 堆栈应用程序,并且正在开发一个电视监视列表应用程序。我在模型中没有季节字段的情况下成功构建了 api。现在我想添加这个字段,以便用户可以将季节和剧集添加到文档中,以跟踪他们观看过的剧集。通过反复试验,我找到了我将在 mongo shell 中使用来更新剧集对象中的字段的查询,但我无法创建正确的语法来在我的路由中使用 mongoose 执行此操作。有人可以在 router.put 上查看我的 tele.js 路由并告诉我出了什么问题。

模型 (TVSeries.js)

var mongoose = require('mongoose')
var Schema = mongoose.Schema

var tvSchema = new Schema({
  title:String,
  poster:String,
  rated:String,
  program_time:Number,
  network:String,
  airs_on:[],
  streams_on:[],
  genre:[],
  seasons:[
            season_number:Number,
            episodes:[
                       {
                         episode_number:Number,
                         title:String,
                         watched:Boolean
                       }
                     ]
          ]
}, {collection: 'tvShows'});

module.exports = mongoose.model('tv', tvSchema);

路线(tele.js)

var express = require('express');
var router = express.Router();
var TV = require('../models/TVSeries.js');

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Your Watchlist' });
});

router.get('/api/shows/:id/seasons', function(req, res){
    TV.findById(req.params.id, 'seasons', function(err, data){
        if(err){console.log(err)}
        else{res.json(data)};
    });
});

router.put('/api/shows/:id/seasons/:sid', function(req, res){
    var setField = {
        seasons:[
            {
                season_number:req.params.sid,
                episodes:[
                    req.body
                    ]
            }
        ]
    }

    TV.findOneAndUpdate({"_id":req.params.id}, setField, {upsert:true}, function(err, results){
       if(err){console.log(err)}
       else{
           console.log(setField);
           res.json(results)
       }
    })
})

module.exports = router;

Mongo Shell 命令

db.tvShows.update({"_id":ObjectId('######################')},{$set: {'seasons.1.episodes.1.title':'This is my title change'}})

【问题讨论】:

  • 仍在努力寻找解决方案。尝试了更接近的 findOneAndUpdate。我现在可以更新剧集对象,但不仅仅是将另一个对象添加到数组中,而是删除所有其他对象并将其替换为 req.body。有谁知道这个问题的解决方案吗?

标签: node.js mongodb express mongoose crud


【解决方案1】:

您可以使用&elementMatch 在数组中查找想要的季节,并且在setField 对象中您可以使用位置$ 运算符来标识查询中匹配的元素。

问题是如果它没有找到任何匹配season_number 的季节,文档将不会被更新。在这种情况下,您可以设置另一个更新查询以将本季添加到 seasons 数组中。

router.put('/api/shows/:id/seasons/:sid', function(req, res){

  var query = {
    "_id": req.params.id,
    "seasons": { 
      $elemMatch: { 
        "season_number": req.params.sid 
      } 
    }
  }

  var setField = {
    $addToSet: {
      "seasons.$.episodes": req.body
    }
  }

  TV.findOneAndUpdate(query, setField, {upsert:true}, function(err, results){
    if (err && err.code == 16836) { // no document was matched
      var season = {
        "season_number": req.params.sid
        "episodes": [ req.body]
      }
      TV.findOneAndUpdate({"_id": req.params.id}, {$push: {"seasons": season}} , function(err, result) {
          console.log("Inserted document in array");
          res.json(result)
      }); 
    }
    else if (err){
       console.log(err);
       res.status(500).send('Something wrong!');
    }
    else {
       console.log(setField);
       res.json(results)
    }
  })
})

可以看到here一些mongodb数组操作符。

希望对你有帮助。

【讨论】:

  • 我在想 $push ,这与我希望做的非常接近。但这正在创建这个“季节”:[{Season 1 Object Episode 1},{Season 1 Object Episode 2}]。我希望我能把它放到这个“季节”:[{“season_number”:1,情节:[{Episodes Object},{Episodes Object}]。因此,从您的示例中,我尝试创建它,以便如果 :sid 为 1,那么它将进入季节数组索引 0 集数组以像这样推送 req.body 。 var setExpression = 'seasons.'+(req.params.sid-1)+'.episodes'; var setField = {$push: {setExpression:req.body}} 但这是返回错误 '$push' is empty...
  • 谢谢你这确实有效。我将不得不阅读 $elemMatch 和 $addtoSet 因为我不确定他们在做什么。我确实有一个关于 mongoose .update 的问题。使用邮递员添加新的季节编号时它会挂起。所以我在最后添加了一个 res.json 。但我不确定它什么时候会到达 else 部分……是在我添加一个已经与已创建的 season_number 匹配的剧集对象时吗?
  • @RawleJugal 我更新了答案。挂起请求的问题是它在第二次更新时没有响应。
  • 是的,当 db 已经有一个赛季时,它会到达 else
  • 感谢您在理解 Lucas 方面提供的所有帮助。因为嵌入了季节和剧集,所以我似乎必须对 put 路线内的剧集执行所有 CRUD 操作,以及其他几个 if 语句检查该剧集是否已经存在并且我需要更新或检查空的 req.body 表示我想删除一个剧集。这让我质疑我是否应该让季节和剧集成为单独的集合,并有自己的模式来做杂事。或者可能删除季节数组并使用 season_number 字段制作一组剧集。有意见吗?
猜你喜欢
  • 2013-06-19
  • 1970-01-01
  • 1970-01-01
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多