Cosmos DB: Getting document id from exception upon conflict - azure-cosmosdb

Cosmos DB returns a DocumentClientException with a status of 409 Conflict when trying to insert a document with unique keys that match an existing document (cf. unique keys, exceptions).
Is it possible to get the id of the document from the exception without querying the db again?

Related

Logic app Delete document cosmos db gives 404 error

I am trying to delete a document from cosmos db using Logic App. The id exists in db, and I have provided the partition key as well. But still I get 404 error.
Can someone assist in adding a delete document function in logic app.
But the id exists in db
You need to pass the partition key value as the actual id instead of "id" which is the partition key path.
Change it to "fd39d4c4........." it should work then.

LINQ CosmosDB MongoDB API upsert E11000 duplicate key error collection

I have just started to try out cosmosdb with the mongodb api and my application is quite easy. It listens on a message queue and store that data in the database. This data might already be stored and needs to get updated so I do an upsert.
The problem is that on the update it fails with a duplicate key error. I have tried to read a bit about this but haven't found any documentation. What I did find out is that you shouldn't set the id when doing the update which I find hard to do.
This is the code I have:
await Ctx.ReplaceOneAsync(d => d.Id == importedData.Id, importedData, new UpdateOptions { IsUpsert = true });
And this is the error I get:
A write operation resulted in an error.
E11000 duplicate key error collection: test Failed _id or unique key constraint A bulk write operation resulted in one or more errors.
How do I do an update based on the id when using linq?

Determine if Cosmos DB NotFound due to missing collection vs. document

Is there a way to programmatically determine from a DocumentClientException where StatusCode == HttpStatusCode.NotFound whether it was the document, the collection, or the database that was not found?
I'm trying to figure out whether I can implement on-demand collection provisioning and only call DocumentClient.CreateDocumentCollectionIfNotExistsAsync when I need to. I'm trying to avoid calling it before making every request (presumably this adds an extra network roundtrip to every request). Likewise, I'm trying to avoid calling it on error recovery when I know it won't help.
From experimentation with the local emulator, the only field I see varying in these three cases is DocumentClientException.Error.Message, and only when the database cannot be found. I generally try to avoid exception dispatching based on human-readable messages.
Wrong database name:
StatusCode: HttpStatusCode.NotFound
Error.Message: {\"Errors\":[\"Owner resource does not exist\"]}...
Correct database name, wrong collection name:
StatusCode: HttpStatusCode.NotFound
Error.Message: {\"Errors\":[\"Resource Not Found\"]}...
Correct database name, correct collection name, incorrect document ID:
StatusCode: HttpStatusCode.NotFound
Error.Message: {\"Errors\":[\"Resource Not Found\"]}...
I'm planning to use a database with its own offer. Since collections inside a database with its own offer are cheap, I'm trying to see whether I can segregate each tenant in my multi-tenant application into its own collection. Each tenant ends up having a different indexing and default TTL policy. The set of collections is not fixed and changes dynamically during runtime as new tenants sign up. I cannot predict when I will need to add a new collection. There's no new tenant notification: I just get a request that I need to handle by creating a document in a possibly non-existent collection. There's a process to garbage collect unused collections.
I'm using the NuGet package Microsoft.Azure.DocumentDB.Core Version 1.9.1 in a .NET Core 2.1 app targeting a SQL API Cosmos DB instance.
If you look at the Message property in detail, you should see following strings that informs whether 404 Not Found response was generated due to Document vs Collection.
ResourceType: Document
ResourceType: Collection
It's not ideal but you can try to regex this information out of error message.

CosmosDB : How to apply concurrency while inserting a document (in parallel requests)

Background:
We have a EventHub where thousands of events are logged every day. The Azure function are configured on trigger over this eventhub on arrival of new messages. The azure function does following two tasks:
Write the raw message into document DB (collection 1)
Upsert an summary (aggregated) message into collection 2 of document Db. Before writing a message it checks if a summary message is already exists based on partition key and unique id (not id), it a doc exists then it update the doc with new aggregated value and if not then insert a new doc. This unique id is created based on a business logic.
Problem Statement:
More than one summary document is getting created for a PartitionKey and unique Id
Scenario Details
let us say, for PartitionKey PartitionKey1 there is no summary
document created in Collection for computed unique key.
multiple messages (suppose 2) arrived at eventhub and which have triggered azure functions.
all these 2 requests run concurrently, Since no existing document is found using the query, so each request make a message, now the Upsert function is
invoked almost at the same time for writing summary document by concurrent request and resulted to have multiple summary documents for a PartitionKey and unique Id.
I've searched and read about Optimistic Concurrency which definitely I will implement for update scenario. but I could not able to find any way through which insert scenarios can be handled?
According to your description, I suggest you use Stored Procedure to achieve this.
Cosmos DB to guarantee ACID for all operations that are part of a single stored procedure.
As the official said: If the collection the stored procedure is registered against is a single-partition collection, then the transaction is scoped to all the documents within the collection. If the collection is partitioned, then stored procedures are executed in the transaction scope of a single partition key. Each stored procedure execution must then include a partition key value corresponding to the scope the transaction must run under.
For more information about Stored Procedure of Cosmos DB and how to create Stored Procedure, we can refer to:
Azure Cosmos DB server-side programming: Stored procedures, database triggers, and UDFs
Create and use stored procedures using C#

SQLite INSERT or UDATE with a custom condition

I know there is a lot of question already asked and answered on this subject but they don't seem to fit my situation.
I have a distant sqlite database — DB server — and a local one — DB local containing photo album entries. DB local updates whenever needed from DB server. DB server has a primary key called identifier, which is stored in DB local to prevent duplicates, but DB local also has its own primary key column called id
If I need to create a new album on my phone I insert an entry in DB local with identifier set to -1 and when DB server will be reachable ask for a proper identifier.
My issue is : I do a lot of refresh and don't want to increment my primary key each time.
When I refresh DB local from DB server I would like to INSERT new albums, and UPDATE existing ones.
I read about the INSERT OR REPLACE statement but it would require my identifier column in DB local to be set as unique. Unfortunately I cannot do so since I can have multiple identifierset to -1.
Is there any way to perform an INSERT or UPDATE conditionally in a single request ?
Thanks !
EDIT : the update is done this way : the DB local is updated from DB server. DB local data is never pushed to DB server, the only way to add a new item is to call an API on the server which will create an empty entry on DB server and get its identifier. But since server is not always reachable (EDGE/3G) some entries in DB local have identifier set to -1. Once the API call have returned with the corresponding identifier we store it instead of -1 for the corresponding entry in DB local

Resources