amazon-dynamodbserverless-frameworkdynamodb-queriesdynamo-localamazon-dynamodb-index

DynamoDB query using secondary index, how to query with different keys


i'm using serverless framework with dynamodb [in Local]. trying to query with secondary indexed fields. goal is to query with few keys like we do in basic find queries in Mongo: {url:'<Somevalue>'} or may be like this {url:<somevalue>,ha:<somevalue>}

Table config i'm using currently:

serverless.yml

resources:
  Resources:
    TableName:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        TableName: ${file(./serverless.js):Tables.TableName.name}
        BillingMode: PAY_PER_REQUEST
        AttributeDefinitions:
          - AttributeName: 'id'
            AttributeType: 'S'
          - AttributeName: 'url'
            AttributeType: 'S'
          - AttributeName: 'ha'
            AttributeType: 'S'
          - AttributeName: 'GSI_1_PK'
            AttributeType: 'S'
          - AttributeName: 'GSI_1_SK'
            AttributeType: 'S'
        KeySchema:
          - AttributeName: 'id'
            KeyType: 'HASH'
        GlobalSecondaryIndexes:
          - IndexName: 'GSI_1'
            KeySchema:
              - AttributeName: 'GSI_1_PK'
                KeyType: 'HASH'
              - AttributeName: 'GSI_1_SK'
                KeyType: 'RANGE'
            Projection:
              ProjectionType: 'ALL'
          - IndexName: 'URI_1'
            KeySchema:
              - AttributeName: 'url'
                KeyType: 'HASH'
            Projection:
              ProjectionType: 'ALL'
          - IndexName: 'HASH_1'
            KeySchema:
              - AttributeName: 'ha'
                KeyType: 'HASH'
            Projection:
              ProjectionType: 'ALL'

  Outputs:
    TableNameARN:
      Value: { 'Fn::GetAtt': [TableName, Arn] }
      Export:
        Name: ${file(./serverless.js):Exports.TableNameARN}

with this, currently i'm only able to search with id field,

Q:

1> What are the changes needs to be made to query with different fields ? [which is secondary indexed , without using id in the query]

2> How do i search with multiple attributes? [i.e : {url:<somevalue>,ha:<somevalue>}]

Query i'm using :

var params = {
    TableName: '<TableName>',
    IndexName:'URI_1',
    Key: {
      url: 'http://something.com'
    }
};
docClient.get(params, function(err, data) {
    if (err) ppJson(err); // an error occurred
    else ppJson(data); // successful response
});

Output of the query:

{
message:"One of the required keys was not given a value",
code:"ValidationException,
...
}

Solution

  • var params = {
        TableName: '<TableName>',
        IndexName : 'URI_1',
        KeyConditionExpression : 'url = :url',
        FilterExpression : 'ha = :ha',
        ExpressionAttributeValues : {
          ':url': 'http://something.com',
          ':ha': 'aaaa'
        }
    };
    docClient.query(params, function(err, data) {
        if (err) console.log(err); // an error occurred
        else console.log(data); // successful response
    });

    additional

    There're three Expressions we could use to query conditions, the first two of them are used for Dynamodb.query and the last one is used for Dynamodb.updateItem or Dynamodb.putItem: