如何使用mongoengine更新嵌入列表中的特定对象?

时间:2017-10-22 05:26:30

标签: python mongodb mongoengine

  

这是我的架构模型

class Address(Document):
       street = StringField()
       city = StringField()
       country = StringField()

    class Users(Document):
       user_name = StringField()
       address = ListField(EmbeddedDocumentField('Address'))
  

这就是我的对象:

{
  user_name: "John",
  address: [
    {
      "street": "broadway",
      "city": "new york",
      "country": "US"
    },
    {
      "street": "weymounth",
      "city": "london",
      "country": "England"
    }
  ]
}
  

这是我更新地址列表中第二项/对象的代码:

new_address = Address(street="bourke", city="melbourne", country="Australia")

User.objects(id="1", address__country="England").update_one(set__address__S=new_address)
  

但是此更新会更改嵌入列表中的第一个对象而不是第二个对象:

{
  user_name: "John",
  address: [
    {
      "street": "bourke",
      "city": "melbourne",
      "country": "Australia"
    },
    {
      "street": "weymounth",
      "city": "london",
      "country": "England"
    }
  ]
}

3 个答案:

答案 0 :(得分:1)

尝试使用EmbeddedDocumentListField

from mongoengine import Document, StringField, EmbeddedDocumentListField, EmbeddedDocument
class Address(EmbeddedDocument):
    street = StringField()
    city = StringField()
    country = StringField()

class Users(Document):
    user_name = StringField()
    address = EmbeddedDocumentListField(Address)


addresses = []

addresses.append(Address(street="broadway", city="new york", country="US"))
addresses.append(Address(street="bourke", city="melbourne", country="Australia"))

u = Users(user_name="john", address=addresses)
u.save()

Users.objects(address__country="US").update_one(
    set__address__S=Address(street="some street", city="Paris", country="France")
    )

最终文件:

{ 
    "_id" : ObjectId("59ec3c5219185b2fb4d428fa"), 
    "user_name" : "john", 
    "address" : [
        {
            "street" : "some street", 
            "city" : "Paris", 
            "country" : "France"
        }, 
        {
            "street" : "bourke", 
            "city" : "melbourne", 
            "country" : "Australia"
        }
    ]
}

答案 1 :(得分:0)

这很好用,但是如果您只需要从列表中更新一个变量,则可以使用标记来完成它:

SqlMapper.AddTypeHandler(new TrimmedStringHandler());

答案 2 :(得分:0)

尝试这种方式

u = Users.objects(user_name="john").first()
u.adress.filter(country="US").update(street="some street", city="Paris", country="France")
u.save()

推荐: 嵌入列表的每个元素应具有一个ObjectId(id)