【问题标题】:DynamoDB query using secondary index, how to query with different keysDynamoDB查询使用二级索引,如何使用不同的key进行查询
【发布时间】:2019-02-02 06:27:52
【问题描述】:

我正在使用带有 dynamodb [本地] 的无服务器框架。 尝试使用二级索引字段进行查询。 目标是像我们在 Mongo 中的基本查找查询中那样使用很少的键进行查询:{url:'<Somevalue>'} 或者可能是这样的{url:<somevalue>,ha:<somevalue>}

我目前使用的表配置:

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}

有了这个,目前我只能用id字段搜索,

1> 使用不同字段进行查询需要进行哪些更改? [这是二级索引,查询中不使用id]

2> 如何搜索多个属性? [即:{url:<somevalue>,ha:<somevalue>}]

我正在使用的查询:

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
});

查询的输出:

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

【问题讨论】:

    标签: amazon-dynamodb serverless-framework dynamodb-queries dynamo-local amazon-dynamodb-index


    【解决方案1】:
    • 您已经使用了 GSI,它允许您使用二级索引。但是您应该使用query 而不是get,它允许您查询具有复合主键(分区键和排序键)的任何表或二级索引。
    • 只要使用FilterExpressionExpressionAttributeValues就可以了,它支持你使用多个条件。

    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
    });

    附加

    我们可以使用三个表达式来查询条件,前两个用于Dynamodb.query,最后一个用于Dynamodb.updateItemDynamodb.putItem

    • KeyConditionExpression - 需要指定分区键的地方 - 必填 - 或者排序键。默认只能支持表键,如果你想使用像GSI这样的索引,你应该使用它与IndexName。
    • FilterExpression - 在查询完成后应用,但在返回结果之前,FilterExpression 不能包含分区键或排序键属性。
    • ConditionExpression - 条件更新成功必须满足的条件。

    【讨论】:

    • 明白了,但如果我只有url 并找到所有包含此url 的文档怎么办?
    • 我在使用 ConditionExpression 时遇到错误,所以我使用了 KeyConditionExpression,但是遇到了这个错误:Query condition missed key schema element ,我猜那是因为没有传递主键。
    • 它适用于我的情况。我还没有找到失败的原因,确定你已经使用了GSI,它允许你使用没有主键的二级索引
    • 顺便说一句,你的 DynamoDB API 版本是多少?
    • 我猜2012-08-10,无论如何,这只有在我通过url 时才有效,但如果我现在也通过:ha作为答案,它的抛出错误Query key condition not supported
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多