【问题标题】:How do I get a continuation token for a bulk INSERT on Azure Cosmos DB?如何在 Azure Cosmos DB 上获取批量 INSERT 的延续令牌?
【发布时间】:2018-02-06 22:59:11
【问题描述】:

我想上传一个代表 10k 个文档的 CSV 文件,以快速和原子的方式添加到我的 Cosmos DB 集合中。我有一个类似于以下伪代码的存储过程:

function createDocsFromCSV(csv_text) {
    function parse(txt) { // ... parsing code here ... }

    var collection = getContext().getCollection();
    var response = getContext().getResponse();

    var docs_to_create = parse(csv_text);
    for(var ii=0; ii<docs_to_create.length; ii++) {
        var accepted = collection.createDocument(collection.getSelfLink(),
                                                    docs_to_create[ii],
                                                    function(err, doc_created) {
                                                        if(err) throw new Error('Error' + err.message);
                                                    });
        if(!accepted) {
            throw new Error('Timed out creating document ' + ii);
        }
    }
}

当我运行它时,存储过程在超时之前创建了大约 1200 个文档(因此回滚而不创建任何文档)。

以前,我使用延续令牌成功更新(而不是创建)存储过程中的数千个文档,并将此答案作为指导:https://stackoverflow.com/a/34761098/277504。但是在搜索文档(例如https://azure.github.io/azure-documentdb-js-server/Collection.html)之后,我没有看到像查询文档那样从创建文档中获取延续令牌的方法。

有没有办法利用存储过程来创建批量文档?

【问题讨论】:

  • 您好,我的回答对您有帮助吗?

标签: stored-procedures azure-cosmosdb


【解决方案1】:

需要注意的是,存储过程是有限执行的,所有操作都必须在服务器指定的请求超时时间内完成。如果操作未在该时间限制内完成,则事务将自动回滚。

为了简化开发以处理时间限制,所有 CRUD(创建、读取、更新和删除)操作都会返回一个布尔值,表示该操作是否会完成。该布尔值可用作结束执行的信号,并用于实现基于延续的模型以恢复执行(这在下面的代码示例中进行了说明)。更多详情请参考doc

上面提供的批量插入存储过程通过返回成功创建的文档数来实现延续模型。

伪代码:

function createDocsFromCSV(csv_text,count) {
    function parse(txt) { // ... parsing code here ... }

    var collection = getContext().getCollection();
    var response = getContext().getResponse();

    var docs_to_create = parse(csv_text);
    for(var ii=count; ii<docs_to_create.length; ii++) {
        var accepted = collection.createDocument(collection.getSelfLink(),
                                                    docs_to_create[ii],
                                                    function(err, doc_created) {
                                                        if(err) throw new Error('Error' + err.message);
                                                    });
        if(!accepted) {
            getContext().getResponse().setBody(count);
        }
    }
}

然后您可以在客户端检查输出文档计数并使用count 参数重新运行存储过程以创建剩余的文档集,直到计数大于csv_text 的长度。

希望对你有帮助。

【讨论】:

  • 这听起来可能会奏效,我希望这周可以尝试一下。据我了解,此解决方案不会是原子的,因为即使未达到总数,它也会在集合中创建新文档。在我的第一次测试中,有 1200 个文档排队等待输入,但有 0 个已提交,但我没想过要一次又一次地重新提交该函数。一旦我尝试过,我会回帖。
猜你喜欢
  • 1970-01-01
  • 2019-02-08
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-12
  • 1970-01-01
  • 2019-09-17
相关资源
最近更新 更多