在DynamoDB中通过范围键对结果进行排序不起作用

时间:2019-02-13 16:15:55

标签: amazon-dynamodb

我的表格定义如下:

    ATTRIBUTE_NAME, ATTRIBUTE_TYPE = 'AttributeName', 'AttributeType'
    my_table = dynamodb.create_table(
    TableName='my_table',
    KeySchema=[
        {
            ATTRIBUTE_NAME: 'order_id',
            'KeyType': 'HASH'
        },
        {
            ATTRIBUTE_NAME: 'time',
            'KeyType': 'RANGE'
        }
    ],
    AttributeDefinitions=[
        {
            ATTRIBUTE_NAME: 'order_id',
            ATTRIBUTE_TYPE: 'S'
        },
        {
            ATTRIBUTE_NAME: 'time',
            ATTRIBUTE_TYPE: 'S'
        },
        {
            ATTRIBUTE_NAME: 'market_product',
            ATTRIBUTE_TYPE: 'S'
        }
    ],
    GlobalSecondaryIndexes=[
        {
            'IndexName': 'market_product_index',
            'KeySchema': [
                {
                    'AttributeName': 'market_product',
                    'KeyType': 'HASH'
                },
            ],
            'Projection': {
                'ProjectionType': 'KEYS_ONLY'
            },
            'ProvisionedThroughput': {
                'ReadCapacityUnits': 5,
                'WriteCapacityUnits': 5
            }
        }
    ],
    ProvisionedThroughput={
        'ReadCapacityUnits': 5,
        'WriteCapacityUnits': 5
    }
    )

在这里我为此表创建伪数据:

from uuid import uuid4 as uuid

my_table_dummy = [
    {
        'order_id': str(uuid()),
        'time': '2019-02-13 15:07:55.575960',
        'market_product': 'bitmex:BTC-USD',
        'side': 'buy',
        'size': '10.2',
        'weighted_price': '21.3'
    },
    {
        'order_id': str(uuid()),
        'time': '2019-02-13 15:06:55.575960',
        'market_product': 'bitmex:BTC-USD',
        'side': 'buy',
        'size': '10.2',
        'weighted_price': '21.3'
    },
    {
        'order_id': str(uuid()),
        'time': '2019-02-12 15:06:55.575960',
        'market_product': 'bitmex:BTC-USD',
        'side': 'buy',
        'size': '10.2',
        'weighted_price': '21.3'
    },
    {
        'order_id': str(uuid()),
        'time': '2019-02-12 15:06:55.575961',
        'market_product': 'bitmex:BTC-USD',
        'side': 'buy',
        'size': '10.2',
        'weighted_price': '21.3'
    },
    {
        'order_id': str(uuid()),
        'time': '2019-02-11 15:06:55.575960',
        'market_product': 'bitmex:BTC-USD',
        'side': 'buy',
        'size': '10.2',
        'weighted_price': '21.3'
    }
]

for dummy_sample in my_table_dummy:
    my_table.put_item(Item=dummy_sample)

我了解到,当有人查询以上内容并使用ScanForwardIndex标志时,结果将按范围键(在这种情况下为time)排序。但是,我没有得到通过time属性以降序/升序获取查询结果的预期行为:

response = my_table.query(
    IndexName='market_product_index',
    KeyConditionExpression=Key('market_product').eq('bitmex:BTC-USD'),
    ScanIndexForward=True
)

响应看起来像这样,即根本没有按时间排序:

{'Items': [{'market_product': 'bitmex:BTC-USD',
   'order_id': '0d9fd701-5a7e-4348-bb01-631388c2c246',
   'time': '2019-02-12 15:06:55.575960'},
  {'market_product': 'bitmex:BTC-USD',
   'order_id': '8cc1f2a2-0bc5-4169-aca5-cf37abbb5bc4',
   'time': '2019-02-11 15:06:55.575960'},
  {'market_product': 'bitmex:BTC-USD',
   'order_id': 'd23cfa2c-9ae6-403b-ae57-1e1a3796e116',
   'time': '2019-02-13 15:06:55.575960'},
  {'market_product': 'bitmex:BTC-USD',
   'order_id': '29095ee3-588f-4fb8-98a0-ce34adf028ea',
   'time': '2019-02-12 15:06:55.575961'},
  {'market_product': 'bitmex:BTC-USD',
   'order_id': '6cacd8fa-a2d0-4f2d-8041-a30fa5252c3b',
   'time': '2019-02-13 15:07:55.575960'}],
 'Count': 5,
 'ScannedCount': 5,
 'ResponseMetadata': {'RequestId': 'bbc8bc0e-218a-4669-ba52-4ac07cc7bb60',
  'HTTPStatusCode': 200,
  'HTTPHeaders': {'content-type': 'application/x-amz-json-1.0',
   'x-amz-crc32': '365619475',
   'x-amzn-requestid': 'bbc8bc0e-218a-4669-ba52-4ac07cc7bb60',
   'content-length': '738',
   'server': 'Jetty(8.1.12.v20130726)'},
  'RetryAttempts': 0}}

1 个答案:

答案 0 :(得分:1)

由于您的索引没有排序键,因此它们以不特定的顺序返回。索引不会自动从基表继承任何结构。

仅选择键,就是告诉DynamoDB表的主键应该投影到GSI,但是DynamoDB不会假定您希望GSI按相同的属性排序。

您可以通过删除并重新创建带有时间戳作为GSI排序键的GSI来解决此问题。