tessl install tessl/golang-github-com-azure-azure-sdk-for-go-sdk-data-azcosmos@1.4.1Go SDK client library for interacting with Azure Cosmos DB SQL API
Partition keys are fundamental to Cosmos DB's horizontal scaling and performance. The azcosmos package supports both simple and hierarchical partition keys.
type PartitionKey struct {
// Has unexported fields.
}Represents a logical partition key value. Can contain one or more values for hierarchical partitioning.
func NewPartitionKey() PartitionKeyCreates an empty partition key. Used for cross-partition queries.
Returns: An empty PartitionKey
func NewPartitionKeyString(value string) PartitionKeyCreates a partition key with a single string value.
Parameters:
value - The string partition key valueReturns: A PartitionKey with the string value
func NewPartitionKeyNumber(value float64) PartitionKeyCreates a partition key with a single numeric value.
Parameters:
value - The numeric partition key valueReturns: A PartitionKey with the numeric value
func NewPartitionKeyBool(value bool) PartitionKeyCreates a partition key with a single boolean value.
Parameters:
value - The boolean partition key valueReturns: A PartitionKey with the boolean value
func (pk PartitionKey) AppendString(value string) PartitionKeyAppends a string value to the partition key for hierarchical partitioning.
Parameters:
value - The string value to appendReturns: A new PartitionKey with the appended value
func (pk PartitionKey) AppendNumber(value float64) PartitionKeyAppends a numeric value to the partition key for hierarchical partitioning.
Parameters:
value - The numeric value to appendReturns: A new PartitionKey with the appended value
func (pk PartitionKey) AppendBool(value bool) PartitionKeyAppends a boolean value to the partition key for hierarchical partitioning.
Parameters:
value - The boolean value to appendReturns: A new PartitionKey with the appended value
func (pk PartitionKey) AppendNull() PartitionKeyAppends a null value to the partition key for hierarchical partitioning.
Returns: A new PartitionKey with a null value appended
var NullPartitionKey PartitionKey = PartitionKey{
values: []interface{}{nil},
}Represents a partition key with a null value. Used for items with null partition keys.
type PartitionKeyDefinition struct {
// Kind returns the kind of partition key definition.
Kind PartitionKeyKind `json:"kind"`
// Paths returns the list of partition key paths of the container.
Paths []string `json:"paths"`
// Version returns the version of the hash partitioning of the container.
Version int `json:"version,omitempty"`
}Defines the partition key configuration for a container.
Fields:
Kind - The partition key kind (Hash or MultiHash)Paths - JSON paths to the partition key properties (e.g., ["/category"] or ["/tenantId", "/userId"])Version - Version 2 required for hierarchical partition keysfunc (pkd PartitionKeyDefinition) MarshalJSON() ([]byte, error)Implements the json.Marshaler interface. If the Kind is not set, it will be inferred based on the number of paths.
type PartitionKeyKind stringRepresents the type of partition key used in a container.
Constants:
const (
PartitionKeyKindHash PartitionKeyKind = "Hash"
PartitionKeyKindMultiHash PartitionKeyKind = "MultiHash"
)PartitionKeyKindHash - Single partition key (one path)PartitionKeyKindMultiHash - Hierarchical partition keys (multiple paths)import "github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos"
// Define container with single partition key
containerProperties := azcosmos.ContainerProperties{
ID: "items",
PartitionKeyDefinition: azcosmos.PartitionKeyDefinition{
Paths: []string{"/category"},
},
}
// Create item with partition key
pk := azcosmos.NewPartitionKeyString("electronics")
item := map[string]interface{}{
"id": "item1",
"category": "electronics", // Must match partition key
"name": "Laptop",
}// Define container
containerProperties := azcosmos.ContainerProperties{
ID: "events",
PartitionKeyDefinition: azcosmos.PartitionKeyDefinition{
Paths: []string{"/year"},
},
}
// Create item with numeric partition key
pk := azcosmos.NewPartitionKeyNumber(2024)
item := map[string]interface{}{
"id": "event1",
"year": 2024, // Must match partition key
"name": "Conference",
}// Define container
containerProperties := azcosmos.ContainerProperties{
ID: "features",
PartitionKeyDefinition: azcosmos.PartitionKeyDefinition{
Paths: []string{"/enabled"},
},
}
// Create item with boolean partition key
pk := azcosmos.NewPartitionKeyBool(true)
item := map[string]interface{}{
"id": "feature1",
"enabled": true, // Must match partition key
"name": "DarkMode",
}// Define container with hierarchical partition keys
containerProperties := azcosmos.ContainerProperties{
ID: "orders",
PartitionKeyDefinition: azcosmos.PartitionKeyDefinition{
Paths: []string{"/tenantId", "/userId"},
Version: 2, // Required for hierarchical keys
},
}
// Create item with hierarchical partition key
pk := azcosmos.NewPartitionKeyString("tenant1").
AppendString("user456")
item := map[string]interface{}{
"id": "order123",
"tenantId": "tenant1", // First level
"userId": "user456", // Second level
"total": 150.00,
}
marshalled, _ := json.Marshal(item)
response, _ := container.CreateItem(context.Background(), pk, marshalled, nil)// Define container with 3-level hierarchy
containerProperties := azcosmos.ContainerProperties{
ID: "transactions",
PartitionKeyDefinition: azcosmos.PartitionKeyDefinition{
Paths: []string{"/region", "/store", "/department"},
Version: 2,
},
}
// Create item with 3-level partition key
pk := azcosmos.NewPartitionKeyString("west-us").
AppendString("store-123").
AppendString("electronics")
item := map[string]interface{}{
"id": "txn789",
"region": "west-us",
"store": "store-123",
"department": "electronics",
"amount": 99.99,
}
marshalled, _ := json.Marshal(item)
response, _ := container.CreateItem(context.Background(), pk, marshalled, nil)// Define container with mixed types
containerProperties := azcosmos.ContainerProperties{
ID: "analytics",
PartitionKeyDefinition: azcosmos.PartitionKeyDefinition{
Paths: []string{"/customerId", "/year", "/active"},
Version: 2,
},
}
// Create partition key with string, number, and boolean
pk := azcosmos.NewPartitionKeyString("customer123").
AppendNumber(2024).
AppendBool(true)
item := map[string]interface{}{
"id": "analytics1",
"customerId": "customer123",
"year": 2024,
"active": true,
"revenue": 50000.00,
}// Define container
containerProperties := azcosmos.ContainerProperties{
ID: "items",
PartitionKeyDefinition: azcosmos.PartitionKeyDefinition{
Paths: []string{"/category"},
},
}
// Create item with null partition key
pk := azcosmos.NullPartitionKey
item := map[string]interface{}{
"id": "uncategorized1",
"category": nil, // Null partition key
"name": "Misc Item",
}// Partition key with null in hierarchy
pk := azcosmos.NewPartitionKeyString("tenant1").
AppendNull().
AppendString("user456")
item := map[string]interface{}{
"id": "item1",
"tenantId": "tenant1",
"middleKey": nil,
"userId": "user456",
}// Create empty partition key for cross-partition query
pk := azcosmos.NewPartitionKey()
// Query across all partitions
query := "SELECT * FROM c WHERE c.price > 1000"
pager := container.NewQueryItemsPager(query, pk, nil)
for pager.More() {
response, _ := pager.NextPage(context.Background())
// Process items from all partitions
}container, _ := database.NewContainer("orders")
// Specify all levels of the hierarchical partition key
pk := azcosmos.NewPartitionKeyString("tenant1").
AppendString("user456").
AppendString("order123")
response, err := container.ReadItem(context.Background(), pk, "order123", nil)
if err != nil {
panic(err)
}
var order map[string]interface{}
json.Unmarshal(response.Value, &order)container, _ := database.NewContainer("orders")
// Query within a tenant and user (prefix of hierarchy)
pk := azcosmos.NewPartitionKeyString("tenant1").
AppendString("user456")
query := "SELECT * FROM c WHERE c.total > @minTotal"
options := &azcosmos.QueryOptions{
QueryParameters: []azcosmos.QueryParameter{
{Name: "@minTotal", Value: 100.0},
},
}
pager := container.NewQueryItemsPager(query, pk, options)
for pager.More() {
response, _ := pager.NextPage(context.Background())
// Process orders for tenant1/user456
}container, _ := database.NewContainer("orders")
// All operations in batch must use same partition key
pk := azcosmos.NewPartitionKeyString("tenant1").
AppendString("user456")
batch := container.NewTransactionalBatch(pk)
order1 := map[string]interface{}{
"id": "order1",
"tenantId": "tenant1",
"userId": "user456",
"total": 100.00,
}
marshalled1, _ := json.Marshal(order1)
batch.CreateItem(marshalled1, nil)
order2 := map[string]interface{}{
"id": "order2",
"tenantId": "tenant1",
"userId": "user456",
"total": 200.00,
}
marshalled2, _ := json.Marshal(order2)
batch.CreateItem(marshalled2, nil)
response, _ := container.ExecuteTransactionalBatch(context.Background(), batch, nil)// 1. Choose partition keys with high cardinality
containerProperties := azcosmos.ContainerProperties{
ID: "users",
PartitionKeyDefinition: azcosmos.PartitionKeyDefinition{
Paths: []string{"/userId"}, // Good: unique per user
},
}
// 2. Avoid hot partitions
// BAD: All items go to same partition
containerProperties = azcosmos.ContainerProperties{
ID: "items",
PartitionKeyDefinition: azcosmos.PartitionKeyDefinition{
Paths: []string{"/type"}, // Bad: low cardinality
},
}
// 3. Use hierarchical keys for multi-tenant scenarios
containerProperties = azcosmos.ContainerProperties{
ID: "data",
PartitionKeyDefinition: azcosmos.PartitionKeyDefinition{
Paths: []string{"/tenantId", "/category", "/subCategory"},
Version: 2,
},
}
// 4. Ensure partition key is immutable in item schema
item := map[string]interface{}{
"id": "item1",
"category": "electronics", // Don't change after creation
"name": "Laptop",
}