6

If I try to upsert a document with an id and partition key that already exists, it works as expected IF there are no Unique constraints set on the container.

However, when I set any value in the table as Unique, then the upsert doesn't work and I get a (409 conflict - a Document with an id matching the id field of document already exists). The Unique constraint shouldn't be a problem in this case, but it causes this error, which has a strange error description for an upsert because it shouldn't matter if the id already exists.

I'm using documentClient.upsertDocument(collectionLink, documentDefinition, null, true);.

Artanis
  • 561
  • 1
  • 7
  • 26
  • Is your collection partitioned? Are you sending the same id and partition key value on each upsert? – Matias Quaranta Mar 20 '19 at 15:33
  • the id is automatically assigned by setting the false flag on the upsertDocument method. the partition key is the same for both requests and the unique field is the same for both requests. I want identical requests to upsert as we have 2 separate clouds attempting to upsert the same request. – Artanis Mar 20 '19 at 15:36
  • 2
    Documents are uniquely identified by their Id and Partition Key Value, regardless of Unique Field configuration. Unique Fields are there to add an extra check. If you send an Upsert with a random "id" every time, then Upsert will always create a different document. For Upsert to do an update/replace, you need to provide the id of the document as part of the request and not an autogenerated one (which would make it different each time). – Matias Quaranta Mar 20 '19 at 15:51
  • but the exception its giving me is that the id is the same. is that just a misleading effect of using a randomly generated id with matching unique values? – Artanis Mar 20 '19 at 16:16
  • i'll try setting the id myself and see if I get the results i'm looking for – Artanis Mar 20 '19 at 16:17
  • 1
    So you are correct I needed to define the id myself and use the exact same id for the other requests. This is the exact opposite of what the exception message said, which is pretty misleading. Please post an answer and I'll mark it as correct, thank you! – Artanis Mar 20 '19 at 20:52

1 Answers1

7

Cosmos DB's Upsert / Replace flow is based on the document's unique identifier (id and Partition Key value), Unique Fields are there to add extra checks for data validation.

When an Upsert operation is made, the service will look for an existing document with the same id and Partition Key value, if there is one, it will update it, otherwise, it will create it.

In your case, you are always sending a new random id, so Upsert is not finding an existing document to update and it's creating a new one every time.

Please define your own id before initiating the Upsert, and set the autogenerate id attribute in the upsert call to it's default (true) value: client.upsertDocument(collectionLink, documentDefinition).

Matias Quaranta
  • 13,907
  • 1
  • 22
  • 47
  • I need to insert a new document when it's given a new 'id' but the partition key is the same as an existing document's partition key. However it gives me a DocumentClientException. Why is this? Shouldn't I be able to have multiple documents with the same partition key value? – Artanis Apr 11 '19 at 16:14
  • 2
    Yes you can have many documents with the same partition key value, but not the same `id` within that partition key value. Check the DocumentClientException to understand what is the failure. If you are also using Unique Keys, you could be generating a conflict in some of your Unique Key constraints. – Matias Quaranta Apr 11 '19 at 19:15
  • thanks, yea it was a separate unique key causing the conflict. I'm finding the document client exceptions are often times misleading, as I've seem them say 'id already exists' for several different scenarios now where the id existing wasn't the issue. – Artanis Apr 11 '19 at 19:22