5

I've managed to use EF Core to create the following item in Cosmos:

    {
        "Code": "https://CokeURL.com/gbm330",
        "Quantity": 1,
        "StockItemId": "00000ff8-0000-0000-0000-000000000000",
        "id": "https://CokeURL.com/gbm330",
        "_rid": "-BdUAM1W389NAgAAAAAAAA==",
        "_self": "dbs/-BdUAA==/colls/-BdUAM1W388=/docs/-BdUAM1W389NAgAAAAAAAA==/",
        "_etag": "\"1e001ff0-0000-1100-0000-608004300000\"",
        "_attachments": "attachments/",
        "_ts": 1619002416
    }

I need to remove it but it appears I need to read the item first. I've tried via Cosmos data explorer but clicking on the row gives the following error:

Failed to read item https://CokeURL.com/gbm330: Illegal characters ['/', '', '?', '#'] cannot be used in resourceId

I've also tried removing using EF Core but that throws an exception that looks like it's related to the SQL API:

Response status code does not indicate success: NotFound (404); Substatus: 0; ActivityId: 7e652a49-9813-4959-b55e-57b228231d6a; Reason: (The value 'dbs/Stock/colls/StockItemCode/docs/https://CokeURL.com/gbm330' specified for query '$resolveFor' is invalid. ActivityId: 7e652a49-9813-4959-b55e-57b228231d6a, Linux/10 cosmos-netstandard-sdk/3.11.4);

Is there another way to remove the item?

Thanks

1 Answer 1

4

Intersting problem! Using SDKs it won't be possible to delete the document.

However there's a workaround. Essentially, Cosmos DB has the functionality to set Time-to-Live (TTL) property on a container/document. Once properly set at the document level, the document will be automatically deleted once the TTL expires.

However before you do that, you will need to set the TTL property on the container to "On" (default is Off). What this setting mean is that documents in the container will automatically delete if TTL is specified on the document and once the TTL has expired. This you can set through Data Explorer in Azure Portal as shown below.

enter image description here

Once the TTL is configured properly on the container level, next thing you would need to do is update the document and set the TTL property on the document. You can do so by using Cosmos DB SDK. Please see sample code where I had set the TTL to be 30 seconds (you can set it as low as 1 second). Once the upsert operation succeeds, you will see the document gets automatically deleted after TTL has expired on the document (30 seconds in my case).

    static async Task UpdateItemTtl()
    {
        CosmosClient cosmosClient = new CosmosClient(connectionString);
        Container container = cosmosClient.GetContainer(databaseName, containerName);
        string documentBody = "{\"ttl\": 30, \"Code\": \"https://CokeURL.com/gbm330\", \"Quantity\": 1, \"ActivityId\": \"0000\", \"id\": \"https://CokeURL.com/gbm330\"}";
        Object o = JsonConvert.DeserializeObject(documentBody);
        ItemResponse<object> response = await container.UpsertItemAsync(o, new PartitionKey("0000"));
        documentBody = JsonConvert.SerializeObject(response.Resource);
        Console.WriteLine(documentBody);
    }
Sign up to request clarification or add additional context in comments.

4 Comments

Superb answer! :D Worked perfectly
It was really an interesting problem! I think Cosmos API should change the API to not allow any value for “id” considering it will have an impact on updating/removing the document. I’m glad to hear that you’re unblocked.
Agreed. I'll review this with the team.
@MarkBrown - Thanks!🙏

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.