简体   繁体   中英

How to update specific value within a sub-document in cosmos db using Azure Function with TypeScript

I need to update a specific value (statutProduit) in a sub-document, within a document collection in cosmos DB, using a HttpTrigger Azure Function, that takes as parameter the document-id ( id ) and the sub-document-id ( EAN ) that i want to update.

The document is similar to the below doc

{
    "id": "b30ca49d-79ee-445c-a2d7-fff776fc95b8",
    "iduser": "21969186-6f25-4927-a140-80f9529b24e3",
    "statutCmd": 0,
    "produits": [
        {
            "EAN": 8002470085353,
            "statutProduit": 0,
            "quantite": 4
        },
        {
            "EAN": 3672762789023,
            "statutProduit": 1,
            "quantite": 3
        }
    ],
    "_rid": "M7ArAL-mcfgRAAAAAAAAAA==",
    "_self": "dbs/M7ArAA==/colls/M7ArAL-mcfg=/docs/M7ArAL-mcfgRAAAAAAAAAA==/",
    "_etag": "\"7f00af77-0000-0e00-0000-5f6e01bf0000\"",
    "_attachments": "attachments/",
    "statutProduit": 2,
    "_ts": 1601044927
}

I am new to typescriot, below is the code i have so far...

import { SqlQuerySpec } from "@azure/cosmos";
import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { CosmosClient } from "@azure/cosmos";  
                            
const httpTrigger: AzureFunction = async function(context: Context, req: HttpRequest): Promise<void> {
  try {
       
      const id: string = req.params.id;
      const EAN: string = req.params.EAN;
     
      const newStatut = req.body.statutProduit;
 
      const client = new CosmosClient(process.env.CONNECTION_STRING); 
      const database = client.database(process.env.COSMOS_DB_NAME);
      const container = database.container(process.env.COSMOS_DB_COLLECTION2_NAME);

      let querySpec: SqlQuerySpec = {
        query: "SELECT f.id, f.iduser, f.statutCmd, ARRAY(SELECT * FROM c IN f.produits WHERE c.EAN = 
        @EAN) AS produits , f._rid, f._self ,f._etag, f._attachments, f._ts FROM Commandes f WHERE f.id = 
        @id",
          parameters: [ {name: "@id" , value : id}, {name: "@EAN" , value : EAN}]
         }; 
      
        const {resources : items}  = await container.items.query(querySpec).fetchAll();
 
        items[0].produits[0].statutProduit = newStatut;
        const {resource : updatedItem}  = await 
        container.item(items[0].id).replace(items[0].produits[0]);
    
      context.res = {
        status: 200, /* Defaults to 200 */
        body : updatedItem
        
      };
    

  } catch (err) {
      console.log(err);
      context.res = {
        status: 401,
        body: "la fonction est exécuté avec succée, mais pas de Update effectuée"
       };
  }
};

below the http request and content body..

http://localhost:7071/api/UpdateStatutProduit/{id}/{EAN} 在此处输入图片说明

I need to update the value within 'statutProduit' from 0 to 2, when his 'EAN' (8002470085353) is passed in parameter ?

Thanks in advance.

With Cosmos DB, there is not currently a way to partially update an item and not really a concept of a "sub-document". Rather, you'd change any of the values within the entire item and issue a replace operation with updated item.

In your case, the produits value is just an array of objects within the item, so you can change any of those values and submit the entire item to replace the current one in Cosmos DB. If updates were needed across multiple items, you could use a foreach loop across the query results and handle each update one at a time.

It is possible, since the patch API is released in cosmos:

const updateObj: PatchRequestBody = [
        {
            op: 'replace',
            path: '/updatedBy',
            value: "Username",
        },
        {
            op: 'replace',
            path: '/year',
            value: 2021,
        }
    ];
    
    dbContainer.item(id, partitionKey).patch(updateObj);

Reference: https://docs.microsoft.com/en-us/azure/cosmos-db/partial-document-update-getting-started

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