在值为 Set 的属性上创建 GSI

Create GSI on an attribute which has the value of Set

所以我想创建一个简单的 Dynamodb table 称为提醒,目前有 3 列:

  1. reminder_id : 这是散列键
  2. reminder_tag: 我想在这个字段上有一个全局二级索引。但同时我想确保 tags 属性的数据类型应该是 Set 。因为一个提醒可以有多个标签。
  3. reminder_title:我也想在这个字段上有一个全局二级索引。这将是一个字符串字段。

我查看了文档:https://boto3.amazonaws.com/v1/documentation/api/latest/reference/customizations/dynamodb.html#valid-dynamodb-types 关于 Boto3 中可用的可能数据类型。

所以我想出了这个脚本:

import boto3


def create_reminders_table():
    """Just create the reminders table."""
    session = boto3.session.Session(profile_name='dynamo_local')
    dynamodb = session.resource('dynamodb', endpoint_url="http://localhost:8000")
    table = dynamodb.create_table(
        TableName='Reminders',
        KeySchema=[
            {
                'AttributeName': 'reminder_id',
                'KeyType': 'HASH'
            }
        ],
        AttributeDefinitions=[
            {
                'AttributeName': 'reminder_id',
                'AttributeType': 'S'
            },
            {
                'AttributeName': 'reminder_tag',
                'AttributeType': 'SS'
            },
            {
                'AttributeName': 'reminder_title',
                'AttributeType': 'S'
            }
        ],
        GlobalSecondaryIndexes=[
            {
                'IndexName': 'ReminderTagGsi',
                'KeySchema': [
                    {
                        'AttributeName': 'reminder_tag',
                        'KeyType': 'HASH'
                    }
                ],
                'Projection': {
                    'ProjectionType': 'INCLUDE',
                    'NonKeyAttributes': [
                        'reminder_title'
                    ]
                }
            },
            {
                'IndexName': 'ReminderTitleGsi',
                'KeySchema': [
                    {
                        'AttributeName': 'reminder_title',
                        'KeyType': 'HASH'
                    }
                ],
                'Projection': {
                    'ProjectionType': 'KEYS_ONLY'
                }
            }
        ],
        BillingMode='PAY_PER_REQUEST'
    )
    return table


if __name__ == '__main__':
    movie_table = create_reminders_table()
    print("Table status:", movie_table.table_status)

但是当我 运行 这样做时,我遇到了以下问题:

botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the CreateTable operation: Member must satisfy enum value set: [B, N, S]

我搜索并发现了一个有同样问题的人问的这个问题:https://forums.aws.amazon.com/thread.jspa?messageID=613970

谁能帮我解决这个问题,因为不提供数据类型的解决方案也行不通。

还有可能在值为 Set 的属性上建立索引吗?我的意思是我应该允许用户搜索带有标签的提醒,为此我需要一组。

请求某人帮助我解决这个问题。

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html

“每个主键属性必须是一个标量(意味着它只能包含一个值)。主键属性允许的唯一数据类型是字符串、数字或二进制。其他 non-key 属性没有此类限制。”

Is it possible to have an index on an attribute which is of value Set ?

没有。正如 CreateTable 文档所说,“KeySchema 中的属性也必须在 AttributeDefinitions 中定义”,数据类型为 (S)tring、(N)umber 或 (B)inary。

enable the user to search for reminders with a tag , and for doing that i need to have a set.

one-many 关系的 DynamoDB 解决方法是 composite sort key,如 urgent#work。不过,这只适用于少量固定数量的标签。

您的 least-bad 选项是按用户查询(并可能使用某些排序键进一步缩小范围),然后按 DynamoDB 外部的标签成员资格过滤结果。 (N.B。IN 运算符不能用在 Query 的 FilterConditionExpression 中,所以它在这里对你没有用。

I want to have a global secondary index on reminder_title

reminder_title 不适合作为索引主键。索引(和 table 的)Primary Key 必须确保 per-record 的唯一性。标题可能不会。您可能需要 3 个元素的组合,user_idrequest_idtitle,以确保跨记录的键唯一性。

考虑连接 title#request_id 的新列 (SK) 中的 composite Primery Key with, say, user_id for the Partition Key (= HASH) and a compound sort key。然后,您将使用以下内容搜索 by-user-by-title:

user_id="Zaphod" AND begins_with(SK, "exercise")