【问题标题】:Azure Cosmos DB - Possible to create a copy of JSON documentAzure Cosmos DB - 可以创建 JSON 文档的副本
【发布时间】:2017-09-25 12:24:18
【问题描述】:

我们有一份客户设备数据使用文档(例如,名称为“ABC_XYZ”),当客户取消提供设备时,应将其存档以供分析之用。解决方案是创建另一个文档(例如,名称为“ABC_XYZ_09252017_1748”)并删除当前文档(将来再次配置设备时,同一文档将保存更多数据)。

为此,我希望在 SDK 中找到一个方法,但找不到任何方法。仅创建 (CreateDocumentAsync) 和替换 (ReplaceDocumentAsync)。

我可以创建一个新名称的新名称,然后将旧名称中的数据复制到新名称中,然后删除旧名称。想知道是否有一个单一的 API,例如CopyDocumentAsync 或任何其他更好的方法来实现这一点?

【问题讨论】:

    标签: c# .net azure azure-cosmosdb


    【解决方案1】:

    没有“复制文档”API 调用(或相关的 SDK 调用)。您需要阅读当前文档(您可以通过直接阅读而不是查询来做到这一点),然后创建一个新文档(然后删除原始文档)。

    如果您希望这种情况以原子方式发生,则需要将查询 + 写入 + 删除放入存储过程(将其操作视为单个事务)。

    或者,您可以保持原始文档不变并将其标记为已删除(使用附加属性),然后在进行正常读取/查询时过滤该属性。

    【讨论】:

    • 感谢您的建议,最后一个不可行,因为将来可能会使用同一个文档来保存新数据。此外,所有这些逻辑都需要进入 WebAPI 方法。我不确定存储过程在那里是否可行?
    • 调用 Cosmos DB 存储过程与调用任何其他 Cosmos DB 操作的工作量差不多。我不明白为什么从 WebAPI 方法调用会是一个问题(这将是一个调用,而不是 3 个读取 + 写入 + 删除的调用)。
    • 好的肯定会试试这个。谢谢。
    【解决方案2】:

    这是一个如何将其实现为存储过程的示例:

    function storedProcedure(copyDocId) {
      let context = getContext();
      let response = context.getResponse();
      let collection = context.getCollection();
      let collectionLink = collection.getAltLink();
    
      let documentLink = collection.getAltLink() + "/docs/" + copyDocId;
    
      let canRead = collection.readDocument(documentLink, {}, readDocumentCallback);
      if (!canRead) throw "Unable to check for existence of document";
    
      function readDocumentCallback(err, doc, responseOptions) {
        if (err) throw err;
        doc.id = doc.id + 'XYZ'; // or however you determine this
    
        let canDelete = collection.deleteDocument(documentLink, {},
          function (err, deleted) {
            if (err) throw err;
    
            let canCreate = collection.createDocument(collectionLink, doc,
              function (err, newDoc) {
                if (err) throw err;
    
                response.setBody(newDoc);
              }
            );
    
            if (!canCreate) throw "Unable to create copy";
          }
        );
    
        if (!canDelete) throw "Unable to delete old document";
      }
    }
    

    将 SPROC 添加到您的集合后,从您的 WebAPI 调用它很简单:

    var sprocUri = UriFactory.CreateStoredProcedureUri(databaseId, collectionId, sprocName);
    var newDoc await documentClient.ExecuteStoredProcedureAsync<dynamic>(sprocUri, idOfDocToCopy);
    

    【讨论】:

      猜你喜欢
      • 2021-02-13
      • 1970-01-01
      • 2019-04-20
      • 1970-01-01
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多