繁体   English   中英

使用Mongoose将元素添加到MongoDB中的数组

[英]Add elements to an array in MongoDB using Mongoose

首先,让我开始提供我的MongoDB模式。

showTitle: String,
seasons: [{
  seasonNumber: String,
  episodes: [{
      episodeNumber: String,
      episodeTitle: String,
      episodeSynopsis: String
            }]  
         }]

此收藏集的基本思想是存储电视节目详细信息。 电视节目可以包含多个季节,每个季节包含多个情节。

我允许用户在客户端添加其他季节(仅seasonNumber)。 这会将一个值传递给服务器端。 当我在服务器端使用console.log时,该部分可以正常工作,因为我可以查看值(一个字符串)。

在这里,我的API调用此特定函数。

function saveReport(err, res, count, seasonId, seasonDetails)
{
  if(count == 0) //if 0 means not exist, so can add into DB
  {
    Show.update({_id: seasonId},{$push: {seasons:{seasonNumber: [seasonDetails]}}}, {upsert:true}, function(err, result)
    {
      console.log(result);
      res.json(result);
    });
  }
  else
  {
    res.json("TV Season already exists in MongoDB");
  }
}

module.exports.seasonsCreate = function(req, res)
{
  console.log("Calling the seasonsCreate function");
  var seasonId = req.params.id;
  var seasonDetails = req.body.season; //season number as a string(intended)

 //finding a specific showing using the id passed as parameter
 //$elemMatch is used to check if season number exists
 //using count to determine
  Show.findOne({_id: req.params.id, seasons: {$elemMatch: {seasonNumber: req.body.season}}}).count(function(err, count)
  {
    saveReport(err, res, count, seasonId, seasonDetails);
  });
}

我手动(使用MongoDB命令)将两个季节添加到MongoDB中。 第1季和第2季各有2集。 但是,当我尝试通过客户端添加第3集时,没有任何反应。 返回的确切结果是这样的:

对象{ok:0,n:0,nModified:0}

在使用类似方法之前,我已经完成了更新。 但是,我有点不满意,因为这一次我有嵌套数组,而不仅仅是对象。 我还尝试了几种组合:

  • 有/无推
  • 有/无设置
  • 有/没有upsert

我很确定问题是我更新数据库的方式。 希望有人可以在这里阐明。 谢谢 !!

p / s:我正在使用最新版本的Mongoose。

由于我感觉到有人告诉您.find()然后再将.save()发出危险的坏建议,因此,我将解释“平整”数据以避免嵌套数组问题的基本情况。

嵌套数组会遇到一个问题,您需要使用该$运算符来匹配所需数组元素的索引以进行更新,该操作只能引用“外部”数组元素。 虽然可以识别该元素并将其“推入”该元素的内部数组可能会很好,但是如果要更新该内部元素,就无法获得内部元素的位置。

因此,这里的想法是“不嵌套数组”和结构,以便您实际上可以在可用约束内进行有效更新。

更好的结构是:

showTitle: String,
episodes: [{
  seasonNumber: String,
  episodeNumber: String,
  episodeTitle: String,
  episodeSynopsis: String
}]

现在,您在这里并没有真正丢失任何内容,它只是数据的一点额外重复,但代价很小。

要添加到数组:

Show.update({ "_id": showId },{ "$push": { "episodes": episodeData } },callback)

要更新元素:

Show.update(
    { 
       "_id": showId,
       "episodes": { 
           "$elemMatch": {
               "seasonNumber": season,
               "episodeNumber": episode
           }
       }
    },
    { "$set": { "episodes.$": episodeData } },
    callback
)

甚至:

Show.update(
    { 
       "_id": showId,
       "episodes": { 
           "$elemMatch": {
               "seasonNumber": season,
               "episodeNumber": episode
           }
       }
    },
    { "$set": { "episodes.$.episodeSynopsis": synopis } },
    callback
)

如果您只想要一个季节的所有剧集:

Show.aggregate(
    [
        { "$match": { "_id": showId, "epsisodes.seasonNumber": seasonNumber } },
        { "$redact": {
            "if": { 
                "$eq": [
                    { "$IfNull": [ "$seasonNumber", seasonNumber ] } },
                    seasonNumber
                ]
            },
            "then": "$DESCEND",
            "else": "$PRUNE"
        }}
    ],
    callback
)

当查询中返回数组时,它将从数组中删除所有不匹配的条目。

因此,您几乎可以做任何您想做的事情,而不必大惊小怪地更改数据存储,并且原子更新不会因其他操作而将数据更改为意外状态而遇到其他问题,否则会带来风险。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM