Skip to content

Comments

[WIP] Multi-attribute index support#537

Open
tywalch wants to merge 22 commits intomasterfrom
feature/composite-attribute-indexes
Open

[WIP] Multi-attribute index support#537
tywalch wants to merge 22 commits intomasterfrom
feature/composite-attribute-indexes

Conversation

@tywalch
Copy link
Owner

@tywalch tywalch commented Dec 13, 2025

Context

AWS has added support for multi-attribute indexes in DynamoDB. Support for this new functionality would be immensely helpful for users and is likely possible without breaking changes.

Approach

In this PR, I will be chipping away at support for this feature. My priority is to just-get-things-working™ with tests. Ideally, this uncovers edge cases and tough judgment calls.

Only once things are working and behavior is locked down, I'll revisit ways to improve code organization, error handling, documentation, etc.

Questions

[ ] Should collection support for "composite" attributes ultimately just be that they enable processing multiple entity types
[ ] Should we still try to achieve index-level entity/service isolation with "composite" indexes or should we just use filters?
[ ] Should we add a "meta" object as the third argument to get and set that includes the entity, version, and service values from the schema? This might help the user build their own isolation fields.

Decisions

Learnings

  • It will be good practice to genericize index attributes using field (e.g., field: "attr1")

# Context AWS has added support for multi-attribute indexes in DynamoDB. Support for this new functionality would be immensely helpful for users and is likely possible without breaking changes.
@netlify
Copy link

netlify bot commented Dec 13, 2025

Deploy Preview for electrodb-dev ready!

Name Link
🔨 Latest commit 79505e8
🔍 Latest deploy log https://app.netlify.com/projects/electrodb-dev/deploys/699b6096c4120e0008cbc61d
😎 Deploy Preview https://deploy-preview-537--electrodb-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@tywalch tywalch linked an issue Dec 13, 2025 that may be closed by this pull request
@anatolzak
Copy link
Contributor

@tywalch just wanted to mention that the "condition" option should not be available for multi-attribute indexes

@anatolzak
Copy link
Contributor

Hey @tywalch! Fortunately, AWS released an update yesterday to DynamoDB Local 3.3.0 that adds support for multi-attribute GSIs, so we no longer need to use an AWS-hosted DynamoDB table to test the new GSI 🎉

…ly identify an Entity within a service. These values are stored on DynamoDB items using "identifier" attributes. When building filter expressions for these identifier attributes we must also make the ExpressionAttributeNames and ExpressionAttributeValues unique within the context of the query operation. There are also character restrictions on these values imposed by DynamoDB. We use the name/alias of the Entity to help create these unique values. Howevery, if the Entity name/alias contains special characters that are not allowed in DynamoDB ExpressionAttributeNames/Values we must remove them. This can lead to potential collisions between different Entity names/aliases that when stripped of special characters become identical.

These tests ensure that at a minimum queries can be performed successfully even when special characters are present in the Entity name/alias.
…ature/composite-attribute-indexes

# Conflicts:
#	src/entity.js
#	src/errors.js
#	test/init.js
#	www/src/pages/en/reference/errors.mdx
DynamoDB-Local now supports multi-attribute keys so actually hitting a live dynamodb api is unnecessary.
@tywalch
Copy link
Owner Author

tywalch commented Feb 22, 2026

@anatolzak I believe this feature may be finished. Would you mind taking a once-over look to see if anything jumps out to you?

@anatolzak
Copy link
Contributor

@anatolzak I believe this feature may be finished. Would you mind taking a once-over look to see if anything jumps out to you?

@tywalch of course! I will take a look tomorrow (it's night time where I am)

Copy link
Contributor

@anatolzak anatolzak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • The casing attribute should not be supported on composite indexes. We should throw an error if it's provided.
  • The cast attribute should not be supported on composite indexes. We should throw an error if it's provided.
  • When querying a composite index and specifying an attribute from the middle of the sort key, it gets silently swallowed
index: 'gsi1',
type: 'composite',
pk: { composite: ['a'] }
sk: {
  composite: ['b', 'c']
}

// Electro ignores C completely and sends a query as if only `a` was provided. We should throw an error in this case
entity.query.gsi({ a: '', c: '' }).go()
  • you should only be able to pass one attribute to all the range methods like lt, begins, between. I tested this manually, and DynamoDB will throw an error if you provide multiple attributes with the range operator.

Also

entity.query.gsi({ a: '' }).lt({ b: '', c: '' }).go()
// Electro will send params like a = ... and b = ... and c < ...
// even though the user may have intended for a = ... and b < ...
// we should throw an error if multiple attributes are provided to a range operation


function expectSubset(label: string, received: any, expected: any) {
try {
if (!received === undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!received === undefined will always evaluate to false

}

function expectNotSubset(label: string, received: any, expected: any) {
if (!received === undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!received === undefined will always evaluate to false

Comment on lines +142 to +145
InvalidLoggerProvided: {
code: 1022,
section: "inconsistent-index-definition",
name: "Inconsistent Index Definition",
section: "invalid-listener-provided",
name: "InvalidListenerProvided",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InvalidLoggerProvided is mapped to listener metadata

@anatolzak
Copy link
Contributor

@tywalch I briefly reviewed the PR, but primarily conducted manual testing and found a few issues.

Let me know when you'd like me to take another look. I will be happy to do so!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DynamoDb Multi-Attribute Keys

2 participants