【问题标题】:How to do "insert if not exist else update" with mongoengine?如何用mongoengine“插入如果不存在则更新”?
【发布时间】:2012-01-16 20:44:28
【问题描述】:

我正在 Django 中使用 mongoengine,
这是我的文档定义:

class Location(mongoengine.Document):  
    user_id = mongoengine.IntField(required=True)  
    point = mongoengine.GeoPointField(required=True)

我想这样做:
给定一个user_id 和一个point:
如果没有包含此user_id 的文档,则使用user_idpoint 创建一个并保存;
否则使用user_idpoint 更新文档。
我可以用 mongoengine 在一个语句中做到这一点吗?

【问题讨论】:

标签: python django mongodb mongoengine


【解决方案1】:

这是我想出的:

location = Location.objects.get_or_create(user_id=user_id)[0]  
location.point = point  
location.save()

【讨论】:

  • location, created = Location.objects.get_or_create(user_id=user_id) 是首选的方式!但是,是的,这将满足您的需求!
  • get_or_create() 现在是 deprecatedupsert 是 Mongoengine 工作人员的 recommended。有关更多信息,请参阅@NCao 的答案。
【解决方案2】:

请注意,get_or_create 现在计划弃用,因为 MongoDB 中没有事务支持,它无法确保原子性。

首选方式是 update 和 upsert:

Location.objects(user_id=user_id).update_one(set__point=point, upsert=True)

更多关于 MongoDB documentation 的更新。

【讨论】:

  • 当对象不存在时,如何使用user_id==-1 做同样的事情?
  • @arthur.sw 使用 MongoDB,新文档的对象 ID 是在客户端生成的,因此您只需使用 user_id= ObjectId() 创建一个新 ID。
  • 从 0.9 版开始有一种新方法(解释为 here): location = Location.objects(user_id=user_id).modify(upsert=True, new=True, set__point=point )
  • 还有upsert_one方法:docs.mongoengine.org/…
【解决方案3】:

从 0.9 版开始有一种新方法(解释为 here):

location = Location.objects(user_id=user_id).modify(upsert=True, new=True, set__point=point)

它返回创建或更新的对象。

【讨论】:

    【解决方案4】:

    或者您可以通过以下方式向您的类对象添加方法:

    class Location(mongoengine.Document):  
        user_id = mongoengine.IntField(required=True)  
        point = mongoengine.GeoPointField(required=True)
    
        def register(self):
            # if doesnt exist, create user id and point field
            if not Location.objects(user_id=self.user_id):
                self.user_id = self.user_id
                self.point = self.point
                self.save()
                return True
            # does exist, do nothing
            else:
                return False
    

    【讨论】:

      猜你喜欢
      • 2019-01-16
      • 1970-01-01
      • 1970-01-01
      • 2016-05-15
      • 1970-01-01
      • 2015-03-31
      • 1970-01-01
      • 1970-01-01
      • 2019-10-17
      相关资源
      最近更新 更多