or run

tessl search
Log in

Version

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
golangpkg:golang/github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos@v1.4.1

docs

batch.mdclient.mdconfiguration.mdcontainer.mddatabase.mdindex.mditems.mdpartition-keys.mdpatch.mdquerying.mdthroughput.mdtypes.md
tile.json

tessl/golang-github-com-azure-azure-sdk-for-go-sdk-data-azcosmos

tessl install tessl/golang-github-com-azure-azure-sdk-for-go-sdk-data-azcosmos@1.4.1

Go SDK client library for interacting with Azure Cosmos DB SQL API

patch.mddocs/

Patch Operations

Patch operations allow you to perform partial document updates without replacing the entire item. This is more efficient than reading, modifying, and replacing items.

PatchOperations Type

type PatchOperations struct {
    // Has unexported fields.
}

Represents a set of patch operations to be applied to an item. See https://learn.microsoft.com/azure/cosmos-db/partial-document-update

Patch Operation Methods

AppendAdd

func (p *PatchOperations) AppendAdd(path string, value any)

Appends an add operation to the patch request. Adds a new property or adds a value to an array.

Parameters:

  • path - JSON path to the property (e.g., "/newProperty" or "/tags/-" for array append)
  • value - The value to add

AppendReplace

func (p *PatchOperations) AppendReplace(path string, value any)

Appends a replace operation to the patch request. Replaces the value of an existing property.

Parameters:

  • path - JSON path to the property (e.g., "/price")
  • value - The new value

AppendRemove

func (p *PatchOperations) AppendRemove(path string)

Appends a remove operation to the patch request. Removes a property from the item.

Parameters:

  • path - JSON path to the property to remove (e.g., "/tempField")

AppendSet

func (p *PatchOperations) AppendSet(path string, value any)

Appends a set operation to the patch request. Sets a property value, creating it if it doesn't exist.

Parameters:

  • path - JSON path to the property (e.g., "/status")
  • value - The value to set

AppendIncrement

func (p *PatchOperations) AppendIncrement(path string, value int64)

Appends an increment operation to the patch request. Increments (or decrements with negative value) a numeric property.

Parameters:

  • path - JSON path to the numeric property (e.g., "/counter")
  • value - The amount to increment (can be negative for decrement)

SetCondition

func (p *PatchOperations) SetCondition(condition string)

Sets a conditional filter for the patch request. The patch will only be applied if the condition is true.

Parameters:

  • condition - A SQL-like conditional expression (e.g., "FROM c WHERE c.status = 'active'")

MarshalJSON

func (o PatchOperations) MarshalJSON() ([]byte, error)

Implements the json.Marshaler interface.

Usage Examples

Replace a Property Value

import (
    "context"
    "github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos"
)

container, _ := database.NewContainer("items")

patchOps := azcosmos.PatchOperations{}
patchOps.AppendReplace("/price", 899.99)

pk := azcosmos.NewPartitionKeyString("electronics")
response, err := container.PatchItem(context.Background(), pk, "item1", patchOps, nil)
if err != nil {
    panic(err)
}

fmt.Printf("Patched item, RU charge: %f\n", response.RequestCharge)

Add a New Property

container, _ := database.NewContainer("items")

patchOps := azcosmos.PatchOperations{}
patchOps.AppendAdd("/discount", 0.15)
patchOps.AppendAdd("/featured", true)

pk := azcosmos.NewPartitionKeyString("electronics")
response, err := container.PatchItem(context.Background(), pk, "item1", patchOps, nil)
if err != nil {
    panic(err)
}

Remove a Property

container, _ := database.NewContainer("items")

patchOps := azcosmos.PatchOperations{}
patchOps.AppendRemove("/tempData")
patchOps.AppendRemove("/oldField")

pk := azcosmos.NewPartitionKeyString("electronics")
response, err := container.PatchItem(context.Background(), pk, "item1", patchOps, nil)
if err != nil {
    panic(err)
}

Increment a Counter

container, _ := database.NewContainer("items")

patchOps := azcosmos.PatchOperations{}
patchOps.AppendIncrement("/viewCount", 1)
patchOps.AppendIncrement("/stock", -1) // Decrement

pk := azcosmos.NewPartitionKeyString("electronics")
response, err := container.PatchItem(context.Background(), pk, "item1", patchOps, nil)
if err != nil {
    panic(err)
}

Set Property (Create or Update)

container, _ := database.NewContainer("items")

patchOps := azcosmos.PatchOperations{}
patchOps.AppendSet("/lastModified", "2024-01-15T10:30:00Z")
patchOps.AppendSet("/status", "active")

pk := azcosmos.NewPartitionKeyString("electronics")
response, err := container.PatchItem(context.Background(), pk, "item1", patchOps, nil)
if err != nil {
    panic(err)
}

Multiple Operations

container, _ := database.NewContainer("items")

patchOps := azcosmos.PatchOperations{}
patchOps.AppendReplace("/price", 799.99)
patchOps.AppendAdd("/tags", []string{"sale", "featured"})
patchOps.AppendIncrement("/viewCount", 1)
patchOps.AppendSet("/lastUpdated", "2024-01-15")
patchOps.AppendRemove("/tempField")

pk := azcosmos.NewPartitionKeyString("electronics")
response, err := container.PatchItem(context.Background(), pk, "item1", patchOps, nil)
if err != nil {
    panic(err)
}

Patch with Conditional Filter

container, _ := database.NewContainer("items")

patchOps := azcosmos.PatchOperations{}
patchOps.AppendReplace("/price", 699.99)
patchOps.SetCondition("FROM c WHERE c.stock > 0")

pk := azcosmos.NewPartitionKeyString("electronics")
response, err := container.PatchItem(context.Background(), pk, "item1", patchOps, nil)
if err != nil {
    // Patch will fail if condition is not met (item has stock <= 0)
    fmt.Printf("Condition not met\n")
}

Patch Array - Add Element

container, _ := database.NewContainer("items")

patchOps := azcosmos.PatchOperations{}
patchOps.AppendAdd("/tags/-", "new-tag") // Append to array

pk := azcosmos.NewPartitionKeyString("electronics")
response, err := container.PatchItem(context.Background(), pk, "item1", patchOps, nil)
if err != nil {
    panic(err)
}

Patch Array - Replace Element

container, _ := database.NewContainer("items")

patchOps := azcosmos.PatchOperations{}
patchOps.AppendReplace("/tags/0", "updated-tag") // Replace first element

pk := azcosmos.NewPartitionKeyString("electronics")
response, err := container.PatchItem(context.Background(), pk, "item1", patchOps, nil)
if err != nil {
    panic(err)
}

Patch Array - Remove Element

container, _ := database.NewContainer("items")

patchOps := azcosmos.PatchOperations{}
patchOps.AppendRemove("/tags/1") // Remove second element

pk := azcosmos.NewPartitionKeyString("electronics")
response, err := container.PatchItem(context.Background(), pk, "item1", patchOps, nil)
if err != nil {
    panic(err)
}

Patch Nested Object

container, _ := database.NewContainer("items")

patchOps := azcosmos.PatchOperations{}
patchOps.AppendReplace("/address/city", "Seattle")
patchOps.AppendAdd("/address/zipCode", "98101")
patchOps.AppendRemove("/address/tempField")

pk := azcosmos.NewPartitionKeyString("customers")
response, err := container.PatchItem(context.Background(), pk, "customer1", patchOps, nil)
if err != nil {
    panic(err)
}

Patch with ETag (Optimistic Concurrency)

container, _ := database.NewContainer("items")

pk := azcosmos.NewPartitionKeyString("electronics")

// Read item to get ETag
readResponse, _ := container.ReadItem(context.Background(), pk, "item1", nil)
etag := readResponse.ETag

// Patch with ETag check
patchOps := azcosmos.PatchOperations{}
patchOps.AppendReplace("/price", 749.99)

options := &azcosmos.ItemOptions{
    IfMatchEtag: &etag,
}

response, err := container.PatchItem(context.Background(), pk, "item1", patchOps, options)
if err != nil {
    // Will fail with 412 Precondition Failed if item was modified
    fmt.Printf("Item was modified by another process\n")
}

Atomic Counter Update

container, _ := database.NewContainer("counters")

patchOps := azcosmos.PatchOperations{}
patchOps.AppendIncrement("/count", 1)
patchOps.AppendSet("/lastIncremented", time.Now().Format(time.RFC3339))

pk := azcosmos.NewPartitionKeyString("global")
response, err := container.PatchItem(context.Background(), pk, "visitor-counter", patchOps, nil)
if err != nil {
    panic(err)
}

// Atomically incremented counter
var counter map[string]interface{}
json.Unmarshal(response.Value, &counter)
fmt.Printf("New count: %d\n", int(counter["count"].(float64)))

Complex Patch Scenario

container, _ := database.NewContainer("products")

patchOps := azcosmos.PatchOperations{}

// Update price and add sale flag
patchOps.AppendReplace("/price", 499.99)
patchOps.AppendAdd("/onSale", true)
patchOps.AppendAdd("/salePrice", 399.99)

// Increment view counter
patchOps.AppendIncrement("/views", 1)

// Update metadata
patchOps.AppendSet("/lastModified", time.Now().Format(time.RFC3339))
patchOps.AppendSet("/modifiedBy", "admin")

// Remove old fields
patchOps.AppendRemove("/deprecatedField")

// Add to featured list
patchOps.AppendAdd("/tags/-", "featured")

// Only apply if product is in stock
patchOps.SetCondition("FROM c WHERE c.stock > 0")

pk := azcosmos.NewPartitionKeyString("electronics")
response, err := container.PatchItem(context.Background(), pk, "laptop-pro", patchOps, nil)
if err != nil {
    panic(err)
}

fmt.Printf("Product updated, RU charge: %f\n", response.RequestCharge)

Patch in Transactional Batch

container, _ := database.NewContainer("items")

pk := azcosmos.NewPartitionKeyString("electronics")
batch := container.NewTransactionalBatch(pk)

// Patch operation 1
patchOps1 := azcosmos.PatchOperations{}
patchOps1.AppendIncrement("/stock", -1)
batch.PatchItem("item1", patchOps1, nil)

// Patch operation 2
patchOps2 := azcosmos.PatchOperations{}
patchOps2.AppendIncrement("/soldCount", 1)
batch.PatchItem("item2", patchOps2, nil)

// Execute atomically
response, err := container.ExecuteTransactionalBatch(context.Background(), batch, nil)
if err != nil {
    panic(err)
}

if response.Success {
    fmt.Printf("Both items patched atomically\n")
}

Performance Comparison: Patch vs Replace

container, _ := database.NewContainer("items")
pk := azcosmos.NewPartitionKeyString("electronics")

// Method 1: Replace (less efficient)
readResp, _ := container.ReadItem(context.Background(), pk, "item1", nil)
var item map[string]interface{}
json.Unmarshal(readResp.Value, &item)
item["price"] = 799.99
marshalled, _ := json.Marshal(item)
replaceResp, _ := container.ReplaceItem(context.Background(), pk, "item1", marshalled, nil)
fmt.Printf("Replace: %f RU\n", replaceResp.RequestCharge)

// Method 2: Patch (more efficient)
patchOps := azcosmos.PatchOperations{}
patchOps.AppendReplace("/price", 799.99)
patchResp, _ := container.PatchItem(context.Background(), pk, "item1", patchOps, nil)
fmt.Printf("Patch: %f RU\n", patchResp.RequestCharge)
// Patch typically uses fewer RUs and less bandwidth