为什么在DocumentDB中使用存储过程不插入超过一百个记录进行批量插入?

时间:2017-02-15 13:45:59

标签: c# azure-cosmosdb

下面是我用于文档db

中批量插入记录的DocumentDB存储过程
function bulkCustomerImport(docObject) {
var context = getContext();
var collection = context.getCollection();
var collectionLink = collection.getSelfLink();
var count = 0;
var customerList = [];
// Check input
if (!docObject.length) throw new Error("Invalid object.");
var docs = docObject;
var docsLength = docs.length;
if (docsLength == 0) {
    context.getResponse().setBody(0);
}

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

// Note that there are 2 exit conditions:
// 1) The createDocument request was not accepted. 
//    In this case the callback will not be called, we just call setBody and we are done.
// 2) The callback was called docs.length times.
//    In this case all documents were created and we don't need to call tryCreate anymore. Just call setBody and we are done.
function tryCreateOrUpdate(doc, callback) {
    var isAccepted = true;
    var isFound = collection.queryDocuments(collectionLink, 'SELECT * FROM root r WHERE r.FullName = "' + doc.FullName + '" and r.Company = "' + doc.Company + '"', function (err, feed, options) {
        if (err) throw err;
        if (feed.length==0) {
            isAccepted = collection.createDocument(collectionLink, doc, callback);
        }
        else {
                 if(!feed.length > 0) throw 'Unable to find metadata document';
            callback(false, feed[0])
        }
    });

    // If the request was accepted, callback will be called.
    // Otherwise report current count back to the client, 
    // which will call the script again with remaining set of docs.
    // This condition will happen when this stored procedure has been running too long
    // and is about to get cancelled by the server. This will allow the calling client
    // to resume this batch from the point we got to before isAccepted was set to false
    if (!isFound && !isAccepted) getContext().getResponse().setBody(customerList);
}

// This is called when collection.createDocument is done and the document has been persisted.
function callback(err, doc) {
    if (err) throw err;

    // One more document has been inserted, increment the count.
    count++;
    customerList.push(doc);
    if (count >= docsLength) {
        // If we have created all documents, we are done. Just set the response.
        getContext().getResponse().setBody(customerList);
    } else {
        // Create next document.
        tryCreateOrUpdate(docs[count], callback);
    }
}
}

上面的批量插入代码适用于少于约一百条记录,并返回一个客户列表。但是如果我有超过一百条记录,我总是会将null值返回给我的.Net代码。我检查了我正在插入的所有记录,其中没有任何不正确的值。这个程序也没有任何错误。

这是用于调用过程的C#代码:

public static async Task<List<Customer>> InsertBulk(string storedProcedureID, List<Customer> cl)
{
var sprocLink = UriFactory.CreateStoredProcedureUri("DatabaseName", "Collection", storedProcedureID);
        StoredProcedure sproc = await Client.ReadStoredProcedureAsync(sprocLink.ToString());
        string argsJson = JsonConvert.SerializeObject(cl.ToArray());
        var docObject = new dynamic[] { JsonConvert.DeserializeObject<dynamic[]>(argsJson) };

        try
        {
            cl = await Client.ExecuteStoredProcedureAsync<List<Customer>>(sproc.SelfLink, docObject);
        }
        catch (DocumentClientException ex)
        {
            throw;
        }

        return cl;
}

请记录此插入的记录可以是数百到数百万的任意数量。任何与此相关的帮助都将受到高度赞赏..

0 个答案:

没有答案