寫博客的時候有一個這樣的業務,一個標籤集合和一個文章集合,它們是多對多的關係,文章集合中tags字段包含它對應的標籤,如今修改標籤集合中某條標籤記錄的名字,文章集合中全部包含這個標籤的tags字段的值也要隨之修改,以前的辦法是這樣寫的:node
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,改善後的代碼以下:mongodb
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'}})atom
//$all的值必須是一個數組spa