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

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

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

这个collections的基本思路是存储电视节目的细节。 电视节目可以包含多个季节,每个季节包含多个节目。

我允许用户在客户端添加更多季节(仅seasonNumber)。 这将传递一个值给服务器端。 这部分工作正常,因为我可以查看值,一个string,当我console.log在我的服务器端。

在这里,我的API调用这个特定的function。

 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集。 但是,当我尝试通过客户端添加第三集时,没有任何反应。 返回的确切结果是这样的:

对象{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 ) 

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

因此,您可以在改变数据存储的同时,用一点小小的功夫来做所有事情,而primefaces更新不会出现其他操作出现问题的primefaces更新,否则就会将数据转换为意外状态。