首先,让我首先提供我的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}
我在使用类似方法之前已完成更新。但是,我有点被抛弃,因为这次我有嵌套数组而不仅仅是对象。我也尝试了几种组合:
我很确定问题是我更新数据库的方式。希望有人能在这里说清楚。谢谢!!
p / s:我使用的是Mongoose的最新版本。
答案 0 :(得分:4)
由于我感觉到人们告诉您.find()
数据然后.save()
发出危险的错误建议,我会解释"展平&#34的基本情况;数据以避免嵌套数组问题。
嵌套数组遇到的问题是,您需要使用positional $
operator来匹配要更新的所需数组元素的索引,只能引用"外部"数组元素。虽然这可能很好地识别该元素和"推"对于该元素的内部数组,如果您想更新该内部元素,则无法获取内部元素的位置。
所以这里的想法是“不是嵌套数组"”和结构,这样你就可以在可用的约束内实际有效地更新。
更好的结构是:
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
)
在查询中返回时,会从数组中剔除任何不匹配的条目。
因此,您可以在更改数据存储时轻松完成所需的一切,并使用原子更新,这些更新不会遇到其他操作的问题,从而将数据转换为意外状态,因为您可以从其中冒险。