mongodb-odm icon indicating copy to clipboard operation
mongodb-odm copied to clipboard

Allow explicitely requesting upsert for documents

Open alcaeus opened this issue 8 years ago • 7 comments

ODM automatically decides whether a document should be inserted or upserted based on whether or not it has an identifier. The logic requires that the identifier is set manually before persist is called. This does not work when using custom ID generators. This is illustrated in #1422.

The best way would be to specify a storage strategy at the document level, specifying whether a document should be written using insert (default) or upsert. This would also allow supporting the $setOnInsert operator that was added in MongoDB 2.4.

Note: this is currently scheduled for the 2.0.0 milestone due to the required cleanup of collection strategies, as some strategies would not play nice when doing upserts.

alcaeus avatar Jun 03 '16 08:06 alcaeus

as some strategies would not play nice when doing upserts.

I was also thinking to allow changing collection's strategy for the upsert only, namely to use atomisSetArray during normal flush and utilize for instace addToSet during upsert.

malarzm avatar Jun 03 '16 09:06 malarzm

I would love to see this too, upsert with $setOnInsert

dbpolito avatar Aug 03 '16 17:08 dbpolito

@alcaeus is it expected behavior then that calling persist on a new document with ID set beforehand will be upserted to MongoDB? I'm asking to know should I rely on this in my code since I'm using it for updating multiple already existing documents without loading them (they represent a state snapshot for a given time for grouped data).

Steveb-p avatar Dec 14 '18 15:12 Steveb-p

Yes, that is the expected behavior at this time. We will not be changing this for 2.0 either.

alcaeus avatar Dec 14 '18 19:12 alcaeus

is there any clean workaround to this issue ?

g13013 avatar Apr 13 '20 21:04 g13013

@g13013 if you are not relying on $setOnInsert, then assigning an identifier when the entity is created will work to force an upsert. If you want to use $setOnInsert, you'll have to insert data manually using the query builder.

alcaeus avatar Apr 15 '20 11:04 alcaeus

@alcaeus I fixed the issue using the @PrePersist @PreUpdate hooks by calling the generator manually

g13013 avatar Apr 15 '20 19:04 g13013