使用存储过程的Azure documentdb批量插入

使用存储过程的Azure documentdb批量插入,azure,bulkinsert,azure-cosmosdb,Azure,Bulkinsert,Azure Cosmosdb,您好,我使用16个集合插入大约300-400万个json对象,每个对象的大小从5-10k不等。我使用存储过程插入这些文档。我有22个容量单元 功能导入(文档){ var collection=getContext().getCollection(); var collectionLink=collection.getSelfLink(); //导入单据的数量,也作为当前单据索引使用。 var计数=0; //验证输入。 如果(!docs)抛出新错误(“数组未定义或为null”); var docs

您好,我使用16个集合插入大约300-400万个json对象,每个对象的大小从5-10k不等。我使用存储过程插入这些文档。我有22个容量单元

功能导入(文档){
var collection=getContext().getCollection();
var collectionLink=collection.getSelfLink();
//导入单据的数量,也作为当前单据索引使用。
var计数=0;
//验证输入。
如果(!docs)抛出新错误(“数组未定义或为null”);
var docsLength=docs.length;
如果(docsLength==0){
getContext().getResponse().setBody(0);
}
//调用CRUDAPI来创建文档。
tryCreateOrUpdate(单据【计数】,回调);
//请注意,有两个退出条件:
//1)createDocument请求未被接受。
//在这种情况下,将不调用回调,我们只调用setBody,就完成了。
//2)回调被称为docs.length次。
//在本例中,所有文档都已创建,我们不再需要调用tryCreate。只需调用setBody,我们就完成了。
函数tryCreateOrUpdate(文档,回调){
var isAccepted=真;
var isFound=collection.queryDocuments(collectionLink,'SELECT*FROM root r其中r.id=“”+doc.id+”,函数(err,feed,options){
如果(错误)抛出错误;
如果(!feed | |!feed.length){
isAccepted=collection.createDocument(collectionLink、doc、回调);
}
否则{
//元数据文档。
var existingDoc=feed[0];
isAccepted=collection.replaceDocument(现有文档、文档、回调);
}
});
//如果请求被接受,将调用回调。
//否则,向客户报告当前计数,
//这将使用剩余的文档集再次调用脚本。
//此存储过程运行时间过长时会出现这种情况
//即将被服务器取消。这将允许调用客户端
//从isAccepted设置为false之前的点恢复此批处理
如果(!isFound&&!isAccepted)getContext().getResponse().setBody(计数);
}
//当collection.createDocument完成并且文档已持久化时,将调用此函数。
函数回调(错误、文档、选项){
如果(错误)抛出错误;
//又插入了一个文档,请增加计数。
计数++;
如果(计数>=文件长度){
//如果我们已经创建了所有文档,我们就完成了。只需设置响应。
getContext().getResponse().setBody(计数);
}否则{
//创建下一个文档。
tryCreateOrUpdate(单据【计数】,回调);
}
}
我的C#代码是这样的

公共异步任务添加(列出实体)
{
int currentCount=0;
int documentCount=entities.Count;
while(currentCount
我面临的问题是,我尝试插入的40万个文档中,有一个文档丢失了,但没有给出任何错误

应用程序是部署在云上的工作者角色。 如果我增加在documentDB中插入的线程或实例的数量,则丢失的文档数量会高得多


如何找出问题所在。请提前感谢。

需要注意的是,存储过程具有有限的执行,其中所有操作都必须在服务器指定的请求超时时间内完成。如果操作没有在该时间限制内完成,事务将自动回滚。为了简化如果要处理时间限制,所有CRUD(创建、读取、更新和删除)操作都会返回一个布尔值,表示该操作是否将完成。该布尔值可以用作结束执行的信号,并用于实现基于延续的模型以恢复执行(这在下面的代码示例中说明)

上面提供的大容量插入存储过程通过返回成功创建的文档数来实现延续模型。存储过程的注释中指出了这一点:

//如果请求被接受,将调用回调。
//否则,向客户报告当前计数,
//这将使用剩余的文档集再次调用脚本。
//此存储过程运行时间过长时会出现这种情况
//即将被服务器取消。这将允许调用客户端
//从isAccepted设置为false之前的点恢复此批处理
如果(!isFound&&!isAccepted)getContext().getResponse().setBody(计数);

如果输出文档计数小于输入文档计数,则需要使用剩余的文档集重新运行存储过程。

我发现在尝试此代码时,docs.length处会出现一个错误,该错误表示长度未定义

function bulkImport(docs) {
    var collection = getContext().getCollection();
    var collectionLink = collection.getSelfLink();

    // The count of imported docs, also used as current doc index.
    var count = 0;

    // Validate input.
    if (!docs) throw new Error("The array is undefined or null.");

    var docsLength = docs.length; // length is undefined
}
经过多次测试(在Azure文档中找不到任何内容),我意识到我无法通过建议的数组
// psuedo object for reference only
docObject = {
  "items": [{doc}, {doc}, {doc}]
}

function bulkImport(docObject) {
    var context = getContext();
    var collection = context.getCollection();
    var collectionLink = collection.getSelfLink();
    var count = 0;

    // Check input
    if (!docObject.items || !docObject.items.length) throw new Error("invalid document input parameter or undefined.");
    var docs = docObject.items;
    var docsLength = docs.length;
    if (docsLength == 0) {
        context.getResponse().setBody(0);
    }

    // Call the funct to create a document.
    tryCreateOrUpdate(docs[count], callback);

    // Obviously I have truncated this function. The above code should help you understand what has to change.
}