Reputation: 267107
I have a table with the following indices:
I'd like to have is_premium
be the range / sort key of expiresOn
, so I could e.g query all accounts which are expiring before or on today's date, AND which have is_premium = true.
If i just queried for all accounts expiring before / on today, but without is_premium=true, I would get 90% of the table in the results.
But, if I try to set a range query on is_premium
, I get the following error when I try to save a record to the table:
com.amazonaws.AmazonServiceException: Type mismatch for Index Key (Service: null; Status Code: 400; Error Code: ValidationException; Request ID: null)
at com.amazonaws.services.dynamodbv2.local.embedded.DDBExceptionMappingInvocationHandler.handleDynamoDBLocalServiceException(DDBExceptionMappingInvocationHandler.java:76) at com.amazonaws.services.dynamodbv2.local.embedded.DDBExceptionMappingInvocationHandler.invoke(DDBExceptionMappingInvocationHandler.java:58) at com.sun.proxy.$Proxy70.putItem(Unknown Source) at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$SaveObjectHandler.doPutItem(DynamoDBMapper.java:1270) at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$1.executeLowLevelRequest(DynamoDBMapper.java:879) at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$SaveObjectHandler.execute(DynamoDBMapper.java:1120) at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.save(DynamoDBMapper.java:966) at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.save(DynamoDBMapper.java:758)
I get this on dynamoDbMapper.save(order)
If I remove the sort / range key, everything works.
Any ideas what I'm doing wrong? The error is very ambigious.
Upvotes: 3
Views: 4680
Reputation: 4946
Booleans are no valid hash/range key in DynamoDB. A possible solution to make the architecture you suggested work would be to modify your data mapper to map booleans on 0 and 1.
But this way you could only query for a specific expiration date and then check if the according user is premium or not. If I understood your use case correctly, what you want is all is_premium =true
within a certain expiresOn
timeframe. In this case the preferable architecture would be:
is_premium
as the global secondary partition keyexpiresOn
as the global secondary sort keyThis way you can query the is_premium
partition and use the sort key to e.g. filter out all items in this partition that expire within one day.
Upvotes: 1
Reputation: 10056
Boolean field is not supported for hash/range keys in dynamodb. (only string/number/binary are supported).
you need to convert it to STRING or NUMBER (or to add new column). (if this will be your range key, so it can be 'true'/'false' or 0/1). if it was your hash key so it can be more complicated.
Upvotes: 6