9
votes

I am new to Cosmos Db and want to understand how to delete/upsert sub-documents within a document collection.

If i have a document:

{ "Id": "1234", "Name": "foo", "Items": [ { "Id": "abcd", "Age": 35, "Claims": [ { "Name": "email", "Value": "[email protected]" } ] } ] }

How do i:

1) add an item to the Items list in the document.

2) delete the existing Item from the Items list

3) upsert item to the items list in the document

4) add/delete a claim value to existing item in items list?

Thanks in advance.

2
Honestly I will use any of the APIs. Whatever is easiest. Is one better than the other? Do you happen to know how in any of them?Jerrod Horton
Just to put the consideration out there: if this item change is a main operation then probably you should model your current document as multiple documents and have item adding/changing/deletion as the item document CRUD. One still must to do data design step when working on document DB.Imre Pühvel

2 Answers

3
votes

As @Sajeetharan said, azure cosmos db doesn't support partial updates now. It seems the team is actively working on this feature. Now,you could update entire document in stored procedure.

Sample code as below for reference:

function updateSproc(id, update) {
    var collection = getContext().getCollection();
    var collectionLink = collection.getSelfLink();
    var response = getContext().getResponse();

    tryQueryAndUpdate();

    function tryQueryAndUpdate(continuation) {
        var query = {query: "select * from root r where r.id = @id", parameters: [{name: "@id", value: id}]};
        var requestOptions = {continuation: continuation};

        var isAccepted = collection.queryDocuments(collectionLink, query, requestOptions, function (err, documents, responseOptions) {
            if (err) throw err;

            if (documents.length > 0) {
                tryUpdate(documents[0]);
            } else {
                throw new Error("Document not found.");
            }
        });
    }

function tryUpdate(document) {
    var requestOptions = {etag: document._etag};

    var fields, i;

    fields = Object.keys(update);
    for (i = 0; i < fields.length; i++) {
       document[fields[i]] = update[fields[i]];
    }

    var isAccepted = collection.replaceDocument(document._self, document, requestOptions, function (err, updatedDocument, responseOptions) {
        if (err) throw err;
        response.setBody(updatedDocument);
    });
}

However, Azure Cosmos DB support MongoDB protocol. You could confirm supported features on Azure official page.

So,incremental operations are supported. Please refer to this link.

Hope it helps you.Any concern,please feel free to let me know.

3
votes

Currently there is no way rather than retrieving the document doing the modification and updating it.

However there is a User voice feature request has been updated on Mar 5, 2018: