【问题标题】:Delete Documents from CosmosDB based on condition through Query Explorer通过查询资源管理器根据条件从 CosmosDB 中删除文档
【发布时间】:2017-11-30 04:27:46
【问题描述】:

删除集合中所有符合 where 条件的文档的查询或其他快速方法是什么?
我想要DELETE * FROM c WHERE c.DocumentType = 'EULA' 之类的东西,但显然它不起作用。

注意:我没有为此寻找任何 C# 实现。

【问题讨论】:

  • 正如 Gaurav Mantri 所说,目前不支持。有一个 feedback 正在审核中。
  • 有趣的是,这可以使用 Graph API,因为您可以在遍历结果上执行 .drop() 以删除所有选定的文档......
  • @JesseCarter 可以详细描述一下
  • @JerryGoyal 不幸的是,除非您完全接受图表,否则我认为它不适用于您的用例,因为 Cosmos 需要特定的文档格式。但例如,您可以执行类似g.V().has('DocumentType', eq('EULA')).drop() 的操作并清除所有匹配的文档
  • 我在哪里运行这个查询

标签: azure azure-cosmosdb


【解决方案1】:

在集合中创建stored procedure 并通过传递带有删除条件的选择查询来执行它。使用这个存储过程的主要原因是因为延续令牌将在很大程度上减少 RU 并且成本更低。

【讨论】:

    【解决方案2】:

    如果您想在 C#/Dotnet Core 中执行此操作,此项目可能会有所帮助:https://github.com/lokijota/CosmosDbDeleteDocumentsByQuery。这是一个简单的 Visual Studio 项目,您可以在其中指定一个 SELECT 查询,所有匹配项都将 a) 备份到文件; b) 根据一组标志删除。

    【讨论】:

      【解决方案3】:
      ##### 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)
      

      【讨论】:

      • 你能解释一下这是什么吗?这看起来像 Spark 代码 (.rdd),而不是普通的 Python。
      【解决方案4】:

      我写了一个脚本来列出所有文件并删除所有文件,修改后也可以删除选中的文件。

      var docdb = require("documentdb");
      var async = require("async");
      
      var config = {
        host: "https://xxxx.documents.azure.com:443/",
        auth: {
          masterKey: "xxxx"
        }
      };
      
      var client = new docdb.DocumentClient(config.host, config.auth);
      
      var messagesLink = docdb.UriFactory.createDocumentCollectionUri("xxxx", "xxxx");
      
      var listAll = function(callback) {
        var spec = {
          query: "SELECT * FROM c",
          parameters: []
        };
      
        client.queryDocuments(messagesLink, spec).toArray((err, results) => {
          callback(err, results);
        });
      };
      
      var deleteAll = function() {
        listAll((err, results) => {
          if (err) {
            console.log(err);
          } else {
            async.forEach(results, (message, next) => {
              client.deleteDocument(message._self, err => {
                if (err) {
                  console.log(err);
                  next(err);
                } else {
                  next();
                }
              });
            });
          }
        });
      };
      
      var task = process.argv[2];
      switch (task) {
        case "listAll":
          listAll((err, results) => {
            if (err) {
              console.error(err);
            } else {
              console.log(results);
            }
          });
          break;
        case "deleteAll":
          deleteAll();
          break;
      
        default:
          console.log("Commands:");
          console.log("listAll deleteAll");
          break;
      }
      

      【讨论】:

      • 欢迎来到 Stack Overflow!虽然链接是分享知识的好方法,但如果它们在未来被破坏,它们将无法真正回答问题。将回答问题的链接的基本内容添加到您的答案中。如果内容太复杂或太大而无法在此处放置,请描述所提出解决方案的总体思路。请记住始终保留对原始解决方案网站的链接引用。见:How do I write a good answer?
      【解决方案5】:

      这有点旧,但只是有相同的要求,并找到了@Gaurav Mantri 所写内容的具体示例。

      存储过程脚本在这里:

      https://social.msdn.microsoft.com/Forums/azure/en-US/ec9aa862-0516-47af-badd-dad8a4789dd8/delete-multiple-docdb-documents-within-the-azure-portal?forum=AzureDocumentDB

      转到 Azure 门户,从上面获取脚本并在数据库中创建一个新的存储过程->您需要从中删除的集合。

      然后在存储过程窗格的底部,脚本文本区域下方是放置参数的地方。就我而言,我只想删除所有内容,所以我使用了:

      SELECT c._self FROM c

      我猜你会是:

      SELECT c._self FROM c WHERE c.DocumentType = 'EULA'

      然后点击“保存并执行”。维奥拉,一些文件被删除了。在 Azure 门户中使用它后,我切换了 Azure DocumentDB Studio 并更好地了解正在发生的事情。 IE。我可以看到我被限制为一次删除 18 个(在结果中返回)。出于某种原因,我在 Azure 门户中看不到这个。

      无论如何,即使每次执行仅限于一定数量的删除,也非常方便。执行 sp 也会受到限制,因此您不能只是捣碎键盘。我想我只会删除并重新创建集合,除非我有可管理数量的要删除的文档(考虑

      感谢 Mimi Gentz @Microsoft 分享上面链接中的脚本。

      HTH

      【讨论】:

      • 感谢您,当您需要针对单个分区运行它时,它会很有帮助。但是在查询本身是跨分区的情况下,存储过程选项是不可行的,因为您目前只能针对分区运行存储过程。
      【解决方案6】:

      我想要 DELETE * FROM c WHERE c.DocumentType = 'EULA' 但是,显然,它不起作用。

      不支持以这种方式删除文档。您需要首先使用 SELECT 查询选择文档,然后单独删除它们。如果需要,您可以在存储过程中编写获取和删除的代码,然后执行该存储过程。

      【讨论】:

      • 我现在有选择代码,我想从 cosmos 中删除所选数据如何执行,请使用代码 sn-p 指导
      猜你喜欢
      • 2020-04-07
      • 1970-01-01
      • 2017-01-14
      • 1970-01-01
      • 2020-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多