获取“密钥架构太大"DynamoDB 的 LocalSecondaryIndexes 错误? [英] Getting "key schema too big" error with LocalSecondaryIndexes wth DynamoDB?

查看:21
本文介绍了获取“密钥架构太大"DynamoDB 的 LocalSecondaryIndexes 错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用如下所示的 Node.js 脚本创建一个 DynamoDB 表.如果我删除 LocalSecondaryIndexes 块并删除删除后不再需要的两个属性定义,则代码可以正常工作并成功创建表.但是使用如下代码所示的块,我从 DynamoDB 收到以下错误:

I am trying to create a DynamoDB table using the Node.js script shown below. If I remove the LocalSecondaryIndexes block and delete the two attributes definitions that are no longer necessary after that removal, the code works fine and creates the table successfully. But with that block as shown in the code below, I get the following error back from DynamoDB:

Unable to create table. Error JSON: {
  "message": "Key Schema too big.  Key Schema must at most consist of the hash and range key of a table",
  "code": "ValidationException",
  "time": "2019-02-13T19:45:34.482Z",
  "statusCode": 400,
  "retryable": false,
  "retryDelay": 29.475438988642534
}

我该如何解决这个问题?

代码如下:

// Create the quizzes table in DynamoDB.
var AWS = require('aws-sdk');

AWS.config.update({
  region: process.env.AWS_REGION,
  endpoint: process.env.AWS_ENDPOINT
});

var dynamodb = new AWS.DynamoDB();

var params = {
    TableName : "Quizzes",
    KeySchema: [
        { AttributeName: "author_id", KeyType: "HASH"},  //Partition key
        { AttributeName: "quiz_id", KeyType: "RANGE" }  //Sort key
    ],
    // Secondary key allows us to get all the different versions of a
    //  a particular quiz, referenced by quiz name, for all the available
    //  languages the quiz supports.
    LocalSecondaryIndexes: [
        {
            IndexName: "ForeignLanguageSupportIndex",
            KeySchema: [
                { AttributeName: "author_id", KeyType: "HASH"},  //Partition key
                { AttributeName: "quiz_name", KeyType: "RANGE" },  //Sort key
                { AttributeName: "language_code", KeyType: "RANGE" },  //Sort key
                { AttributeName: "quiz_id", KeyType: "RANGE" }  //Sort key
            ],
            Projection: {
                ProjectionType: "ALL"
            }
        }
    ],
    AttributeDefinitions: [
        { AttributeName: "author_id", AttributeType: "S" },
        { AttributeName: "quiz_name", AttributeType: "S" },
        { AttributeName: "language_code", AttributeType: "S" },
        { AttributeName: "quiz_id", AttributeType: "S" }
    ],
    // Using on-demand provisioning (pay as you go, no pre-allocation).
    BillingMode: "PAY_PER_REQUEST"
};

dynamodb.createTable(params, function(err, data) {
    if (err) {
        console.error("Unable to create table. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("Created table. Table description JSON:", JSON.stringify(data, null, 2));
    }
});

推荐答案

每个表/索引必须有 1 个散列键和 0 或 1 个范围键.如果您需要使用多个属性进行查询,您可以创建多个索引,或者,如果数据是分层的,您可以将多条数据合并到您的排序键中.(请参阅此 AWS 博客发布官方示例.另请参阅使用排序键组织数据的最佳实践.)

Each table/index must have 1 hash key and 0 or 1 range keys. If you need to query using multiple attributes, you can create multiple indexes or, if the data is hierarchical as yours is, you can combine multiple pieces of data into your sort key. (See this AWS blog post for an official example. See also the Best Practices for Using Sort Keys to Organize Data.)

您可以像这样创建您需要的索引:

You can create the index you need like this:

// Create the quizzes table in DynamoDB.
var AWS = require('aws-sdk');

AWS.config.update({
  region: process.env.AWS_REGION,
  endpoint: process.env.AWS_ENDPOINT
});

var dynamodb = new AWS.DynamoDB();

var params = {
    TableName : "Quizzes",
    KeySchema: [
        { AttributeName: "author_id", KeyType: "HASH"},  //Partition key
        { AttributeName: "quiz_id", KeyType: "RANGE" }  //Sort key
    ],
    // Secondary key allows us to get all the different versions of a
    //  a particular quiz, referenced by quiz name, for all the available
    //  languages the quiz supports.
    LocalSecondaryIndexes: [
        {
            IndexName: "ForeignLanguageSupportIndex",
            KeySchema: [
                { AttributeName: "author_id", KeyType: "HASH"},  //Partition key
                { AttributeName: "quiz_name_language", KeyType: "RANGE" },  //Sort key

            ],
            Projection: {
                ProjectionType: "ALL"
            }
        }
    ],
    AttributeDefinitions: [
        { AttributeName: "author_id", AttributeType: "S" },
        { AttributeName: "quiz_name_language", AttributeType: "S" },
        { AttributeName: "quiz_id", AttributeType: "S" }
    ],
    // Using on-demand provisioning (pay as you go, no pre-allocation).
    BillingMode: "PAY_PER_REQUEST"
};

dynamodb.createTable(params, function(err, data) {
    if (err) {
        console.error("Unable to create table. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("Created table. Table description JSON:", JSON.stringify(data, null, 2));
    }
});

那么我的数据是什么样的?

你读/写的对象看起来像这样:

So what does my data look like?

Your object that you read/write would look something like this:

{
    author_id: "author1234",
    quiz_name: "DynamoDBExperienceSurvey",
    language_code: "en-us",
    quiz_name_language: "DynamoDBExperienceSurvey/en-us",
    quiz_id: "55dc0736-2fdf-11e9-b210-d663bd873d93",
    quiz_data: {
        ...
    }
}

如何执行查询?

以下是关键条件表达式 获取您需要的数据.

要获取某个作者的所有调查,您可以仅使用哈希键查询您的表或 LSI.

To get all surveys by a certain author, you can query your table or the LSI using only the hash key.

author_id = "theAuthorId" 

要根据名称获取测验的所有语言变体,您的关键条件是

To get all the language variants of a quiz based on the name, your key condition would be

author_id = "theAuthorId" AND begins_with(quiz_name_language, "theQuizName/")

在这种情况下,重要的是在测验名称的末尾包含 /(或您使用的任何分隔符),否则theQuizName"也会返回theQuizName2"的结果,theQuizName3"等

In this case, it's important that you include the / (or whatever delimiter you use) at the end of the quiz name, or else "theQuizName" will also return results for "theQuizName2", "theQuizName3", etc.

奖励:您还可以使用语言代码的第一部分查询特定语言的所有区域变体.

Bonus: you can also query for all of the regionalized variants of a specific language by using the first part of the language code.

author_id = "theAuthorId" AND begins_with(quiz_name_language, "theQuizName/en-")

这篇关于获取“密钥架构太大"DynamoDB 的 LocalSecondaryIndexes 错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆