寫博客的時候有一個這樣的業務,一個標簽集合和一個文章集合,它們是多對多的關系,文章集合中tags字段包含它對應的標簽,現在修改標簽集合中某條標簽記錄的名字,文章集合中所有包含這個標簽的tags字段的值也要隨之修改,之前的辦法是這樣寫的:
articleModel.find({tags:{$all:[doc.name]}},function(err,articles){
articles.forEach(function(article){
for(var j = 0;j<article.tags.length;j++){
if(article.tags[j] === doc.name){
article.tags[j] = req.body.name;
article.markModified('tags');
article.save();
break;
}
}
})
})
上面代碼的意思,在article集合中找到所有文檔的tags字段包含有doc.name的記錄,然后遍歷找到的結果集,循環更新每條記錄。這樣寫代碼繁瑣,效率又不高,后面在這里找到靈感http://cnodejs.org/topic/541be549ad60405c1f02f660,改善后的代碼如下:
articleModel.update({tags:{$all:[doc.name]},tags:doc.name,$atomic:true},{$set:{"tags.$":req.body.name}},{multi:true},function(err){
if(err) return console.log(err);
console.log('文章更新成功');
})
下面這樣寫也可以,我猜想需要被修改的字段只要出現在第一個參數的條件表達式中就可以了
articleModel.update({tags:{$all:[doc.name]},$atomic:true},{$set:{"tags.$":req.body.name}},{multi:true},function(err){
if(err) return console.log(err);
console.log('文章更新成功');
})
//mongodb 寫法 db.rbacs.update({grants:{$all:['user']}},{$set:{"grants.$":'user2'}})
//$all的值必須是一個數組
