2
votes

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

1 Answers

2
votes

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);
    }