簡體   English   中英

如何使用 KeyConditionExpression 查詢 AWS DynamoDb?

[英]How to query AWS DynamoDb using KeyConditionExpression?

我有一個 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 查詢錯誤 - 不支持查詢關鍵條件
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.KeyConditions.html

正如我在之前的回答中提到的。 您不能將一個 GSI/Primary 的哈希鍵和另一個 GSI/Primary 的哈希鍵放在單個KeyConditionExpression 上

條件必須對單個分區鍵值執行相等測試

條件可以選擇對單個排序鍵值執行多個比較測試之一。 這允許 Query 檢索具有給定分區鍵值和排序鍵值的一個項目,或具有相同分區鍵值但不同排序鍵值的多個項目。

從文檔

DynamoDB 不支持它,它實際上是為了節省您的資金。 您在這里可以做的是使用更具體的 GSI 哈希鍵作為 KeyConditionExpression 然后您可以對結果集執行 FilterExpression

否則,設置一個 GSI,其屬性之一為哈希鍵,另一個為范圍鍵。 這樣您就可以使用語法進行查詢

partitionKeyName = :partitionkeyval AND sortKeyName = :sortkeyval

請記住 partitionKeyName 僅支持相等。 sortKeyName 支持多種不同的操作

根據此處的文檔,問題是您的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

有 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 }
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM