Sean Kearon
Sean Kearon

Reputation: 11427

How to change the structure of a document in CosmosDB using the SQL API

How do you change the structure of a document or set of documents in CosmosDB when using the SQL API?

For example, how should you go about changing from this:

{
    "id": "some-id",
    "StudentId": "[email protected]",1
    // etc.

to this:

{
    "id": "some-id",
    "StudentEmail": "[email protected]",
    // etc.

It's worth noting that a word often used for the act of changing the structure of items in a database is "migration". However, in the CosmosDB literature that word seems to be used solely for the act of moving data into a CosmosDB database.

Upvotes: 0

Views: 1444

Answers (1)

Gaurav Mantri
Gaurav Mantri

Reputation: 136356

So Cosmos DB SQL API does not support partial document updates. You would need to replace the entire document. What you would need to do is fetch the document, make the changes and then replace the item.

You can find the sample code for the same here: https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos.Samples/Usage/ItemManagement/Program.cs. From the same link, here's the code for replacing a document:

private static async Task ReplaceItemAsync(SalesOrder order)
{
    //******************************************************************************************************************
    // 1.5 - Replace a item
    //
    // Just update a property on an existing item and issue a Replace command
    //******************************************************************************************************************
    Console.WriteLine("\n1.5 - Replacing a item using its Id");

    order.ShippedDate = DateTime.UtcNow;
    ItemResponse<SalesOrder> response = await container.ReplaceItemAsync(
        partitionKey: new PartitionKey(order.AccountNumber),
        id: order.Id,
        item: order);

    SalesOrder updated = response.Resource;
    Console.WriteLine($"Request charge of replace operation: {response.RequestCharge}");
    Console.WriteLine($"Shipped date of updated item: {updated.ShippedDate}");

    order.ShippedDate = DateTime.UtcNow;
    using (Stream stream = Program.ToStream<SalesOrder>(order))
    {
        using (ResponseMessage responseMessage = await container.ReplaceItemStreamAsync(
            partitionKey: new PartitionKey(order.AccountNumber),
            id: order.Id,
            streamPayload: stream))
        {
            // Item stream operations do not throw exceptions for better performance
            if (responseMessage.IsSuccessStatusCode)
            {
                SalesOrder streamResponse = FromStream<SalesOrder>(responseMessage.Content);
                Console.WriteLine($"\n1.5.2 - Item replace via stream {streamResponse.Id}");
            }
            else
            {
                Console.WriteLine($"Replace item from stream failed. Status code: {responseMessage.StatusCode} Message: {responseMessage.ErrorMessage}");
            }
        }
    }
}

While replacing, please keep in mind that both id and partition key value should not change. If any of the values changes, a new document will be created.

Upvotes: 1

Related Questions