Удаление документа из Cosmos DB — объект с указанным идентификатором не существует в системе

#c# #azure-cosmosdb

#c# #azure-cosmosdb

Вопрос:

Я сталкиваюсь с проблемой при попытке удалить документ из CosmosDb , насколько я понимаю, сначала мне нужно загрузить документ, который я хочу удалить, а затем передать document.SelfLink в следующий метод:

 DeleteDocumentAsync
 

Однако, когда я пытаюсь удалить его, он выдает следующую ошибку:

объект с указанным идентификатором не существует в системе

Я знаю, что документ существует, поскольку я могу видеть документ в document переменной.

Ниже приведена моя текущая настройка кода:

  private static void DeleteDocument()
    {
        var feedOptions = new FeedOptions
        {
            MaxItemCount = -1,
            EnableCrossPartitionQuery = true
        };

        var document = _documentClient
            .CreateDocumentQuery(UriFactory.CreateDocumentCollectionUri(_databaseName, _collection), feedOptions)
            .Where(x => x.Id == "ba00d500-de61-411e-b8ef-f749b23cc326")
            .AsEnumerable()
            .SingleOrDefault();

        if (document == null) return; // Document is not null when I check here

        _documentClient.DeleteDocumentAsync(UriFactory.CreateDocumentUri(_databaseName, _collection, document.Id), new RequestOptions { PartitionKey = new Microsoft.Azure.Documents.PartitionKey(document.Id) })
            .GetAwaiter()
            .GetResult();
    }
 

Вот документ в CosmosDB:

введите описание изображения здесь

Я также пытался ссылаться на document.SelfLink вместо использования UriFactory.CreateDocumentUrl , но результат все тот же.

Обновить.

Кажется, что передача Undefined.Value выполняется, поскольку PartitionKey , похоже, работает:

 _documentClient.DeleteDocumentAsync(document.SelfLink, new RequestOptions { PartitionKey = new Microsoft.Azure.Documents.PartitionKey(Undefined.Value) })
            .GetAwaiter()
            .GetResult();
 

Что лично я нахожу действительно странным.

Комментарии:

1. Документ имеет id (нижний регистр), но ваш предикат Linq имеет Id (и вы ссылаетесь document.Id )

Ответ №1:

Я не вижу ничего странного, просто нужно знать ключ раздела и указывать его при отправке запроса на сервер. Ключ раздела является частью идентификатора документа так же, как id и -field . Даже если ключ раздела undefined .

Когда вы запрашивали документы, вы явно запрашивали сканирование всех разделов, EnableCrossPartitionQuery = true что позволяло вам исключить ключ раздела из запроса и все равно получать результаты. Вы также должны были передать ключ раздела там, чтобы сэкономить затраты, но это работает.

Для удаления нет межсекционных удалений, и вы должны передать ключ раздела. Как только вы это сделали, документ был найден и его можно было удалить. Вполне ожидаемо.

Кроме того, НЕТ, вам не нужно загружать документ, чтобы удалить его, это просто дополнительная сложность, стоимость и сервер roundtripto. Все, что вам нужно знать, это идентификатор удаляемого документа (база данных коллекция раздел идентификатор). Для клиента CosmosDB V2, аналогичного этому примеру:

 var documentUri = UriFactory.CreateDocumentUri(databaseName, containerName, documentId);
var options = new RequestOptions() { PartitionKey = new PartitionKey(partition) };

await cosmosClient.DeleteDocumentAsync(documentUri, options).ConfigureAwait(false);