使用NodeJS将新值推送到MongoDB文档中的数组

时间:2014-07-03 10:42:45

标签: node.js mongodb mongojs

我有一个MongoDB集合,其文档如下所示:

{
    "id": 51584,
    "tracks": [],
    "_id": {
        "$oid": "ab5a7... some id ...cc81da0"
    }
}

我想将单个轨道推入数组,因此我尝试以下NodeJS代码:

function addTrack(post,callback){
    var partyId = post['partyId'], trackId = post['trackId'];
    // I checked here that partyId and trackId are valid vars.
    db.db_name.update({id: partyId}, { $push: { tracks: [trackId] } }, function(err, added) {
      if( err || !added ) {
        console.log("Track not added.");
        callback(null,added);
      }
      else {
        console.log("Track added to party with id: "+partyId);
        callback(null,added);
        }
    });
}

这将成功返回添加了曲目的回调。但是,当我手动检查数据库时,它不会更新,并且数组轨道仍为空。 我已经尝试了许多不同的东西来推动轨道元素(即将它变成一个数组等)但到目前为止没有运气。

PS:也许我应该注意到我正在使用MongoLab来托管数据库。

欢迎任何帮助。

3 个答案:

答案 0 :(得分:1)

我发现我的问题,在addTrack更新({id:partyId},...方法partyId不是字符串,所以它没有找到任何要推送的文档。感谢SudoGetBeer引导我找到解决方案。< / p>

答案 1 :(得分:0)

如果您的发布文档是正确的(通过find()获取):

tracks是一个子文档或嵌入文档(http://docs.mongodb.org/manual/tutorial/query-documents/#embedded-documents

区别很简单:{} = Document,[] = Array

因此,如果您想使用$ push,则需要将tracks字段更新为数组

答案 2 :(得分:0)

以下是我的表现:

 // This code occurs inside an async function called editArticle()
 const addedTags = ['one', 'two', 'etc']

 // ADD NEW TAGS IN MONGO DB
 try {
     const updateTags = addedTags.reduce((all, tag) => {
         all.push(articles.updateOne({ slug: article.slug }, { $push: { tags: tag } }))
         return all
     }, [])
     await Promise.all(updateTags)
 } catch (e) {
     log('error', 'addTags', e)
     throw 'addTags'
 }

addTags是标签数组,我们需要一次将它们推入Mongo DB中,以便我们推送的文档如下所示:

 {
     tags: ["existingTag1", "existingTag2", "one", "two", "etc"]
 }

如果按照上面的原始问题推送数组,它将如下所示:

 {
     tags: ["existingTag1", "existingTag2", ["one", "two", "etc"]]
 }

所以,标签[2]将是["one", "two", "etc"],而不是你想要的。

我已经展示了.reduce()这是一个累加器,这是一种奇特的,不可改变的方式:

 let updateTags = []
 addedTags.forEach((tag) => {
     updateTags.push(articles.updateOne({ slug: article.slug }, { $push: { tags: tag } }))
 })

此时,updateTags包含一系列函数,因此调用Promise.all(updateTags)将全部运行它们并在其中任何一个失败时引爆。由于我们使用的是Mongo DB Native Driver,如果发生任何错误,您将不得不进行清理,因此您可能希望在调用Promise.all()之前跟踪预写状态(即:之前的标记是什么?)< / p>

在上限范围的catch区块或catch区块中,您可以&#34; fire恢复之前的状态&#34;逻辑(回滚)和/或重试。

类似的东西:

 // Upper scope
 catch (e) {
     if (e === 'addTags') rollback(previousState)
     throw 'Problem occurred adding tags, please restart your computer.'
     // This can now bubble up to your front-end client
 }