【问题标题】:How to query AWS DynamoDb using KeyConditionExpression?如何使用 KeyConditionExpression 查询 AWS DynamoDb?
【发布时间】:2019-09-26 20:17:32
【问题描述】:

我有一个 AWS DynamoDb 表,
我有 user_id 作为索引或 GSI(user_id-index ),
我也有 product_type 作为索引或 GSI(prod_type-in​​dex )。

我正在尝试使用 KeyConditionExpression 来查询 DynamoDb 表,
但我得到了一个 -

Validation Exception, with message:"Query key condition not supported" and statusCode: 400
ValidationException: Query key condition not supported\n at Request.extractError 

我的桌子上有以下物品结构 -

{
  "id": "12345f9f-f08c-45ae-986a-f1b5ac712345",
  "user_id": 1234,
  "prod_type": "OTHER"
}

以下是我的查询表的 NodeJs 代码 -

let AWS = require('aws-sdk');

AWS.config.update({
    region: 'us-east-1'
});

let connection = new AWS.DynamoDB.DocumentClient();

let table = "some_table";

let params = {
    IndexName : "user_id-index",
    ExpressionAttributeValues: {
        ":v1": {
            N: 1234
        },
        ":v2": {
            S: "OTHER"
        }
    },
    ExpressionAttributeNames: {
        "#userId": "user_id",
        "#prodType": "prod_type"
    },
    TableName: table,
    KeyConditionExpression: "#userId = :v1 and #prodType = :v2"
};

connection.query(params, function(err, data) {
    if (err) {
        console.log(err);
    } else {
        console.log(data);
    }
});

参考资料 -
Dynamodb query error - Query key condition not supported
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.KeyConditions.html

【问题讨论】:

    标签: node.js amazon-web-services amazon-dynamodb


    【解决方案1】:

    有 2 种不同的方式与 dynamoDb 交互,您可以使用:AWS.DynamoDB(执行一些自定义类型包装,例如将数字包装为字符串)或 AWS.DynamoDB.DocumentClient 为您进行类型包装 -后者在大多数情况下使用起来更简单。

    您正在调用 DocumentClient,但使用类型进行包装,就好像您直接调用 AWS.DynamoDB 那样会失败

    只需使用您的 user_id 索引(我假设它只是一个排序键,也不需要范围键),这应该可以工作:

      let params = {
         TableName: table,
         IndexName : "user_id-index",
         KeyConditionExpression: "user_id = :userId",
         ExpressionAttributeValues: { “:userId”: 1234 }
      }
    

    【讨论】:

      【解决方案2】:

      根据文档 here,问题是您的 ExpressionAttributeValues 值不正确。您需要提供变量和数据类型与值的映射。您需要提供这样的映射:

      let params = {
         IndexName : "user_id-index",
         ExpressionAttributeValues: {
            ":v1": {
                 N: 1234
             },
             ":v2": {
                 S: "OTHER"
             }
         },
         TableName: table,
         KeyConditionExpression: "user_id = :v1 and prod_type = :v2"
      };
      

      您需要根据文档指定数据类型。 S 用于字符串文字,N 用于数字等。您可以在上面的文档中找到详细信息。我还强烈建议您也使用 ExpressionAttributeNames。我发现它工作得更好,并且是这个 SDK 的最佳实践。您需要替换您在 KeyConditionExpression 中的映射中指定的变量,如下所示:

      let params = {
         IndexName : "user_id-index",
         ExpressionAttributeValues: {
             ":v1": {
                 N: 1234
             },
             ":v2": {
                 S: "OTHER"
             }
         },
         ExpressionAttributeNames: {
             "#userId": "user_id",
             "#prodType": "prod_type"
         }
         TableName: table,
         KeyConditionExpression: "#userId = :v1 and #prodType = :v2"
      };
      

      参考 -
      https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.KeyConditions.html

      【讨论】:

      • 还是出现同样的错误,更新问题。
      • 这可能与您的架构以及您如何设置索引有关。这里有一个很好的解决方案:stackoverflow.com/a/32216137/9307595
      • 那么 KeyConditionExpression 中的属性必须是表的 PrimaryKey 还是像 GSI 这样的索引?但是在我的情况下,表结构总共有 3 列,其中 1 是 PK,2 是 GSI,仍然,查询失败,我做错了什么,我应该改变什么?
      【解决方案3】:

      正如我在上一个答案中提到的。您不能将一个 GSI/Primary 的哈希键和另一个 GSI/Primary 的哈希键放在一个 KeyConditionExpression

      条件必须对单个分区键执行相等性测试 价值。

      条件可以选择执行几个比较测试之一 在单个排序键值上。这允许 Query 检索一项 具有给定的分区键值和排序键值,或多个项目 具有相同的分区键值但不同的排序键值。

      from the docs

      DynamoDB 不支持,实际上是为了省钱。 您可以在这里做的是使用更具体的 GSI 哈希键作为 KeyConditionExpression,然后您可以对结果集执行 FilterExpression

      否则,设置一个 GSI,其中一个属性作为哈希键,另一个作为范围键。这样你就可以使用语法查询了

      partitionKeyName = :partitionkeyval AND sortKeyName = :sortkeyval
      

      记住 partitionKeyName 只支持相等。 sortKeyName 支持多种不同的操作

      【讨论】:

      • 成功了! KeyConditionExpression 作用于查询中的 GSI 和 SortKey 属性。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      • 1970-01-01
      • 1970-01-01
      • 2019-09-26
      • 2021-01-11
      • 1970-01-01
      相关资源
      最近更新 更多