Search code examples
mongodbupsertidempotent

How to make a MongoDB Upsert truly idempotent?


I want to insert a document into a MongoDB in an idempotent way.

The explanation provided by the MongoDB documentation, and also here on SO, is to use the upsert=True modifier.

However, to my understanding, this does not guarantee idempotence, because an already existing document could be modified.

The operation I am looking for is as follows:

  • If the document, identified by some key, does not exist, insert it.
  • If a document with the given key already exists, there are two things that might happen:
    • The existing document and the provided document are exactly the same. Then, return the same result as if a new document would have been inserted.
    • The existing document differs from the provided document: Throw an error, because idempotence would be violated.

Does MongoDB support such an operation out of the box? Why are upsert operations labelled idempotent even though they might modify the document that is already present?


Solution

  • Idempotent means that you can execute the same action twice and have the same effect as if it only had happened once. The name upsert is also a hint: it is a contraction of update and insert. This means that it will either (if it exists) update an existing document, or insert a new one. So: upsert operations are labelled idempotent because they are. Your interpretation of the word idempotent is not what everyone else uses.

    Your use case resp. requirement is something else. In my understanding, it is quite hard to do that in MongoDB, because there are no usable general inbuilt transaction mechanisms (at least last I looked). You'd need to do something like a two-phase commit, from your application.