Как удалить все документы в DocumentDB через код С#
Автор вопроса: satish kumar VОтветов: 3
Я использую новую базу данных от Microsoft под названием DocumentDB. Теперь хочу удалить документ по ID, но не могу понять, как это сделать. Операция удаления в DocumentDB требует собственных ссылок, и они отличаются от моих собственных идентификаторов. Однако я один раз запрашиваю документ, затем я получу ссылку на себя. С помощью этой ссылки я удаляю документ.
Теперь я хочу удалить все документы около 50000+ документов в моей коллекции.
Нужно получить каждый документ, а затем удалить или любой простой способ сделать то же самое?
Возможно ли это?
(в java) Я тоже хотел бы удалить весь документ данной коллекции. Кажется невозможным использование синтаксиса SQL. Например, УДАЛИТЬ ОТ ГДЕ сегодня недоступно. Я голосую за этот отзыв, который находится в состоянии under review. Я не хочу удалять повторное создание родительской коллекции: для меня это неприемлемый обходной путь. Я был бы очень рад получить решение для этого... boly38 06.07.2015
Ссылку на этот вопрос можно увидеть, если вы экспортируете шаблон экземпляра Azure Cosmos DB! Sunil Purushothaman 10.03.2020
Вы правы, что для удаления документов требуется ссылка на документ _self.
Если вы хотите удалить ВСЕ документы в своей коллекции, возможно, будет проще и быстрее удалить и заново создать коллекцию. Единственное предостережение заключается в том, что скрипты на стороне сервера (например, sprocs, udfs, триггеры) также относятся к коллекции и, возможно, их также необходимо создать заново.
Обновление: я написал быструю хранимую процедуру, которая выполняет массовое удаление по запросу. Это позволяет выполнять операции массового удаления с меньшим количеством сетевых запросов.
/**
* A DocumentDB stored procedure that bulk deletes documents for a given query.<br/>
* Note: You may need to execute this sproc multiple times (depending whether the sproc is able to delete every document within the execution timeout limit).
*
* @function
* @param {string} query - A query that provides the documents to be deleted (e.g. "SELECT * FROM c WHERE c.founded_year = 2008")
* @returns {Object.<number, boolean>} Returns an object with the two properties:<br/>
* deleted - contains a count of documents deleted<br/>
* continuation - a boolean whether you should execute the sproc again (true if there are more documents to delete; false otherwise).
*/
function bulkDeleteSproc(query) {
var collection = getContext().getCollection();
var collectionLink = collection.getSelfLink();
var response = getContext().getResponse();
var responseBody = {
deleted: 0,
continuation: true
};
// Validate input.
if (!query) throw new Error("The query is undefined or null.");
tryQueryAndDelete();
// Recursively runs the query w/ support for continuation tokens.
// Calls tryDelete(documents) as soon as the query returns documents.
function tryQueryAndDelete(continuation) {
var requestOptions = {continuation: continuation};
var isAccepted = collection.queryDocuments(collectionLink, query, requestOptions, function (err, retrievedDocs, responseOptions) {
if (err) throw err;
if (retrievedDocs.length > 0) {
// Begin deleting documents as soon as documents are returned form the query results.
// tryDelete() resumes querying after deleting; no need to page through continuation tokens.
// - this is to prioritize writes over reads given timeout constraints.
tryDelete(retrievedDocs);
} else if (responseOptions.continuation) {
// Else if the query came back empty, but with a continuation token; repeat the query w/ the token.
tryQueryAndDelete(responseOptions.continuation);
} else {
// Else if there are no more documents and no continuation token - we are finished deleting documents.
responseBody.continuation = false;
response.setBody(responseBody);
}
});
// If we hit execution bounds - return continuation: true.
if (!isAccepted) {
response.setBody(responseBody);
}
}
// Recursively deletes documents passed in as an array argument.
// Attempts to query for more on empty array.
function tryDelete(documents) {
if (documents.length > 0) {
// Delete the first document in the array.
var isAccepted = collection.deleteDocument(documents[0]._self, {}, function (err, responseOptions) {
if (err) throw err;
responseBody.deleted++;
documents.shift();
// Delete the next document in the array.
tryDelete(documents);
});
// If we hit execution bounds - return continuation: true.
if (!isAccepted) {
response.setBody(responseBody);
}
} else {
// If the document array is empty, query for more documents.
tryQueryAndDelete();
}
}
}
Ответ 2 · рейтинг 3 · Brett
Вот решение для удаления документов с помощью C# SDK. В приведенном ниже коде предполагается одна база данных и одна коллекция. Он будет перебирать все документы в коллекции и удалять их по одному. Чтобы удалить определенные базы данных, коллекции или документы, измените соответствующий метод "CreateQuery", включив в него синтаксис выбора SQL. Например, чтобы выбрать конкретную базу данных,
db = client.CreateDatabaseQuery().Where(o => o.Id == "MyDocDb").ToList().First();
Пример кода для удаления всех документов в экземпляре DocumentDB с одной базой данных и одной коллекцией:
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Util
{
class Program
{
private Uri _docDbUri = new Uri("https://<nameofyourdocdb>.documents.azure.com:443/");
private string _docDbKey = "<your primary key>";
private async Task DeleteDocsAsync()
{
using (var client = new DocumentClient(_docDbUri, _docDbKey))
{
try
{
var db = client.CreateDatabaseQuery().ToList().First();
var coll = client.CreateDocumentCollectionQuery(db.CollectionsLink).ToList().First();
var docs = client.CreateDocumentQuery(coll.DocumentsLink);
foreach (var doc in docs)
{
await client.DeleteDocumentAsync(doc.SelfLink);
}
}
catch (Exception ex)
{
Trace.WriteLine(ex);
throw;
}
}
}
static void Main(string[] args)
{
try
{
Program p = new Program();
p.DeleteDocsAsync().Wait();
}
catch (Exception)
{
throw;
}
}
}
}
Ответ 3 · рейтинг 1 · Roman Svitukha
Вот способ удалить документы с включенным AllowBulkExecution. Этот метод удаляет документы частями по 100, так как в настоящее время Cosmos DB поддерживает не более 100 операций одновременно. Он принимает имя свойства ключа раздела и использует отражение для получения его значения.
public async Task BulkDeleteDocumentsAsync(IEnumerable<T> entities, string partitionKeyPropertyName)
{
List<Task> tasks = new List<Task>(100);
foreach (var entity in entities)
{
var partitionKey = entity.GetType().GetProperty(partitionKeyPropertyName)?.GetValue(entity, null)?.ToString();
if (partitionKey != null)
{
tasks.Add(DeleteDocumentAsync(entity.Id!, partitionKey)
.ContinueWith(itemResponse =>
{
if (!itemResponse.IsCompletedSuccessfully)
{
AggregateException innerExceptions = itemResponse.Exception!.Flatten();
if (innerExceptions.InnerExceptions.FirstOrDefault(innerEx => innerEx is CosmosException) is CosmosException cosmosException)
{
_logger.LogError($"Cosmos Exception deleting {entity.Id} {cosmosException.StatusCode} ({cosmosException.Message}).");
}
else
{
_logger.LogError($"Exception deleting {entity.Id} {innerExceptions.InnerExceptions.FirstOrDefault()}.");
}
}
}));
if (tasks.Count == 100)
{
await Task.WhenAll(tasks);
tasks.Clear();
}
}
}
await Task.WhenAll(tasks);
}