如何使用$ set和$ elemMatch之类的东西更新MongoDB文档数组中的单个子文档?

时间:2014-04-06 20:42:52

标签: mongodb meteor mongodb-query

我有一个像这样的集合结构:

albums: {
    2oBkjqYFwf3vrgDj4: {
        _id: "2oBkjqYFwf3vrgDj4",
        titles: [
            {
                titleText: "i am an album"
            },
            {
                titleText: "this is my other title"
            }
        ]
    }
}

我想做类似下面的事情来更新titleText等于某事的地方,然后改变它:

db.albums.update({"_id": "2oBkjqYFwf3vrgDj4", "titles": {$elemMatch: {"titleText": "i am an album"}}},
    {$set: {
        "titles.titleText": "i am not an album"
    }
)

我知道我可以做一个foreach,但这似乎浪费了很多资源,因为我计划在titles.titleText上建立一个索引。

我有什么遗漏,或者有没有一种简单的方法可以做到这一点? 我正在使用Meteor,但如果有一种方法可以在MongoDB中执行此操作,我认为它不应该改变任何逻辑。

谢谢大家!

3 个答案:

答案 0 :(得分:5)

原来我的问题是link

的重新发布

这个问题可以在MongoDB中解决,

db.albums.update({
        "_id": "2oBkjqYFwf3vrgDj4",
        "titles.titleText": "i am an album"
    },
    {$set:
        {"titles.$.titleText": "i am not an album"}
    }
)

当上一个问题发布时,位置运算符wasn't supported by minimongo。截至目前,mongo选择器无法从客户端代码中用于security reasons

必须从服务器上的Meteor.method()调用上述方法。

答案 1 :(得分:0)

使用meteor collection api,您可以使用updatedocumentation here。您提供选择器,然后提供修改器。你也可以直接用mongo做同样的事情。一般语法如下,但我自己没有运行它。我不知道是否存在类似于您的代码的更好的方式,可能是干的,但应该完成工作。

Albums.update(
    {_id: "2oBkjqYFwf3vrgDj4", "titles.titleText": "i am an album"},
    {$set:{"titles.titleText": "i am not an album"}}
};

答案 2 :(得分:0)

$ set在客户端上运行良好。一个很好的工作是(他在派对中)他的例子。

step 1: get the array for your items.
    var album = albums.findOne().services;
step 2: lets find the index we want using _indexOf and _pluck
                 var indexToUpdate = _.indexOf(_.pluck('insert your array', 'insert your column name'), 'insert the one you want to update');

                var modifier = { $set: {} };
                modifier.$set["services." + indexToUpdate + ".youfieldinarray"] = 'your new value'.
step 3: update your item object      
albumns.update(Business.findOne()._id, modifier);

不确定我是否会在大型系列中执行此操作,但对于较小的客户端,它可以正常运行。