Loc Dai Le
Loc Dai Le

Reputation: 1697

Resource not found when trying to delete from Cosmos DB

When I try to delete a resource for Cosmos DB I get following error: Resource not found. It begins to happen when I started using a unlimited collection with a partion key. This worked fine without partionkey and a limit 10gb collection.

protected async Task<bool> DeleteDocument(Resource document)
    {
        var documentUri = UriFactory.CreateDocumentUri(_db.Options.Value.DatabaseName, _db.Options.Value.CollectionName, document.Id);

        ResourceResponse<Document> result = null;

        var options = new RequestOptions
        {
            PartitionKey = new PartitionKey("moachingpartionkey")
        };

        for (int i = 0; i < MaxRetryCount; i++)
        {
            try
            {
                result = await _db.Client.DeleteDocumentAsync(documentUri, options);
                break;
            }
            catch (DocumentClientException dex) when (dex.StatusCode.HasValue && (int)dex.StatusCode.Value == 429)
            {
                _logger.LogWarning($"");
                await Task.Delay(dex.RetryAfter);
            }
        }

        if (result == null)
            return false;

        int statusCode = (int)result.StatusCode;
        return statusCode >= 200 && statusCode < 300;
    }

Here is my create:

protected async Task<bool> CreateDocumentAsync(Resource document)
    {
        var collectionUri = UriFactory.CreateDocumentCollectionUri(_db.Options.Value.DatabaseName, _db.Options.Value.CollectionName);

        ResourceResponse<Document> result = null;

        for (int i = 0; i < MaxRetryCount; i++)
        {
            try
            {
                result = await _db.Client.CreateDocumentAsync(collectionUri, document);
                break;
            }
            catch (DocumentClientException dex) when (dex.StatusCode.HasValue && (int)dex.StatusCode.Value == 429)
            {
                _logger.LogWarning($"");
                await Task.Delay(dex.RetryAfter);
            }
        }

        if (result == null)
            return false;

        int statusCode = (int)result.StatusCode;
        return statusCode >= 200 && statusCode < 300;
    }

Upvotes: 4

Views: 2809

Answers (1)

bit
bit

Reputation: 4487

Since you have asked in the comments, here is the code I use to add partition key while creating the collection:

var collection = new DocumentCollection
{
    Id = "Customers", // just an example collection
};

// Set partition key
collection.PartitionKey.Paths.Add("/CountryId"); // just an example of the partition key path

// Set throughput
var options = new RequestOptions
{
    OfferThroughput = 400, // Default value is 10000. Currently set to minimum value to keep costs low.
};

// Create
await client.CreateDocumentCollectionIfNotExistsAsync(
   UriFactory.CreateDatabaseUri("YourCosomosDatabaseId"),
   collection,
   options);

Here is the code I use to Delete a document. Note that I check if it exists first, otherwise I get exception.

 // Check if it exists, otherwise delete throws
 var doc = await GetByIdAsync(id, 99); // your method to fetch the document by Id, the partition key (CountryId) is 99 
 if (doc == null)
 {
     return true; // Indicates successful deletion
 }

 // Delete
 var uri = UriFactory.CreateDocumentUri("YourCosomosDatabaseId", "Customers", id);
 var reqOptions = new RequestOptions { PartitionKey = new PartitionKey(99) }; // CountryId is 99
 var result = await Client.DeleteDocumentAsync(uri, reqOptions);
 return result.StatusCode == HttpStatusCode.NoContent;

To clarify a bit of the terminology-
When you say PartitionKey you imply a value like an int or string e.g 99 above.

Whereas when you say PartitionkeyPath you imply the property path/name in the document e.g /CountryId in above.

References for IDocumentClient and DocumentClient

Upvotes: 1

Related Questions