Mongodb:如何更改嵌套数组的元素?

时间:2014-09-28 15:45:05

标签: python mongodb pymongo

根据我的阅读,使用$中的位置运算符mongo无法更新嵌套数组中的元素。 $只能深入一级。我发现它是mongo 2.7中的请求功能。

由于写入冲突,不能更新整个文档one level up。我需要能够为特定的奖励计划更改'username'

其中一个想法是拉动,修改和推送整个'reward_programs'元素,但之后我会松开订单。订单很重要。

考虑这个文件:

 {
  "_id:"0,
  "firstname":"Tom",
  "profiles" : [
               {
                    "profile_name": "tom",
                    "reward_programs:[
                                        {
                                            'program_name':'American',
                                            'username':'tomdoe',
                                        },
                                        {
                                            'program_name':'Delta',
                                            'username':'tomdoe',
                                        }
                                      ]
               }
            ]
}

您将如何专门更改'username'的{​​{1}}?

2 个答案:

答案 0 :(得分:1)

在做了更多阅读之后,目前mongodb似乎不支持此功能。位置更新仅支持一级深度。可以为mongodb 2.7添加该功能。

这是一些解决方法。

1)展平您的数据库结构。在这种情况下,制作奖励计划'它自己的收藏品,并对此进行操作。

2)使用dicts的dicts而不是dicts数组。这样,您可以只有一个绝对路径到您需要修改的对象。查询灵活性可能存在缺陷。

3)看起来对我很苛刻,但你也可以在嵌套数组上查看列表,找到它在数组中的位置索引,并执行以下操作:

 users.update({'_id': request._id, 'profiles.profile_name': profile_name}, {'$set': {'profiles.$.reward_programs.{}.username'.format(index): new_username}})     

4)读入整个文档,修改,回写。但是,这可能存在写冲突

最初设置数据库结构非常重要。这实际上取决于你将如何使用它。

答案 1 :(得分:0)

一种简单的方法:

doc = collection.find_one({'_id': 0})
doc['profiles'][0]["reward_programs"][1]['username'] = 'new user name'
#replace the whole collection
collection.save(doc)