简体   繁体   English

Cosmos DB - 删除文档

[英]Cosmos DB - Deleting a document

How can I delete an individual record from Cosmos DB?如何从 Cosmos DB 中删除单个记录?

I can select using SQL syntax:我可以选择使用 SQL 语法:

SELECT *
FROM collection1
WHERE (collection1._ts > 0)

And sure enough all documents (analogous to rows?) are returned果然所有文档(类似于行?)都返回了

However this doesn't work when I attempt to delete但是,当我尝试删除时这不起作用

DELETE
FROM collection1
WHERE (collection1._ts > 0)

How do I achieve that?我如何做到这一点?

The DocumentDB API's SQL is specifically for querying . DocumentDB API 的 SQL 专门用于查询. That is, it only provides SELECT , not UPDATE or DELETE .也就是说,它只提供SELECT ,而不提供UPDATEDELETE

Those operations are fully supported, but require REST (or SDK) calls.完全支持这些操作,但需要调用 REST(或 SDK)。 For example, with .net, you'd call DeleteDocumentAsync() or ReplaceDocumentAsync() , and in node.js, this would be a call to deleteDocument() or replaceDocument() .例如,在 .net 中,您将调用DeleteDocumentAsync()ReplaceDocumentAsync() ,而在 node.js 中,这将是对deleteDocument()replaceDocument()的调用。

In your particular scenario, you could run your SELECT to identify documents for deletion, then make "delete" calls, one per document (or, for efficiency and transactionality, pass an array of documents to delete, into a stored procedure).在您的特定场景中,您可以运行SELECT来识别要删除的文档,然后进行“删除”调用,每个文档一个(或者,为了效率和事务性,将要删除的文档数组传递到存储过程中)。

Another option to consider is the time to live (TTL).另一个需要考虑的选项是生存时间 (TTL)。 You can turn this on for a collection and then set an expiration for the documents.您可以为集合打开此功能,然后为文档设置到期时间。 The documents will be cleaned up automatically for you as they expire.文件到期时将自动为您清理。

The easiest way is probably by using Azure Storage Explorer .最简单的方法可能是使用Azure 存储资源管理器 After connecting you can drill down to a container of choice, select a document and then delete it.连接后,您可以深入到选择的容器,选择一个文档,然后将其删除。 You can find additional tools for Cosmos DB on https://gotcosmos.com/tools .您可以在https://gotcosmos.com/tools上找到 Cosmos DB 的其他工具。

使用 Azure 存储资源管理器连接到 Cosmos DB

Create a stored procedure with the following code:使用以下代码创建存储过程:

/**
 * A Cosmos DB stored procedure that bulk deletes documents for a given query.
 * Note: You may need to execute this stored procedure multiple times (depending whether the stored procedure 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 c._self FROM c WHERE c.founded_year = 2008"). Note: For best performance, reduce the # of properties returned per document in the query to only what's required (e.g. prefer SELECT c._self over SELECT * )
 * @returns {Object.<number, boolean>} Returns an object with the two properties:
 *   deleted - contains a count of documents deleted
 *   continuation - a boolean whether you should execute the stored procedure again (true if there are more documents to delete; false otherwise).
 */
function bulkDeleteStoredProcedure(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();
        }
    }
}

And execute it using your partition key (example: null) and a query to select the documents (example: SELECT c._self FROM c to delete all).并使用您的分区键(例如:null)和查询来选择文档(例如:SELECT c._self FROM c 以删除全部)执行它。

Based on Delete Documents from CosmosDB based on condition through Query Explorer基于通过查询资源管理器根据条件从 CosmosDB 中删除文档

##### Here is the python script which can be used to delete data from Partitioned Cosmos Collection #### This will delete documents Id by Id based on the result set data.

Identify the data that needs to be deleted before below step

res_list = "select id from id_del"
res_id = [{id:x["id"]} 
             for x in sqlContext.sql(res_list).rdd.collect()]
config = {
   "Endpoint" : "Use EndPoint"
  "Masterkey" : "UseKey", 
      "WritingBatchSize" : "5000",
    'DOCUMENTDB_DATABASE': 'Database',
    'DOCUMENTDB_COLLECTION': 'collection-core'
}; 

for row in res_id:
# Initialize the Python DocumentDB client
  client = document_client.DocumentClient(config['Endpoint'], {'masterKey': config['Masterkey']})

# use a SQL based query to get   documents

## Looping thru partition to delete

  query = { 'query': "SELECT c.id FROM c where c.id = "+ "'" +row[id]+"'"   }
  print(query)
  options = {}
  options['enableCrossPartitionQuery'] = True
  options['maxItemCount'] = 1000
  result_iterable = client.QueryDocuments('dbs/Database/colls/collection-core', query, options)
  results = list(result_iterable)
  print('DOCS TO BE DELETED : ' + str(len(results)))
  if len(results) > 0 :
      for i in range(0,len(results)):
      #  print(results[i]['id'])
          docID = results[i]['id']
          print("docID :" + docID)
          options = {}
          options['enableCrossPartitionQuery'] = True
          options['maxItemCount'] = 1000
          options['partitionKey'] = docID
          client.DeleteDocument('dbs/Database/colls/collection-core/docs/'+docID,options=options)
          print ('deleted Partition:' +  docID)

Here is an example of how to use bulkDeleteStoredProcedure using .net Cosmos SDK V3 .以下是如何使用 .net Cosmos SDK V3使用bulkDeleteStoredProcedure的示例。

ContinuationFlag has to be used because of the execution bounds.由于执行边界,必须使用 ContinuationFlag。

private async Task<int> ExecuteSpBulkDelete(string query, string partitionKey)
    {
        var continuationFlag = true;
        var totalDeleted = 0;
        while (continuationFlag)
        {
            StoredProcedureExecuteResponse<BulkDeleteResponse> result = await _container.Scripts.ExecuteStoredProcedureAsync<BulkDeleteResponse>(
                "spBulkDelete", // your sproc name
                new PartitionKey(partitionKey), // pk value
                new[] { sql });

            var response = result.Resource;
            continuationFlag = response.Continuation;
            var deleted = response.Deleted;
            totalDeleted += deleted;
            Console.WriteLine($"Deleted {deleted} documents ({totalDeleted} total, more: {continuationFlag}, used {result.RequestCharge}RUs)");
        }

        return totalDeleted;
    }

and response model:和响应模型:

public class BulkDeleteResponse
{
    [JsonProperty("deleted")]
    public int Deleted { get; set; }

    [JsonProperty("continuation")]
    public bool Continuation { get; set; }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM