2015-03-03 134 views
4

我想知道如何通过选择文档(行)然后进入嵌套数组并选择特定对象来更新与PyMongo/MongoDB的嵌套数组。用PyMongo更新数组中的对象

{ 
    "_id" : "12345", 
    "name" : "John Doe, 
    "mylist" : [ 
     { 
      "nested_id" : "1", 
      "data1"  : "lorem ipsum", 
      "data2"  : "stackoverflow", 
      "data3"  : "james bond" 
     }, 
     { 
      "nested_id" : "2", 
      "data1"  : "lorem ipsum", 
      "data2"  : "stackoverflow", 
      "data3"  : "james bond" 
     }, 
     { 
      .... 
     }  
     ] 
} 

然后让我们说你通过一个你想要更新的元素的酌情。在这个例子中只更新数据1DATA3

data = { 
    "data1" : "new lorem", 
    "data3" : "goldeneye"  
} 

我曾尝试使用下面的语法,但没有成功。

db.testing.find_and_modify(
      query={"_id": "12345", 'mylist.nested_id' : "1"}, 
      update={"$set": {'mylist' : data}}) 

它应该看起来像更新

{ 
     "_id" : "12345", 
     "name" : "John Doe, 
     "mylist" : [ 
      { 
       "nested_id" : "1", 
       "data1"  : "new lorem", 
       "data2"  : "stackoverflow", 
       "data3"  : "goldeneye" 
      }, 
      { 
       "nested_id" : "2", 
       "data1"  : "lorem ipsum", 
       "data2"  : "stackoverflow", 
       "data3"  : "james bond" 
      }, 
      { 
       .... 
      }  
      ] 
    } 

回答

7

使用"dot notation"并在更新部分的位置操作之后什么。同时将您的输入相匹配的“点符号”形式的键表示:

# Transform to "dot notation" on explicit field 
for key in data: 
    data["mylist.$." + key] = data[key] 
    del data[key] 

# Basically makes 
# { 
#  "mylist.$.data1": "new lorem", 
#  "mylist.$.data3": "goldeneye" 
# } 

db.testing.find_and_modify(
    query = {"_id": "12345", 'mylist.nested_id' : "1"}, 
    update = { "$set": data } 
) 

这样就转$从更新的查询部分的实际匹配元素的位置。匹配的数组元素将被更新,并使用“点符号”只有提到的领域将受到影响。

不知道在这种情况下“服务”应该是什么意思,我只是将它视为“转录错误”,因为您明确试图匹配位置上的数组元素。

这可能会更清洁,但这应该给你一个总体思路。

+0

你好尼尔,谢谢你的回答!是的,你确实是对的,“服务”是一个错字!我尝试了你的建议,并得到一些错误。在循环中,它多次添加'mylist。$。',索引[0]除外。所以它看起来像这个'mylist。$ .mylist。$。mylist。$。data1:“data”'。但是如果我创建一个空字典并将“新”项目添加到该字典中,它就会起作用。但想知道是否可以在没有和使用你的方法的情况下做到这一点! :) – Sigils 2015-03-03 11:09:05

+0

@Sigils对不起。你说的是你在修改“字典”内容时遇到问题。为什么会这样? – 2015-03-03 11:14:21

+0

不要对不起,你已经帮了我很多。但我会尽力在这里写出错误。循环后的数据字典看起来像是这样的:“data = {mylist。$。data1”:“new lorem”, “mylist。$。mylist。$。mylist。$。data2”:“more data”,您可以看到第一次完美添加,但在此之后,它只是继续添加更多内容!“#:。 – Sigils 2015-03-03 11:19:20