Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DynamoDB Global Secondary Index with Exclusive Start Key

Is it possible to specify an exclusive start key when querying a DynamoDB table via global secondary index?

I'm using the aws-java-sdk version 1.6.10 and executing queries with a QueryExpression and a DynamoDBMapper. Here's the gist of what I'm trying to do:

MappedItem key = new MappedItem();
item.setIndexedAttribute(attributeValue);

Map<String, AttributeValue> exclusiveStartKey = new HashMap<String, AttributeValue>();
exclusiveStartKey.put(MappedItem.INDEXED_ATTRIBUTE_NAME, new AttributeValue().withS(attributeValue));
exclusiveStartKey.put(MappedItem.TIMESTAMP, new AttributeValue().withN(startTimestamp.toString()));

DynamoDBQueryExpression<MappedItem> queryExpression = new DynamoDBQueryExpression<MappedItem>();
queryExpression.withIndexName(MappedItem.INDEX_NAME);
queryExpression.withConsistentRead(Boolean.FALSE);
queryExpression.withHashKeyValues(key);
queryExpression.setLimit(maxResults * 2);
queryExpression.setExclusiveStartKey(exclusiveStartKey);

This results in a 400 error saying that the specified start key is invalid. The TIMESTAMP is the range key for the table index and for the global secondary index, and the attribute value pair is valid (i.e. there is an item in the table with the values passed as the hash and range key for the index, and the attribute passed as the index is the hash key of the global secondary index).

Is there something I missed or is this not possible?

like image 231
rpmartz Avatar asked Feb 12 '14 14:02

rpmartz


People also ask

Does a GSI need a sort key?

Every global secondary index must have a partition key, and can have an optional sort key. The index key schema can be different from the base table schema.

Can a global secondary index create at the same time as the table creation?

Global Secondary Indexes (GSI) enable you to perform more efficient queries. Now, you can add or delete GSIs from your table at any time, instead of just during table creation.

What are the global secondary key features of DynamoDB?

DynamoDB supports two types of secondary indexes: Global secondary index — An index with a partition key and a sort key that can be different from those on the base table. A global secondary index is considered "global" because queries on the index can span all of the data in the base table, across all partitions.


2 Answers

OK I'm super late to the party but I have figured out what is going on. This isn't a bug, it's working as it should, but I've never seen it in the documentation.

It turns out that in global secondary indexes, the primary indexes are used as "tiebreakers." That is, if two objects have the same GSI hash+sort keys, then the primary indexes are used to order them in the GSI. That means that when you query a GSI with an exclusive start key, you need both the GSI indexes and the primary indexes in order to start at the exact right place.

Maybe this will help out somebody. I know it stumped me for a while!

like image 137
Bill Shubert Avatar answered Oct 04 '22 00:10

Bill Shubert


Had the same issue and just got sorted. :) Too late to answer the question but hope someone will find helpful.

When you query or scan table with secondary indexes and pagination, you should include primary keys of the table and the index (as key), with last evaluated values (as attribute value) when you setting ExclusiveStartKey.

Just Sysout the LastEvaluatedKey from the query or scan result to see the format.

// let's just assume that we have a table to store details of products
Map<String, AttributeValue> exclusiveStartKey = new HashMap<String, AttributeValue>();
// primary key of the table
exclusiveStartKey.put("productId", new AttributeValue().withS("xxxx"));
exclusiveStartKey.put("produtSize", new AttributeValue().withS("XL"));
// primary key of the index
exclusiveStartKey.put("categoryId", new AttributeValue().withS("xx01"));
exclusiveStartKey.put("subCategoryId", new AttributeValue().withN("1"));
like image 33
Naween Niroshan Avatar answered Oct 04 '22 01:10

Naween Niroshan