Querying a Global Secondary Index in dynamodb Loca

2019-03-14 16:24发布

I am creating a table and GSI in DynamoDB, using these parameters, as per the documentation:

configId is the primary key of the table, and I am using the publisherId as the primary key for the GSI. (I've removed some unnecessary configuration parameters for brevity)

var params = {
    TableName: 'Configs',
    KeySchema: [ 
        {
            AttributeName: 'configId',
            KeyType: 'HASH',
        }
    ],
    AttributeDefinitions: [
        {
            AttributeName: 'configId',
            AttributeType: 'S',
        },
        {
            AttributeName: 'publisherId',
            AttributeType: 'S',
        }
    ],
    GlobalSecondaryIndexes: [ 
        { 
            IndexName: 'publisher_index', 
            KeySchema: [
                {
                    AttributeName: 'publisherId',
                    KeyType: 'HASH',
                }
            ]
        }
    ]
};

I am querying this table using this:

{ TableName: 'Configs',
  IndexName: 'publisher_index',
  KeyConditionExpression: 'publisherId = :pub_id',
  ExpressionAttributeValues: { ':pub_id': { S: '700' } } }

but I keep getting the error:

"ValidationException: One or more parameter values were invalid: Condition parameter type does not match schema type"

In the docs it specifies that the primary KeyType can either be HASH or RANGE, and that you set the AttributeType in the AttributeDefinitions field. I am sending the publisherId as String, not sure what I am missing here.

Is the issue in the way I am creating the table, or the way I am querying? Thanks

4条回答
家丑人穷心不美
2楼-- · 2019-03-14 16:39

Turns out it depends on whether you use AWS.DynamoDB or AWS.DynamoDB.DocumentClient.

Check the difference in the documentation: AWS.DynamoDB.query vs. AWS.DynamoDB.DocumentClient.query

In the DocumentClient the doc clearly states:

The document client simplifies working with items in Amazon DynamoDB by abstracting away the notion of attribute values. This abstraction annotates native JavaScript types supplied as input parameters, as well as converts annotated response data to native JavaScript types.

...

Supply the same parameters as AWS.DynamoDB.query() with AttributeValues substituted by native JavaScript types.

Maybe you where also referring to the DynamoDB API Reference which in fact makes no assumptions about the used SDK but uses plain HTTP Requests in the examples.

Thus using the AWS.DynamoDB.DocumentClient you would just provide a simple key-value map for ExpressionAttributeValues as suggested by @gior91.

查看更多
祖国的老花朵
3楼-- · 2019-03-14 16:42

Try to change this

{ 
 TableName: 'Configs',
 IndexName: 'publisher_index',
 KeyConditionExpression: 'publisherId = :pub_id',
 ExpressionAttributeValues: { ':pub_id': { S: '700' } } 
}

in this

{ 
 TableName: 'Configs',
 IndexName: 'publisher_index',
 KeyConditionExpression: 'publisherId = :pub_id',
 ExpressionAttributeValues: { ':pub_id': '700'} 
}

From { ':pub_id': { S: '700' } } to { ':pub_id': '700'}.

I had the same problem and I spent 2 days for this. The official documentation in misleading.

查看更多
We Are One
4楼-- · 2019-03-14 16:52

Try replacing your query JSON with this:

{
  TableName: 'Configs',
  IndexName: 'publisher_index',
  KeyConditionExpression: '#publisherId = :pub_id',
  ExpressionAttributeNames: { '#publisherId': 'publisherId' },
  ExpressionAttributeValues: { ':pub_id': { 'S': '700' } }
}
查看更多
我只想做你的唯一
5楼-- · 2019-03-14 16:56

As stated above, you need to use the DynamoDB Document Client if you want to abtract away the type casting.

var docClient = new AWS.DynamoDB.DocumentClient();

...then you can just use the above listed object notation to call the API.

{ ':pub_id': '700'}

Ran into this issue myself, I was using DynamoDB() in some places and the docClient in others, couldn't figure it out for awhile, but that'll solve it.

查看更多
登录 后发表回答