简体   繁体   中英

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

I am trying to perform a Bulk Update in One of my collection (say pages). I have created a Stored Procedure for this which is working all fine when I execute from Azure. But the problem comes when I execute that through a REST API.

When I Pass List of Objects to the Stored Procedure function its some how taking only the first object.

This is my SP for Bulk Update

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);
    }
}

I'm using RestSharp as a http client to make REST Request.

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);
    }

This is my sample data that is passed as a parameter to above function

[{
    "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
}

]

In SP, if I do

docs[0]._etag

im getting error as undefined

Exception Details

{
"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"

}

Please help, Im blocked. Am I missing anything?

Thanks in advance !!

I got the solution for this and leaving this here so that i might help someone in future

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, ie 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.

thanks,

Happy Coding

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM