【问题标题】:DynamoDB: Query a secondary index with prefix (begins_with) onlyDynamoDB:仅查询带有前缀 (begins_with) 的二级索引
【发布时间】:2021-08-06 06:24:38
【问题描述】:

我想对不属于主键的字符串进行 DynamoDB 查询,而我只有这个字符串。

举个例子

Music
  Artist: String, PrimaryKey(HASH)
  SongTitle: String, PrimaryKey(RANGE)
  AlbumTitle: String, GlobalSecondaryKey(probably RANGE)

我想查询“所有具有 AlbumTitle 以 'Some' 开头的音乐项目”。

我用 aws cli 试过这个

创建表(对于 AlbumTitle 仍然使用 HASH)

aws dynamodb create-table \
    --table-name Music \
    --attribute-definitions \
        AttributeName=Artist,AttributeType=S \
        AttributeName=SongTitle,AttributeType=S \
        AttributeName=AlbumTitle,AttributeType=S \
    --key-schema \
        AttributeName=Artist,KeyType=HASH \
        AttributeName=SongTitle,KeyType=RANGE \
    --provisioned-throughput \
        ReadCapacityUnits=10,WriteCapacityUnits=5 \
    --global-secondary-indexes \
        "[
            {
                \"IndexName\": \"AlbumTitle-Index\",
                \"KeySchema\": [{\"AttributeName\":\"AlbumTitle\",\"KeyType\":\"HASH\"}],
                \"Projection\":{ \"ProjectionType\":\"ALL\" },
                \"ProvisionedThroughput\":{
                    \"ReadCapacityUnits\": 1,
                    \"WriteCapacityUnits\": 1
                }
            }
        ]"

等到

aws dynamodb describe-table --table-name Music | grep IndexStatus

回复

 "IndexStatus": "ACTIVE", 

放一些东西

aws dynamodb put-item \
    --table-name Music  \
    --item '{"Artist": {"S": "No One You Know"}, "SongTitle": {"S": "Call Me Today"}, "AlbumTitle": {"S": "Somewhat Famous"}, "Awards": {"N": "1"}}'
aws dynamodb put-item \
    --table-name Music  \
    --item '{"Artist": {"S": "No One You Know"}, "SongTitle": {"S": "Call Me Tomorrow"}, "AlbumTitle": {"S": "Something Famous"}, "Awards": {"N": "1"}}'
aws dynamodb put-item \
    --table-name Music \
    --item '{"Artist": {"S": "Acme Band"}, "SongTitle": {"S": "Happy Day"}, "AlbumTitle": {"S": "Songs About Life"}, "Awards": {"N": "10"} }'

查询相等(有效)

aws dynamodb query \
    --table-name Music \
    --index-name AlbumTitle-Index \
    --key-condition-expression "AlbumTitle = :name" \
    --expression-attribute-values '{":name":{"S":"Somewhat Famous"}}'

使用 begin_with 查询(不起作用)

aws dynamodb query \
    --table-name Music \
    --index-name AlbumTitle-Index \
    --key-condition-expression "begins_with(AlbumTitle, :name)" \
    --expression-attribute-values '{":name":{"S":"Some"}}'

结果

An error occurred (ValidationException) when calling the Query operation: Query key condition not supported

好的。这不起作用,因为我使用 AlbumTitle(HASH) 创建了索引 AlbumTitle-Index。因此我只能查询equals。

问题/疑问

我需要进行哪些更改才能执行前缀搜索?我只找到 begins_with 并且在任何地方都将它与 HASH 键结合为它的第一部分。除了应该在AlbumTitle 中作为前缀匹配的字符串之外,我什么都没有。 我不能简单地将HASH 替换为RANGE 中的AlbumTutle-Index 喜欢

    --global-secondary-indexes \
        "[
            {
                \"IndexName\": \"AlbumTitle-Index\",
                \"KeySchema\": [{\"AttributeName\":\"AlbumTitle\",\"KeyType\":\"RANGE\"}],
                ...

因为

An error occurred (ValidationException) when calling the CreateTable operation: Invalid KeySchema: The first KeySchemaElement is not a HASH key type

【问题讨论】:

    标签: amazon-web-services amazon-dynamodb dynamodb-queries


    【解决方案1】:

    我通过添加一个新字段解决了这个问题,该字段仅包含名为 AlbumTitleForHash 的专辑标题的第一位数字,这将是 GSI 的哈希键。

    然后我可以查询AlbumTitleHash=<first digit of query>AlbumTitle=<query>

    【讨论】:

      【解决方案2】:

      聚会迟到了,但对于阅读本文的任何人:如果您通过分区键(GSI 或非 GSI)进行查询,则必须要求相等。 如果你有一个排序键,你可以应用一些有趣的函数到它的条件。参考:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.KeyConditionExpressions

      OP 为解决他们的问题所做的有效是:它将主键转换为相等/可散列比较。这是 DynamoDB 解决问题的方式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-09
        • 1970-01-01
        • 2023-02-20
        • 1970-01-01
        • 1970-01-01
        • 2018-11-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多