使用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更新,否则就会将数据转换为意外状态。