Go 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",
}Install with Tessl CLI
npx tessl i tessl/golang-github-com-azure-azure-sdk-for-go-sdk-data-azcosmos