-
Notifications
You must be signed in to change notification settings - Fork 81
Description
Describe the bug
When using upsert().add() with an entity that has a GSI with a sort key, the GSI sort key (gsi1sk) is not included in the UpdateExpression. This results in the item not being properly replicated to the GSI.
I hope I'm not just missing something.
ElectroDB Version
3.5.3
ElectroDB Playground Link
Playground link
Entity/Service Definitions
{
model: {
entity: 'stats',
version: '1',
service: 'stats',
},
attributes: {
metricName: {
type: 'string',
required: true,
},
metricValue: {
type: 'number',
required: true,
},
dimensionName: {
type: 'string',
required: true,
},
dimensionValue: {
type: 'string',
required: true,
},
timestamp: {
type: 'string',
required: true,
},
},
indexes: {
// Primary access pattern: Query by metric/dimension/value across time range
primary: {
pk: {
field: 'pk',
composite: ['metricName', 'dimensionName', 'dimensionValue'],
},
sk: {
field: 'sk',
composite: ['timestamp'],
}
},
// Query top N by metric value (DynamoDB-sorted rankings)
// Use case: Get top 10 communications by message count, top campaigns by cost
numberSortKey: {
index: 'gsi1pk-gsi1sk-index',
pk: {
field: 'gsi1pk',
composite: ['metricName', 'dimensionName', 'metricName'],
},
sk: {
field: 'gsi1sk',
composite: ['metricValue'],
template: '${metricValue}',
}
}
},
}
Expected behavior
The UpdateExpression should include the GSI sort key (gsi1sk) when performing an upsert with add(), ensuring the item is properly indexed in the gsi1pk-gsi1sk-index.
Additional context
I have a data model where I'd like to have an access pattern with a numeric sort key so that I can perform numeric sorting.
For example, "Get top 10 campaigns by message count."
According to the docs, if I want a numeric key i need to utilize the template property of the index.
When a new item is created from the upsert().add() I see it in the main table, but if scan the GSI, there are no items (item is not replicated). If I examine the item in the main table, there is no attribute gsi1sk. If I manually add it, the item is replicated and I see it in the GSI.
{
TableName: 'electrodb-test',
UpdateExpression: 'SET #__edb_e__ = :__edb_e___u0, #__edb_v__ = :__edb_v___u0, #metricName = :metricName_u0, #dimensionName = :dimensionName_u0, #dimensionValue = :dimensionValue_u0, #timestamp = :timestamp_u0, #gsi1pk = :gsi1pk_u0 ADD #metricValue :metricValue_u0',
ExpressionAttributeNames: {
'#__edb_e__': '__edb_e__',
'#__edb_v__': '__edb_v__',
'#metricName': 'metricName',
'#dimensionName': 'dimensionName',
'#dimensionValue': 'dimensionValue',
'#timestamp': 'timestamp',
'#gsi1pk': 'gsi1pk',
'#metricValue': 'metricValue'
},
ExpressionAttributeValues: {
':__edb_e___u0': 'stats',
':__edb_v___u0': '1',
':metricName_u0': 'messageCount',
':dimensionName_u0': 'campaignId',
':dimensionValue_u0': 'campgin-123',
':timestamp_u0': '2026-01-06T21',
':gsi1pk_u0': '$stats#metricname_messagecount#dimensionname_campaignid#metricname_messagecount',
':metricValue_u0': 1
},
Key: {
pk: '$stats#metricname_messagecount#dimensionname_campaignid#dimensionvalue_campgin-123',
sk: '$stats_1#timestamp_2026-01-06t21'
}
}