2017-03-08 361 views
1

我是AWS DynamoDB的新手,需要此处专家的指导。DynamoDB:查询所有数据并按日期降序排序

我正在创建一个应用程序,该应用程序将显示事件列表,其中事件日期必须大于今天的日期,并按事件日期降序排列。我的表架构如下图所示:

分区键=事件ID

排序键= EVENTDATE

如果我使用关系型数据库,我可以使用 “SELECT * FROM事件,其中EVENTDATE> todaydate ORDERBY EVENTDATE DESC”,但如何我想通过AWS DynamoDB实现这一目标?我正在使用QUERY而不是SCAN。

+0

让我们讨论上[聊天室](HTTP相同:/ /chat.stackoverflow.com/rooms/138204/chat-between-tj-and-thearrow) – LuFFy

回答

-1

不幸的是,您无法使用Query API实现上述用例。

原因: -

  • 你需要比比较操作的更大。可以在FilterExpression或使用KeyConditionExpression的排序键属性上使用不等式比较运算符。

  • 在上述用例中,您没有eventId,因此您不能使用 KeyConditionExpression。即使使用eventDate作为散列键创建GSI,也不能在散列键上使用不等式运算符,并且对于除排序键之外的任何属性都不能排序。因此,使用GSI选项无法达到分拣要求。

解决方法解决方案中使用查询API上面使用案例: -

  • 与哈希键创建GSI作为eventDate

  • 使用查询API由eventDate查询索引

  • 在客户端按eventDate排序数据。大多数编程语言都有很好的排序API。您可以轻松地在客户端实现这个

注: -

  • 你不能同时实现排序和使用查询API的要求特别是在不知道主表的哈希键
+0

Tq为您的回复先生。这意味着我没有解决方法来达到我在上述问题中提到的效果? –

+0

@notionquest,请注意使用查询API,您可以使用ScanIndexForward参数按排序键以正向或反向顺序获取结果。 – LuFFy

+0

@LuFFy这里的用例没有散列键值。 OP想要使用查询API而没有散列键值。这就是为什么我建议使用带有散列键的GSI作为eventDate。 – notionquest

-1

根据DynamoDB Query API Documentation

查询:

查询操作使用表或次要索引 直接访问从该表或索引项的主键。

使用KeyConditionExpression参数为分区键提供特定值 。查询操作将使用该分区键值从表或索引中返回所有 项目。您可以通过在KeyConditionExpression中指定 排序键值和比较运算符来可选地缩小查询操作的范围。 可以使用ScanIndexForward参数按排序键以 或相反顺序获得结果。

KeyConditionExpression

,用于指定项是在由查询动作检索 密钥值(一个或多个)条件。

该条件必须对单个分区键 的值执行相等性测试。该条件还可以对单个排序键值执行几个比较测试 中的一个。查询可以使用KeyConditionExpression来 检索具有给定分区键值和排序键值的一个项目, 或几个具有相同分区键值但不同 排序键值的项目。

分区键相等测试是必需的,而且必须在 以下格式指定:

partitionKeyName = :partitionkeyval

如果您也想为排序键的条件,则必须使用是 合并以及排序键的条件。以下是 一个例子,使用=比较运算符排序键:

partitionKeyName = :partitionkeyval AND sortKeyName = :sortkeyval

有效的比较用于排序关键条件如下:

  • sortKeyName = :sortkeyval - 如果排序键值真等于:sortkeyval。
  • sortKeyName < :sortkeyval - 如果排序键值小于:sortkeyval,则为true。
  • sortKeyName <= :sortkeyval - 如果排序关键字值小于或等于:sortkeyval,则返回true。
  • sortKeyName > :sortkeyval - 如果排序关键值大于:sortkeyval,则为true。
  • sortKeyName >= :sortkeyval - 如果排序关键字值大于或等于:sortkeyval,则返回true。
  • sortKeyName BETWEEN :sortkeyval1 AND :sortkeyval2 - 如果排序关键字值大于或等于:sortkeyval1且小于 或等于sortkeyval2,则为true。
  • begins_with (sortKeyName, :sortkeyval) - 如果排序键值以特定操作数开头,则返回true。 (您不能使用此功能 以及Number类型的排序键。)

您可以选择使用ExpressionAttributeNames参数 替换分​​区键的名称和与占位 令牌排序键。如果属性名称与DynamoDB保留字冲突 ,则可能需要此选项。例如,下面的 KeyConditionExpression参数将导致错误,因为尺寸是 保留字:

Size = :myval 

为了解决这个问题,定义一个占位符(例如一个#S)来表示 属性名大小。 KeyConditionExpression则如下:

#S = :myval 

对于保留字的列表,请参阅保留字亚马逊 DynamoDB开发者指南中。

有关ExpressionAttributeNames和 ExpressionAttributeValues的更多信息,请参阅Amazon DynamoDB开发人员指南中的使用属性名称的占位符 和值。

类型:String

要求:无

您的情况可以转换为下面的代码:

$tableName = "genericTable"; 
$response = $dynamodb->query([ 
    'TableName' => $tableName, 
    'IndexName' => 'OrderCreationDateIndex', 
    'KeyConditionExpression' => 'partitionKeyName = :partitionkeyval AND sortKeyName = :sortkeyval', 
    'ExpressionAttributeValues' => [ 
     ':partitionkeyval' => ['S' => 'pkey'], 
     ':sortkeyval' => ['S' => 'sortkey'] 
    ], 
    'Select' => 'ALL_PROJECTED_ATTRIBUTES', 
    'ScanIndexForward' => false, 
    'ConsistentRead' => true, 
    'Limit' => 5, 
    'ReturnConsumedCapacity' => 'TOTAL' 
]); 
+0

@ zalizan-zolkipali,将创建日期转换为unixtime,然后按照我的答案来实现您的任务,它已经在我的最终工作和实时解决方案中。 – LuFFy

+0

@ Zalizan Zolkipali,上述解决方案不会工作,因为eventId不是查询的一部分。如果eventId可用,则对查询API使用情况而言,这是一个直接的用例。 – notionquest