如何将 Objects 的列表作为参数传递给 Azure CosmosDB (DocumentDB) 存储过程?

How to Pass List of Objects as a Parameter to Azure CosmosDB (DocumentDB) Stored Procedures?

我正在尝试在我的 collection 之一(比如页面)中执行批量更新。我为此创建了一个存储过程,当我从 Azure 执行时它工作正常。但是当我通过 REST API 执行它时,问题就来了。

当我将 Objects 的列表传递给存储过程函数时,它是如何只取第一个 object.

这是我的批量更新SP

function bulkImport(docs) {
if(typeof docs==="string")
    docs= JSON.parse(docs);
var collection = getContext().getCollection();
var collectionLink = collection.getSelfLink();
var count=0;
// Validate input.
if (!docs) throw new Error("The array is undefined or null.");
var docsLength = docs.length;
if (docsLength == 0) {
    getContext().getResponse().setBody(0);
}
tryUpdate(docs[count], callback);
function tryUpdate(doc, callback) {
    var requestOptions = { etag: doc._etag };
   var isAccepted = collection
                     .replaceDocument(doc._self,
                                      doc,
                                      requestOptions,
                                      callback);        
    if (!isAccepted) getContext().getResponse().setBody(count);
}
function callback(err, doc, options) {
    if (err) throw err;
    count++;

    if (count >= docsLength) {
        getContext().getResponse().setBody(count);
    } else {
        tryUpdate(docs[count], callback);
    }
}

我正在使用 RestSharp 作为 http 客户端来发出 REST 请求。

public static IRestResponse ExecuteStoredProcedure(string sprocs, string dbName, string colls, string key, string baseurl, string api_Version, string parameter)
    {
        //REST API URL Replace Document By Id PUT https://{databaseaccount}.documents.azure.com/dbs/{db-id}/colls/{coll-id}/docs/{doc-name}
        var client = new RestClient(baseurl + "dbs/" + dbName + "/colls/" + colls + "/sprocs/" + sprocs);
        //using getRquest() to Adding Header to the request
        var request = GetRequest(api_Version, Method.POST, dbName, colls, key,
            "dbs/" + dbName + "/colls/" + colls + "/sprocs/" + sprocs, "sprocs");
        request.AddParameter("undefined", parameter, ParameterType.RequestBody);
        return Execute(client, request);
    }

这是我作为参数传递给上述函数的示例数据

[{
    "id": "somestring",
    "query": {},
    "createdDate": "",
    "updatedDate": "",
    "createdBy": "Sai",
    "updatedBy": "Sai",
    "_rid": "somevalue",
    "_self": "somevalue,
    "_etag": "somevalue",
    "_attachments": "attachments/",
    "_ts": 0
},
{
    "id": "someid",
    "query": {},
    "createdDate": "",
    "updatedDate": "",
    "createdBy": "Sai",
    "updatedBy": "Sai",
    "_rid": "somevalue",
    "_self": "somevalue,
    "_etag": "somevalue",
    "_attachments": "attachments/",
    "_ts": 0
}

]

在 SP 中,如果我这样做

docs[0]._etag

我收到未定义的错误

异常详情

{
"code": "BadRequest",
"message": "Message: {\"Errors\":[\"Encountered exception while executing Javascript. Exception = TypeError: Unable to get property '_etag' of undefined or null reference\r\nStack trace: TypeError: Unable to get property '_etag' of undefined or null reference\n   at tryUpdate (bulkUpdatePage.js:21:9)\n   at bulkImport (bulkUpdatePage.js:13:5)\n   at __docDbMain (bulkUpdatePage.js:55:5)\n   at Global code (bulkUpdatePage.js:1:2)\"]}\r\nActivityId: 358544ea-07ee-45fd-9612-65295aa36900, Request URI: /apps/97eda9fb-4d31-43ec-816e-e341bfd2b031/services/962b1d52-8e1c-4d3a-a20e-1dc6ddca59f5/partitions/a75f0fb5-bd14-46a4-b0bb-a35e3cb3a2be/replicas/131823537009439236p, RequestStats: \r\nRequestStartTime: 2018-10-24T07:53:42.4855657Z, Number of regions attempted: 1\r\n, SDK: Microsoft.Azure.Documents.Common/2.0.0.0"

}

请帮忙,我被屏蔽了。 我错过了什么吗?

提前致谢!!

我找到了解决方案并把它留在这里,这样我以后可以帮助别人

On REST level sproc request body is array of sproc function parameters, each item in this array is separate argument to sproc. If you need array of docs to be 1st parameter, add one more [] around, i.e. use something like this: [[{"id":1}, {"id":2}]]. General hint for REST: use Fiddler and see what is passed over the wire when you use your REST and doing the same form API (using connection protocol = https) or DocumentDBStudio.

谢谢,

快乐编码