javascript - DynamoDB 的 LocalSecondaryIndexes 出现 "key schema too big"错误?

标签 javascript node.js indexing amazon-dynamodb

我正在尝试使用如下所示的 Node.js 脚本创建 DynamoDB 表。如果我删除 LocalSecondaryIndexes block 并删除删除后不再需要的两个属性定义,则代码可以正常工作并成功创建表。但使用下面代码所示的该 block ,我从 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 blog post 作为官方示例。另请参阅 Best Practices for Using Sort Keys to Organize Data 。)

如何创建表格?

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

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

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

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

{
    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: {
        ...
    }
}

如何执行查询?

这里是key condition expressions获取您需要的数据。

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

author_id = "theAuthorId" 

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

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

在这种情况下,请务必在测验名称末尾添加 /(或您使用的任何分隔符),否则“theQuizName”也会返回“theQuizName2”、“theQuizName3”等的结果。

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

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

关于javascript - DynamoDB 的 LocalSecondaryIndexes 出现 "key schema too big"错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54678479/

相关文章:

javascript - 一旦 dom-repeat 的渲染完成就运行一个方法

javascript - 当轮播中的图像为 1365 x 415 px 时,如何使轮播图像适合 1 7'' 或更多屏幕?

javascript - 是否可以在使用 Javascript/JQuery 发送到服务器之前将表单数据转换为文件?

javascript - 如何导入只有 JSDoc 注释的 JavaScript 模块

javascript - 获取两个 Moment 日期/时间之间的日期/时间

mysql用索引解释文件排序

javascript - 高亮最近点d3js折线图和点图

javascript - 如何检查数组是否包含至少一个对象?

mysql - 检查 SQL 查询中是否使用了索引?

python - 使用要排除的索引列表进行索引