如何使用 KeyConditionExpression 查询 AWS DynamoDb?

Ani*_*aje 11 amazon-web-services node.js amazon-dynamodb

我有一个 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 
Run Code Online (Sandbox Code Playgroud)

我的桌子上有以下项目结构 -

{
  "id": "12345f9f-f08c-45ae-986a-f1b5ac712345",
  "user_id": 1234,
  "prod_type": "OTHER"
}
Run Code Online (Sandbox Code Playgroud)

以下是我用于查询表的 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);
    }
});
Run Code Online (Sandbox Code Playgroud)

参考 -
Dynamodb 查询错误 - 查询关键条件不受支持
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.KeyConditions.html

小智 11

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

let params = {
   IndexName : "user_id-index",
   ExpressionAttributeValues: {
      ":v1": {
           N: 1234
       },
       ":v2": {
           S: "OTHER"
       }
   },
   TableName: table,
   KeyConditionExpression: "user_id = :v1 and prod_type = :v2"
};
Run Code Online (Sandbox Code Playgroud)

您需要根据文档指定数据类型。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"
};
Run Code Online (Sandbox Code Playgroud)

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


qkh*_*pro 7

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

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

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

从文档

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

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

partitionKeyName = :partitionkeyval AND sortKeyName = :sortkeyval
Run Code Online (Sandbox Code Playgroud)

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