Azure Cosmos DB - 可以创建JSON文档的副本

时间:2017-09-25 12:24:18

标签: c# .net azure azure-cosmosdb

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

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

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

2 个答案:

答案 0 :(得分:2)

没有“复制文档”API调用(或相关的SDK调用)。您需要阅读当前文档(可以使用直接读取和查询),然后创建新文档(然后删除原始文档)。

如果您希望以原子方式进行此操作,则需要将查询+ write + delete放入存储过程(将其操作视为单个事务)。

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

答案 1 :(得分: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);