How to do "insert if not exist else update" with mongoengine?

18,875

Solution 1

Note that get_or_create is now scheduled to be deprecated, because with no transaction support in MongoDB it cannot ensure atomicity.

The preferred way is update with upsert:

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

More on upserts on the MongoDB documentation.

Solution 2

There is a new way to do it since version 0.9 (explained here):

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

It returns the created or updated object.

Solution 3

this is what I came up with:

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

Solution 4

Or you can add a method to your class object via:

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
Share:
18,875

Related videos on Youtube

wong2
Author by

wong2

Actively maintaining https://github.com/wong2/pick

Updated on June 04, 2022

Comments

  • wong2
    wong2 almost 2 years

    I'm working with mongoengine in Django,
    this is my document defination:

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

    I want to do this:
    given a user_id and a point:
    if there is no document that have this user_id, create one with the user_id and point and save it;
    else update the document with user_id with point.
    Can I do this in one statement with mongoengine?

    • mac
      mac over 12 years
      possible duplicate of mongodb: insert if not exists - The answer is: use upsert.
    • wong2
      wong2 over 12 years
      @mac I think there maybe something even simpler.
  • Ross
    Ross over 12 years
    location, created = Location.objects.get_or_create(user_id=user_id) Is the preferred way of doing it! But yes that will do what you need!
  • Inactivist
    Inactivist about 11 years
    get_or_create() is now deprecated. upsert is recommended by the Mongoengine crew. See @NCao's answer for more info.
  • arthur.sw
    arthur.sw almost 10 years
    How can I do the same thing but with user_id==-1 when the object does not exist?
  • Nicolas Cortot
    Nicolas Cortot almost 10 years
    @arthur.sw with MongoDB, the object ID for a new document is generated client-side, so you just need to create a new ID with user_id= ObjectId().
  • arthur.sw
    arthur.sw over 9 years
    There is a new way to do it since version 0.9 (explained here): location = Location.objects(user_id=user_id).modify(upsert=True, new=True, set__point=point)
  • Hieu
    Hieu over 7 years
    There is upsert_one method too: docs.mongoengine.org/…
  • Paul Miller
    Paul Miller over 2 years
    What's the reason for the lines self.user_id = self.user_id self.point = self.point? Thanks