DynamoDB 中的查询操作 - Amazon DynamoDB
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

DynamoDB 中的查询操作

Amazon DynamoDB 中的 Query 操作基于主键值查找项目。

您必须提供分区键属性的名称以及该属性的一个值。Query 将返回具有该分区键值的所有项目。(可选)您可以提供排序键属性,并使用比较运算符来细化搜索结果。

有关如何使用 Query 的更多信息,例如请求语法、响应参数和其他示例,请参阅《Amazon DynamoDB API 参考》中的查询

查询的键条件表达式

要指定搜索条件,请使用键条件表达式—用于确定要从表或索引中读取的项目的字符串。

您必须指定分区键名称和值作为等式条件。无法在键条件表达式中使用非键属性。

您可选择为排序键提供另一个条件(如果有)。排序键条件必须使用下列比较运算符之一:

  • a = b — 如果属性 a 等于值 b,则为 true

  • a < b — 如果 a 小于 b,则为 true

  • a <= b — 如果 a 小于等于 b,则为 true

  • a > b — 如果 a 大于 b,则为 true

  • a >= b — 如果 a 大于等于 b,则为 true

  • a BETWEEN b AND c — 如果 a 大于或等于 b,且小于或等于 c,则为 true。

以下函数也受支持:

  • begins_with (a, substr)— 如果属性 a 的值以特定子字符串开头,则为 true。

以下 Amazon Command Line Interface (Amazon CLI) 示例将演示键条件表达式的用法。这些表达式使用占位符(例如 :name:sub)而不是实际的值。有关更多信息,请参阅DynamoDB 中的表达式属性名称表达式属性值

Thread 表中查询特定的 ForumName(分区键)。具有 ForumName 值的所有项目将由查询进行读取,因为排序键 (Subject) 未包括在 KeyConditionExpression 中。

aws dynamodb query \ --table-name Thread \ --key-condition-expression "ForumName = :name" \ --expression-attribute-values '{":name":{"S":"Amazon DynamoDB"}}'

Thread 表中查询特定的 ForumName(分区键),但这一次仅返回具有给定 Subject(排序键)的项目。

aws dynamodb query \ --table-name Thread \ --key-condition-expression "ForumName = :name and Subject = :sub" \ --expression-attribute-values file://values.json

--expression-attribute-values 的参数存储在文件 values.json 中。

{ ":name":{"S":"Amazon DynamoDB"}, ":sub":{"S":"DynamoDB Thread 1"} }

Reply 表中查询特定的 Id(分区键),但仅返回其 ReplyDateTime(排序键)以特定字符开头的项目。

aws dynamodb query \ --table-name Reply \ --key-condition-expression "Id = :id and begins_with(ReplyDateTime, :dt)" \ --expression-attribute-values file://values.json

--expression-attribute-values 的参数存储在文件 values.json 中。

{ ":id":{"S":"Amazon DynamoDB#DynamoDB Thread 1"}, ":dt":{"S":"2015-09"} }

您可以在键条件表达式中使用任意属性名称,前提是第一个字符是 a-zA-Z,其余字符(从第二个字符开始,如果存在)为 a-zA-Z0-9。此外,属性名称不得为 DynamoDB 保留字。(有关这些保留关键字的完整列表,请参阅DynamoDB 中的保留字。) 如果属性名称不满足这些要求,则您必须将表达式属性名称定义为占位符。有关更多信息,请参阅 DynamoDB 中的表达式属性名称

对于具有给定分区键值的项目,DynamoDB 会将这些项目存储在紧邻位置并按照排序键值对其进行排序。在 Query 操作中,DynamoDB 按照排序顺序检索项目,然后使用 KeyConditionExpression 和可能存在的任何 FilterExpression 处理项目。只有在此时才会将 Query 结果发送回客户端。

Query 操作始终返回结果集。如果未找到匹配的项目,结果集将为空。

Query 结果始终按排序键值排序。如果排序键的数据类型为 Number,则按照数值顺序返回结果。否则,按照 UTF-8 字节的顺序返回结果。默认情况下,系统按升序排序。要颠倒顺序,请将 ScanIndexForward 参数设置为 false

单个 Query 操作最多可检索 1 MB 的数据。在向结果应用任何 FilterExpressionProjectionExpression 之前,将应用此限制。如果 LastEvaluatedKey 包含在响应中且为非 null 值,则您必须为结果集分页(请参阅对表查询结果分页)。

查询的筛选条件表达式

如果您需要进一步细化 Query 结果,则可以选择性地提供筛选表达式。筛选表达式可确定 Query 结果中应返回给您的项目。所有其他结果将会丢弃。

筛选表达式在 Query 已完成但结果尚未返回时应用。因此,无论是否存在筛选表达式,Query 都将占用同等数量的读取容量。

Query 操作最多可检索 1 MB 的数据。此限制在计算筛选表达式之前应用。

筛选表达式不得包含分区键或排序键属性。您需要在关键字条件表达式而不是筛选表达式中指定这些属性。

筛选表达式的语法与关键条件表达式的语法相似。筛选表达式可使用的比较运算符、函数和逻辑运算符与关键条件表达式可使用的相同。此外,筛选表达式可以使用不等于运算符 (<>)、OR 运算符、CONTAINS 运算符、IN 运算符、BEGINS_WITH 运算符、BETWEEN 运算符、EXISTS 运算符和 SIZE 运算符。有关更多信息,请参阅 查询的键条件表达式筛选条件和条件表达式的语法

以下 Amazon CLI 示例在 Thread 表中查询特定 ForumName(分区键)和 Subject(排序键)。在找到的项目中,只返回最常用的讨论线程,换句话说,只有那些具有超过一定数量 Views 的线程。

aws dynamodb query \ --table-name Thread \ --key-condition-expression "ForumName = :fn and Subject = :sub" \ --filter-expression "#v >= :num" \ --expression-attribute-names '{"#v": "Views"}' \ --expression-attribute-values file://values.json

--expression-attribute-values 的参数存储在文件 values.json 中。

{ ":fn":{"S":"Amazon DynamoDB"}, ":sub":{"S":"DynamoDB Thread 1"}, ":num":{"N":"3"} }

请注意,Views 在 DynamoDB 中是一个保留字(请参阅 DynamoDB 中的保留字),因此本示例使用 #v 作为占位符。有关更多信息,请参阅 DynamoDB 中的表达式属性名称

注意

筛选表达式将从 Query 结果集中删除项目。在您预计会检索到大量项目并且还需要丢弃其中大多数项目的情况下,请尽量避免使用 Query

限制结果集中的项目数

Query 操作可让您限制它读取的项目数。为此,请将 Limit 参数设置为您需要的最大项目数。

例如,假设您对某个表进行 QueryLimit 值为 6,并且没有筛选表达式。Query 结果将包含表中与请求中的键条件表达式匹配的前 6 个项目。

现在假设您向 Query 添加了一个筛选表达式。在这种情况下,DynamoDB 最多可读取六个项目,然后仅返回与筛选表达式匹配的项目。最终 Query 结果包含六个或更少的项目,即使更多项目(如果 DynamoDB 继续读取更多项目)与过滤表达式匹配,也是如此。

对结果中的项目进行计数

除了与您的条件匹配的项目之外,Query 响应还包含以下元素:

  • ScannedCount — 在应用筛选表达式(如果有)之前,与关键字条件表达式匹配的项目的数量。

  • Count — 在应用筛选表达式(如果有)之后,剩余的项目的数量。

注意

如果您不使用筛选表达式,那么 ScannedCountCount 具有相同的值。

如果 Query 结果集的大小大于 1 MB,则 ScannedCountCount 将仅表示项目总数的部分计数。您需要执行多次 Query 操作才能检索所有结果(请参阅对表查询结果分页)。

所有 Query 响应都将包含由该特定 Query 请求处理的项目的 ScannedCountCount。要获取所有 Query 请求的总和,您可以对 ScannedCountCount 记录流水账。

查询占用的容量单位

您可对任何表或二级索引执行 Query 操作,前提是它具有复合主键(分区键和排序键)。Query 操作占用读取容量单位,如下所示。

如果对...进行 Query DynamoDB 将占用...的读取容量单位
表的预置读取容量。
全局二级索引 索引的预置读取容量。
本地二级索引 基表的预置读取容量。

默认情况下,Query 操作不会返回任何有关它占用的读取容量大小的数据。但是,您可在 ReturnConsumedCapacity 请求中指定 Query 参数以获取此信息。下面是 ReturnConsumedCapacity 的有效设置:

  • NONE — 不返回任何已占用容量数据。(这是默认值。)

  • TOTAL — 响应包含占用的读取容量单位的总数。

  • INDEXES — 响应显示占用的读取容量单位的总数,以及访问的每个表和索引的占用容量。

DynamoDB 将基于项目大小而不是返回到应用程序的数据量来确定占用的读取容量单位数。因此,无论您是请求所有属性(默认行为)还是只请求部分属性(使用投影表达式),占用的容量单位数都是相同的。无论是否使用筛选表达式,该数量都是相同的。Query 对于为请求提供服务所涉及的每个分区均消耗一个最小读容量单位(对于最终一致性,原定设置为 0.5,对于强一致性,原定设置为 1.0),这包括不含任何项目的分区。

查询的读取一致性

默认情况下,Query 操作将执行最终一致性读取。这意味着 Query 结果可能无法反映由最近完成的 PutItemUpdateItem 操作导致的更改。有关更多信息,请参阅 读取一致性

如果您需要强一致性读取,请在 Query 请求中将 ConsistentRead 参数设置为 true